diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ce6a99c..e929a7d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,10 +18,10 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/gitpod-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -44,9 +44,9 @@ jobs: permissions: contents: read id-token: write - runs-on: ${{ github.repository == 'stainless-sdks/gitpod-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -67,7 +67,7 @@ jobs: github.repository == 'stainless-sdks/gitpod-python' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -84,10 +84,10 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ${{ github.repository == 'stainless-sdks/gitpod-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 0c20e7db..b2d28661 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -17,7 +17,7 @@ jobs: id-token: write steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye uses: eifinger/setup-rye@c694239a43768373e87d0103d7f547027a23f3c8 # v4 diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml new file mode 100644 index 00000000..c69ebb25 --- /dev/null +++ b/.github/workflows/release-doctor.yml @@ -0,0 +1,21 @@ +name: Release Doctor +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + release_doctor: + name: release doctor + runs-on: ubuntu-latest + if: github.repository == 'gitpod-io/gitpod-sdk-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Check release environment + run: | + bash ./bin/check-release-environment + env: + PYPI_TOKEN: ${{ secrets.GITPOD_PYPI_TOKEN || secrets.PYPI_TOKEN }} diff --git a/.release-please-manifest.json b/.release-please-manifest.json index f7014c35..a7130553 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.0" + ".": "0.12.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index e93723a0..83150193 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 193 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3dcdbd68ce4b336149d28d17ab08f211538ed6630112ae4883af2f6680643159.yml -openapi_spec_hash: 7e4333995b65cf32663166801e2444bb -config_hash: 8d7b241284195a8c51f5d670fbbe0ab4 +configured_endpoints: 213 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod/gitpod-f8271fd3c90de2edf4e8e63bce296f295fb8e54c0522b4d159d1d1f33a902474.yml +openapi_spec_hash: fb7b7d87dc232de2b141c5cc57d16fd1 +config_hash: 3d1af35edc400f59127c3b02ca3ab0ec diff --git a/CHANGELOG.md b/CHANGELOG.md index ddc444e4..22f59ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,107 @@ # Changelog +## 0.12.0 (2026-07-30) + +Full Changelog: [v0.11.0...v0.12.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.11.0...v0.12.0) + +### ⚠ BREAKING CHANGES + +* **api:** narrow public SDK surface +* **agent:** remove loop condition mechanism + +### Features + +* add base snapshot resource types ([86bc2ef](https://github.com/gitpod-io/gitpod-sdk-python/commit/86bc2ef04924b9c3b778263cf7c8c2f91d48def0)) +* **agent:** add devcontainer rebuild wait schema ([0cf6575](https://github.com/gitpod-io/gitpod-sdk-python/commit/0cf6575388a08e93a3e77bfd29c21b0cde3fc1b8)) +* **agents:** add native goal set control ([09bcc43](https://github.com/gitpod-io/gitpod-sdk-python/commit/09bcc435a18e00c8690c7106dbe453c3d8fa7a08)) +* **api:** add access_token field to runner create response models ([957eb60](https://github.com/gitpod-io/gitpod-sdk-python/commit/957eb60ea90eb7ed188da2cbfb0cd43838b0affd)) +* **api:** add agent turn controls ([0c7f633](https://github.com/gitpod-io/gitpod-sdk-python/commit/0c7f633f5ac848e21a39639c8952a8f53d5037fa)) +* **api:** add AGENT_EXECUTION_CNF capability to RunnerCapability ([3a521b2](https://github.com/gitpod-io/gitpod-sdk-python/commit/3a521b2a8292e6351117379a4c0c5d6e82e592cc)) +* **api:** add agent_execution_ids filter to agents list_executions ([630d438](https://github.com/gitpod-io/gitpod-sdk-python/commit/630d438761b409a15283932124a24e16b4221828)) +* **api:** add allow_unverified_email_scim_fallback_match to scim_configurations ([e1bba76](https://github.com/gitpod-io/gitpod-sdk-python/commit/e1bba7667f79b870c55096a00f18032bda03a65d)) +* **api:** add base snapshot build environment role ([0ce4953](https://github.com/gitpod-io/gitpod-sdk-python/commit/0ce4953f9e02f0a031fb963d80817aa795efcae6)) +* **api:** add base snapshot runner capability ([2c9855c](https://github.com/gitpod-io/gitpod-sdk-python/commit/2c9855c295b2a6deab6707a2b24387225a4ecf10)) +* **api:** add Claude Sonnet 5 model enum ([73ea069](https://github.com/gitpod-io/gitpod-sdk-python/commit/73ea0696fe48ad35bf58b082ecb774c2bfb14a36)) +* **api:** add Codex agent settings shape ([8d830ce](https://github.com/gitpod-io/gitpod-sdk-python/commit/8d830ce28b966c506ad9b63b0f28891226a4150a)) +* **api:** add Codex fast mode setting ([5c7ef6c](https://github.com/gitpod-io/gitpod-sdk-python/commit/5c7ef6ce126d085d5a743b7a24beed4ba99395ab)) +* **api:** add codex model policy states ([f930e3c](https://github.com/gitpod-io/gitpod-sdk-python/commit/f930e3c6346d8109a3e598a1720e1bfb08de130e)) +* **api:** add Codex policy allowlists ([4594b02](https://github.com/gitpod-io/gitpod-sdk-python/commit/4594b0296008ed2866917bba226a9fb2e08ede63)) +* **api:** add credential_proxy to secrets, remove format from environment spec ([349a1ba](https://github.com/gitpod-io/gitpod-sdk-python/commit/349a1bab3893da2900dad96fe92213c0d79c3c92)) +* **api:** add default environment class IDs to project creation defaults ([212b6b2](https://github.com/gitpod-io/gitpod-sdk-python/commit/212b6b2c408910da0b1e414428d310a32552b47a)) +* **api:** add disable_from_scratch to organizations policies ([916c70f](https://github.com/gitpod-io/gitpod-sdk-python/commit/916c70f870b5492fe5b6c117459d88cb7cb9c46f)) +* **api:** add dynamic LLM header contracts ([6520bd4](https://github.com/gitpod-io/gitpod-sdk-python/commit/6520bd48832e6063cda12b6a0354586b79619ec7)) +* **api:** add incident trigger support to workflow_trigger and workflow_execution ([5e90f8a](https://github.com/gitpod-io/gitpod-sdk-python/commit/5e90f8ae3d12d2acf8f1eaab330b5a9d8a39fea0)) +* **api:** add integration_id field, make webhook_id required in pull_request trigger ([077b662](https://github.com/gitpod-io/gitpod-sdk-python/commit/077b6622dc4e21a2033c8275c46716286a6515b8)) +* **api:** add max_port_admission_level to organizations policies ([4942a70](https://github.com/gitpod-io/gitpod-sdk-python/commit/4942a703b999261d0b0935f4db63e76c8db5d103)) +* **api:** add old_path field to ContentGitChangedFile ([d79d4d4](https://github.com/gitpod-io/gitpod-sdk-python/commit/d79d4d49ef41a889a81a0d484616fca442849356)) +* **api:** add Opus 4.8 supported model ([386256e](https://github.com/gitpod-io/gitpod-sdk-python/commit/386256e0cd6237eddebe61b4abca2c1e838ad67e)) +* **api:** add pagination and query parameter to runners.list_scm_organizations ([333311a](https://github.com/gitpod-io/gitpod-sdk-python/commit/333311aebaefb657861e2a9f6e8adb0f2abdd4dc)) +* **api:** add port_authentication capability to runner_capability ([c29b095](https://github.com/gitpod-io/gitpod-sdk-python/commit/c29b09596d2d87caaea047e61613a333c2fe4e31)) +* **api:** add prebuild trigger value to environments automations ([af2c44e](https://github.com/gitpod-io/gitpod-sdk-python/commit/af2c44e64fac19bf848c4325e0b39b183c998e74)) +* **api:** add prebuild_requires_success field to TaskSpec ([eccb99f](https://github.com/gitpod-io/gitpod-sdk-python/commit/eccb99f382cbc77c6bfcdc497ba19f23dbb78286)) +* **api:** add project_creation_defaults to organizations policies ([5d8545f](https://github.com/gitpod-io/gitpod-sdk-python/commit/5d8545fa2691bb59b0acf8ca0121300d48349a1e)) +* **api:** add PULL_REQUEST_EVENT_REVIEW_REQUESTED to workflow_trigger events ([242a3ab](https://github.com/gitpod-io/gitpod-sdk-python/commit/242a3ab60ed3580fd9488858727294ed86568ccf)) +* **api:** add readiness_timeout field to service spec types ([8786477](https://github.com/gitpod-io/gitpod-sdk-python/commit/8786477b21152c9040f3281d5b2cb17f3eada5f2)) +* **api:** add RESOURCE_ROLE_ORG_ENVIRONMENTS_READER to resource_role ([e99dc40](https://github.com/gitpod-io/gitpod-sdk-python/commit/e99dc409933596ef561dbd6784e7041d4d64a084)) +* **api:** add RUNNER_CAPABILITY_REDIS_STREAM to RunnerCapability enum ([b1ad5f5](https://github.com/gitpod-io/gitpod-sdk-python/commit/b1ad5f5fa5110c766928bd1be2589b227513d413)) +* **api:** add security policy CRUD ([85d3d46](https://github.com/gitpod-io/gitpod-sdk-python/commit/85d3d46fa1c7a73a1911eaa00e5423c62781662f)) +* **api:** add StatusGoal model and goal field to agent_execution ([3d37569](https://github.com/gitpod-io/gitpod-sdk-python/commit/3d37569f37337919926bbf799e1069aa585eef49)) +* **api:** add SUPPORTED_MODEL_OPENAI_AUTO to agent_execution status ([54503f5](https://github.com/gitpod-io/gitpod-sdk-python/commit/54503f5295a703ee855eac4c11694d2bbe465d13)) +* **api:** add SUPPORTED_MODEL_OPUS_4_7 to agent_execution Status ([74af533](https://github.com/gitpod-io/gitpod-sdk-python/commit/74af5338d7f6447df5a6464a2b2ef893c3bf4f6e)) +* **api:** add UserInputMetadata type ([ea300f4](https://github.com/gitpod-io/gitpod-sdk-python/commit/ea300f4314c14529c02ffec1e38f474d8a426844)) +* **api:** add web_browser_disabled parameter to organizations policies update ([a4a49d6](https://github.com/gitpod-io/gitpod-sdk-python/commit/a4a49d6d122a1e8911331ebfbe1b7bd1ffa9b854)) +* **api:** expose audit log entry kind ([d90ec8f](https://github.com/gitpod-io/gitpod-sdk-python/commit/d90ec8f9bdfd15d61cb8226a5c3716f6dbccf346)) +* **api:** expose default security policy assignment ([aeb8cba](https://github.com/gitpod-io/gitpod-sdk-python/commit/aeb8cba53564aa4062127a0534fedbdb81ab15d2)) +* **api:** expose usage insights API ([c7e6921](https://github.com/gitpod-io/gitpod-sdk-python/commit/c7e6921ffa2dfa33f115ad9d2ecc723aaccc5d10)) +* **api:** expose Veto Exec security policies ([07e4ed5](https://github.com/gitpod-io/gitpod-sdk-python/commit/07e4ed5e9cd7eeeab9269339a877f3cac37e407f)) +* **api:** remove deprecated access_token from runner responses ([003cd7d](https://github.com/gitpod-io/gitpod-sdk-python/commit/003cd7dcac020428985564e76c2bb6e45acd434c)) +* **api:** remove terminal field from RunsOn type ([faca2b2](https://github.com/gitpod-io/gitpod-sdk-python/commit/faca2b27b88f17a759bd91c305e5ea2a856a1e2c)) +* **audit:** curate audit events at their producers ([f54fb4a](https://github.com/gitpod-io/gitpod-sdk-python/commit/f54fb4af5721608ece6eeda2357da0c87da923be)) +* **audit:** store and retrieve Veto Exec details ([c6adc6a](https://github.com/gitpod-io/gitpod-sdk-python/commit/c6adc6a24a2806587598ad260e059e1631c89602)) +* **automations:** pin agent and Codex model per automation ([ce020c9](https://github.com/gitpod-io/gitpod-sdk-python/commit/ce020c9d3c968bff092d0ef3a37a340c306d2268)) +* **codex:** add GPT-5.6 model selection ([315f4ff](https://github.com/gitpod-io/gitpod-sdk-python/commit/315f4ffea3e7d68c45dec05bb176deeb444cc3a3)) +* **internal/types:** support eagerly validating pydantic iterators ([cbf4bac](https://github.com/gitpod-io/gitpod-sdk-python/commit/cbf4bac0498fbc32a85fb3d620ba2d7d551b53d0)) +* **rbac:** add billing viewer role ([64f6c50](https://github.com/gitpod-io/gitpod-sdk-python/commit/64f6c50c4c171f569d40e45adab9c101adcb5916)) +* **rbac:** add insights viewer role ([03c8230](https://github.com/gitpod-io/gitpod-sdk-python/commit/03c82308b65adb3944a401ebd890a1b0cd880954)) +* **secrets:** support JFrog OIDC secret sources ([419e2c0](https://github.com/gitpod-io/gitpod-sdk-python/commit/419e2c05b62cea8946933ff061d197a754f3507c)) +* support setting headers via env ([4e4f3fe](https://github.com/gitpod-io/gitpod-sdk-python/commit/4e4f3fe4d03901b3b63bccd13012197be6cc50ec)) + + +### Bug Fixes + +* **api:** narrow public SDK surface ([97913bf](https://github.com/gitpod-io/gitpod-sdk-python/commit/97913bf54c101cce3026b8fec0d1afde1f9d0c0d)) +* **api:** wrap prebuild default updates ([69a9ca3](https://github.com/gitpod-io/gitpod-sdk-python/commit/69a9ca3ab1f351c3d3e48a85d43d0d33434d0da3)) +* **client:** add missing f-string prefix in file type error message ([9371ec1](https://github.com/gitpod-io/gitpod-sdk-python/commit/9371ec1502be44e4684f8b1e0c7c6d55e8ead8dd)) +* **client:** preserve hardcoded query params when merging with user params ([b7f0b1d](https://github.com/gitpod-io/gitpod-sdk-python/commit/b7f0b1d27ef51872bf81541dd7f81a8101f856af)) +* ensure file data are only sent as 1 parameter ([5c02854](https://github.com/gitpod-io/gitpod-sdk-python/commit/5c02854efdc2874535d3d7867823048d5e8d4693)) +* use correct field name format for multipart file arrays ([c731392](https://github.com/gitpod-io/gitpod-sdk-python/commit/c731392aa36e5a3bba895d4e52a7d50addab326a)) + + +### Performance Improvements + +* **client:** optimize file structure copying in multipart requests ([cb792b6](https://github.com/gitpod-io/gitpod-sdk-python/commit/cb792b633104ff26eb799d8c32703920213ec23e)) + + +### Chores + +* **internal:** more robust bootstrap script ([5f05caa](https://github.com/gitpod-io/gitpod-sdk-python/commit/5f05caacfd1a55617d435845771e28503eff687c)) +* **internal:** reformat pyproject.toml ([b061deb](https://github.com/gitpod-io/gitpod-sdk-python/commit/b061deb38573beb2771beb0dfe92a5c3ba09b9d3)) +* **internal:** regenerate SDK with no functional changes ([2dc3c8d](https://github.com/gitpod-io/gitpod-sdk-python/commit/2dc3c8dbe693a77dc985066501d9bc9afacac347)) + + +### Documentation + +* **api:** add customer-facing descriptions to runner enums and fix CreateRunner examples ([5319ad7](https://github.com/gitpod-io/gitpod-sdk-python/commit/5319ad756a2e97b9d4d26444e3517b735bbd9eaa)) +* **api:** update trigger usage note in AutomationTrigger ([5a292cb](https://github.com/gitpod-io/gitpod-sdk-python/commit/5a292cb1ef87a0dd73d93445707412d25c0e95e0)) +* **types:** mark is_admin deprecated in Organization model ([5e7b9f3](https://github.com/gitpod-io/gitpod-sdk-python/commit/5e7b9f3d7dd7af385ca75b17f01c1cab87da8cb6)) + + +### Refactors + +* **agent:** remove loop condition mechanism ([9951849](https://github.com/gitpod-io/gitpod-sdk-python/commit/99518499ea51cdc5e6a37908af83afe8fe8a79ca)) +* **api:** default StartAgent agent ID ([beee4ef](https://github.com/gitpod-io/gitpod-sdk-python/commit/beee4ef89179b0541bd09335b2f6dce9a9506a3b)) +* **api:** remove project defaults API surface ([f96e98e](https://github.com/gitpod-io/gitpod-sdk-python/commit/f96e98e385ffffeb280bda2a549c4a4af0a05d3d)) + ## 0.11.0 (2026-04-02) Full Changelog: [v0.10.0...v0.11.0](https://github.com/gitpod-io/gitpod-sdk-python/compare/v0.10.0...v0.11.0) diff --git a/api.md b/api.md index dbd40b76..43258222 100644 --- a/api.md +++ b/api.md @@ -3,13 +3,19 @@ ```python from gitpod.types import ( AutomationTrigger, + CodexOpenAIModel, + CodexReasoningEffort, + CodexServiceTier, + CodexSettings, CountResponseRelation, + DateRange, EnvironmentClass, EnvironmentVariableItem, EnvironmentVariableSource, ErrorCode, FieldValue, Gateway, + KernelControlsAction, OrganizationRole, OrganizationTier, Principal, @@ -69,12 +75,18 @@ from gitpod.types import ( AgentExecution, AgentMessage, AgentMode, + GoalStatus, + CodexOpenAIModel, + CodexReasoningEffort, + CodexServiceTier, + CodexSettings, Prompt, PromptMetadata, PromptSpec, Role, Type, UserInputBlock, + UserInputMetadata, WakeEvent, AgentCreateExecutionConversationTokenResponse, AgentCreatePromptResponse, @@ -139,6 +151,57 @@ Methods: - client.automations.retrieve_execution_action(\*\*params) -> AutomationRetrieveExecutionActionResponse - client.automations.start_execution(\*\*params) -> AutomationStartExecutionResponse +# Billing + +Types: + +```python +from gitpod.types import ( + AgentExecutionCreditUsage, + BillingCurrency, + ByokRateCardTokenType, + CreditUsageExportGroupBy, + CreditUsageReportFilter, + CreditsByType, + CumulativeCreditUsage, + DailyCreditUsage, + DailyEnterpriseAIUsage, + EnterpriseAITokenUsage, + EnterpriseAIUsage, + EnterpriseAIUsageBudget, + EnterpriseAIUsageBudgetSource, + EnterpriseAIUsageByModel, + EnterpriseAIUsageByTokenType, + EnterpriseAIUsageTimeSeriesFilter, + EnterpriseAIUserBudgetPolicySource, + EnvironmentCreditUsage, + TeamCreditUsage, + TeamCumulativeCreditUsage, + TeamEnterpriseAIUsage, + UsageType, + UserCostBudgetUsage, + UserCreditBudgetUsage, + UserCreditUsage, + UserEnterpriseAIUsage, + BillingGetCreditUsageExportResponse, + BillingGetCreditUsageReportResponse, + BillingGetCumulativeCreditUsageResponse, + BillingGetEnterpriseAIUsageSummaryResponse, + BillingGetEnterpriseAIUsageTimeSeriesResponse, +) +``` + +Methods: + +- client.billing.get_credit_usage_export(\*\*params) -> BillingGetCreditUsageExportResponse +- client.billing.get_credit_usage_report(\*\*params) -> BillingGetCreditUsageReportResponse +- client.billing.get_cumulative_credit_usage(\*\*params) -> BillingGetCumulativeCreditUsageResponse +- client.billing.get_enterprise_ai_usage_summary(\*\*params) -> BillingGetEnterpriseAIUsageSummaryResponse +- client.billing.get_enterprise_ai_usage_time_series(\*\*params) -> BillingGetEnterpriseAIUsageTimeSeriesResponse +- client.billing.list_enterprise_ai_team_usage(\*\*params) -> SyncTeamUsagePage[TeamEnterpriseAIUsage] +- client.billing.list_enterprise_ai_user_usage(\*\*params) -> SyncUserUsagePage[UserCostBudgetUsage] +- client.billing.list_enterprise_user_credit_usage(\*\*params) -> SyncUserUsagePage[UserCreditBudgetUsage] + # Editors Types: @@ -273,36 +336,24 @@ Methods: - client.environments.classes.list(\*\*params) -> SyncEnvironmentClassesPage[EnvironmentClass] -# Errors +# Events Types: ```python from gitpod.types import ( - Breadcrumb, - ErrorEvent, - ErrorLevel, - ExceptionInfo, - ExceptionMechanism, - RequestInfo, - StackFrame, + AuditLogEntryDetails, + Process, + ResourceOperation, + EventRetrieveResponse, + EventListResponse, + EventWatchResponse, ) ``` Methods: -- client.errors.report_errors(\*\*params) -> object - -# Events - -Types: - -```python -from gitpod.types import ResourceOperation, EventListResponse, EventWatchResponse -``` - -Methods: - +- client.events.retrieve(\*\*params) -> EventRetrieveResponse - client.events.list(\*\*params) -> SyncEntriesPage[EventListResponse] - client.events.watch(\*\*params) -> JSONLDecoder[EventWatchResponse] @@ -500,11 +551,11 @@ Types: ```python from gitpod.types.organizations import ( AgentPolicy, + CodexModelPolicy, ConversationSharingPolicy, CrowdStrikeConfig, CustomAgentEnvMapping, CustomSecurityAgent, - KernelControlsAction, OrganizationPolicies, SecurityAgentPolicy, VetoExecPolicy, @@ -709,7 +760,7 @@ Methods: - client.runners.check_repository_access(\*\*params) -> RunnerCheckRepositoryAccessResponse - client.runners.create_logs_token(\*\*params) -> RunnerCreateLogsTokenResponse - client.runners.create_runner_token(\*\*params) -> RunnerCreateRunnerTokenResponse -- client.runners.list_scm_organizations(\*\*params) -> RunnerListScmOrganizationsResponse +- client.runners.list_scm_organizations(\*\*params) -> SyncOrganizationsPage[RunnerListScmOrganizationsResponse] - client.runners.parse_context_url(\*\*params) -> RunnerParseContextURLResponse - client.runners.search_repositories(\*\*params) -> RunnerSearchRepositoriesResponse @@ -838,16 +889,65 @@ Methods: - client.secrets.get_value(\*\*params) -> SecretGetValueResponse - client.secrets.update_value(\*\*params) -> object +# SecurityPolicies + +Types: + +```python +from gitpod.types import ( + SecurityPolicy, + SecurityPolicyCreateResponse, + SecurityPolicyRetrieveResponse, + SecurityPolicyUpdateResponse, +) +``` + +Methods: + +- client.security_policies.create(\*\*params) -> SecurityPolicyCreateResponse +- client.security_policies.retrieve(\*\*params) -> SecurityPolicyRetrieveResponse +- client.security_policies.update(\*\*params) -> SecurityPolicyUpdateResponse +- client.security_policies.list(\*\*params) -> SyncSecurityPoliciesPage[SecurityPolicy] +- client.security_policies.delete(\*\*params) -> object + # Usage Types: ```python -from gitpod.types import EnvironmentUsageRecord +from gitpod.types import ( + AgentTraceModelBreakdown, + AgentTraceSummary, + AgentTraceTimeBucket, + CoAuthorSummary, + CoAuthorTimeBucket, + CoAuthorTool, + EnvironmentUsageRecord, + PrSummary, + PrTimeBucket, + Resolution, + SupportedModel, + TimeSeriesPoint, + ToolBreakdown, + UsageGetAdoptionUsageSummaryResponse, + UsageGetAgentTraceSummaryResponse, + UsageGetAgentTraceTimeSeriesResponse, + UsageGetCoAuthorSummaryResponse, + UsageGetCoAuthorTimeSeriesResponse, + UsageGetPrSummaryResponse, + UsageGetPrTimeSeriesResponse, +) ``` Methods: +- client.usage.get_adoption_usage_summary(\*\*params) -> UsageGetAdoptionUsageSummaryResponse +- client.usage.get_agent_trace_summary(\*\*params) -> UsageGetAgentTraceSummaryResponse +- client.usage.get_agent_trace_time_series(\*\*params) -> UsageGetAgentTraceTimeSeriesResponse +- client.usage.get_co_author_summary(\*\*params) -> UsageGetCoAuthorSummaryResponse +- client.usage.get_co_author_time_series(\*\*params) -> UsageGetCoAuthorTimeSeriesResponse +- client.usage.get_pr_summary(\*\*params) -> UsageGetPrSummaryResponse +- client.usage.get_pr_time_series(\*\*params) -> UsageGetPrTimeSeriesResponse - client.usage.list_environment_runtime_records(\*\*params) -> SyncRecordsPage[EnvironmentUsageRecord] # Users diff --git a/pyproject.toml b/pyproject.toml index 5d1671eb..6c612339 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gitpod-sdk" -version = "0.11.0" +version = "0.12.0" description = "The official Python library for the gitpod API" dynamic = ["readme"] license = "Apache-2.0" @@ -171,7 +171,7 @@ show_error_codes = true # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. -exclude = ['src/gitpod/_files.py', '_dev/.*.py', 'tests/.*'] +exclude = ["src/gitpod/_files.py", "_dev/.*.py", "tests/.*"] strict_equality = true implicit_reexport = true diff --git a/scripts/bootstrap b/scripts/bootstrap index b430fee3..fe8451e4 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response diff --git a/src/gitpod/_base_client.py b/src/gitpod/_base_client.py index cc7f8af2..a9da58f9 100644 --- a/src/gitpod/_base_client.py +++ b/src/gitpod/_base_client.py @@ -540,6 +540,10 @@ def _build_request( files = cast(HttpxRequestFiles, ForceMultipartDict()) prepared_url = self._prepare_url(options.url) + # preserve hard-coded query params from the url + if params and prepared_url.query: + params = {**dict(prepared_url.params.items()), **params} + prepared_url = prepared_url.copy_with(raw_path=prepared_url.raw_path.split(b"?", 1)[0]) if "_" in prepared_url.host: # work around https://github.com/encode/httpx/discussions/2880 kwargs["extensions"] = {"sni_hostname": prepared_url.host.replace("_", "-")} diff --git a/src/gitpod/_client.py b/src/gitpod/_client.py index dddc11d8..3bbff998 100644 --- a/src/gitpod/_client.py +++ b/src/gitpod/_client.py @@ -19,7 +19,11 @@ RequestOptions, not_given, ) -from ._utils import is_given, get_async_library +from ._utils import ( + is_given, + is_mapping_t, + get_async_library, +) from ._compat import cached_property from ._version import __version__ from ._streaming import Stream as Stream, AsyncStream as AsyncStream @@ -35,9 +39,9 @@ usage, users, agents, - errors, events, groups, + billing, editors, runners, secrets, @@ -49,11 +53,12 @@ automations, environments, organizations, + security_policies, ) from .resources.usage import UsageResource, AsyncUsageResource from .resources.agents import AgentsResource, AsyncAgentsResource - from .resources.errors import ErrorsResource, AsyncErrorsResource from .resources.events import EventsResource, AsyncEventsResource + from .resources.billing import BillingResource, AsyncBillingResource from .resources.editors import EditorsResource, AsyncEditorsResource from .resources.secrets import SecretsResource, AsyncSecretsResource from .resources.accounts import AccountsResource, AsyncAccountsResource @@ -65,6 +70,7 @@ from .resources.groups.groups import GroupsResource, AsyncGroupsResource from .resources.runners.runners import RunnersResource, AsyncRunnersResource from .resources.projects.projects import ProjectsResource, AsyncProjectsResource + from .resources.security_policies import SecurityPoliciesResource, AsyncSecurityPoliciesResource from .resources.environments.environments import EnvironmentsResource, AsyncEnvironmentsResource from .resources.organizations.organizations import OrganizationsResource, AsyncOrganizationsResource @@ -115,6 +121,15 @@ def __init__( if base_url is None: base_url = f"https://app.gitpod.io/api" + custom_headers_env = os.environ.get("GITPOD_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -144,6 +159,13 @@ def automations(self) -> AutomationsResource: return AutomationsResource(self) + @cached_property + def billing(self) -> BillingResource: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import BillingResource + + return BillingResource(self) + @cached_property def editors(self) -> EditorsResource: from .resources.editors import EditorsResource @@ -156,16 +178,6 @@ def environments(self) -> EnvironmentsResource: return EnvironmentsResource(self) - @cached_property - def errors(self) -> ErrorsResource: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import ErrorsResource - - return ErrorsResource(self) - @cached_property def events(self) -> EventsResource: from .resources.events import EventsResource @@ -224,6 +236,12 @@ def secrets(self) -> SecretsResource: return SecretsResource(self) + @cached_property + def security_policies(self) -> SecurityPoliciesResource: + from .resources.security_policies import SecurityPoliciesResource + + return SecurityPoliciesResource(self) + @cached_property def usage(self) -> UsageResource: """ @@ -396,6 +414,15 @@ def __init__( if base_url is None: base_url = f"https://app.gitpod.io/api" + custom_headers_env = os.environ.get("GITPOD_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -425,6 +452,13 @@ def automations(self) -> AsyncAutomationsResource: return AsyncAutomationsResource(self) + @cached_property + def billing(self) -> AsyncBillingResource: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import AsyncBillingResource + + return AsyncBillingResource(self) + @cached_property def editors(self) -> AsyncEditorsResource: from .resources.editors import AsyncEditorsResource @@ -437,16 +471,6 @@ def environments(self) -> AsyncEnvironmentsResource: return AsyncEnvironmentsResource(self) - @cached_property - def errors(self) -> AsyncErrorsResource: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import AsyncErrorsResource - - return AsyncErrorsResource(self) - @cached_property def events(self) -> AsyncEventsResource: from .resources.events import AsyncEventsResource @@ -505,6 +529,12 @@ def secrets(self) -> AsyncSecretsResource: return AsyncSecretsResource(self) + @cached_property + def security_policies(self) -> AsyncSecurityPoliciesResource: + from .resources.security_policies import AsyncSecurityPoliciesResource + + return AsyncSecurityPoliciesResource(self) + @cached_property def usage(self) -> AsyncUsageResource: """ @@ -657,6 +687,13 @@ def automations(self) -> automations.AutomationsResourceWithRawResponse: return AutomationsResourceWithRawResponse(self._client.automations) + @cached_property + def billing(self) -> billing.BillingResourceWithRawResponse: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import BillingResourceWithRawResponse + + return BillingResourceWithRawResponse(self._client.billing) + @cached_property def editors(self) -> editors.EditorsResourceWithRawResponse: from .resources.editors import EditorsResourceWithRawResponse @@ -669,16 +706,6 @@ def environments(self) -> environments.EnvironmentsResourceWithRawResponse: return EnvironmentsResourceWithRawResponse(self._client.environments) - @cached_property - def errors(self) -> errors.ErrorsResourceWithRawResponse: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import ErrorsResourceWithRawResponse - - return ErrorsResourceWithRawResponse(self._client.errors) - @cached_property def events(self) -> events.EventsResourceWithRawResponse: from .resources.events import EventsResourceWithRawResponse @@ -737,6 +764,12 @@ def secrets(self) -> secrets.SecretsResourceWithRawResponse: return SecretsResourceWithRawResponse(self._client.secrets) + @cached_property + def security_policies(self) -> security_policies.SecurityPoliciesResourceWithRawResponse: + from .resources.security_policies import SecurityPoliciesResourceWithRawResponse + + return SecurityPoliciesResourceWithRawResponse(self._client.security_policies) + @cached_property def usage(self) -> usage.UsageResourceWithRawResponse: """ @@ -777,6 +810,13 @@ def automations(self) -> automations.AsyncAutomationsResourceWithRawResponse: return AsyncAutomationsResourceWithRawResponse(self._client.automations) + @cached_property + def billing(self) -> billing.AsyncBillingResourceWithRawResponse: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import AsyncBillingResourceWithRawResponse + + return AsyncBillingResourceWithRawResponse(self._client.billing) + @cached_property def editors(self) -> editors.AsyncEditorsResourceWithRawResponse: from .resources.editors import AsyncEditorsResourceWithRawResponse @@ -789,16 +829,6 @@ def environments(self) -> environments.AsyncEnvironmentsResourceWithRawResponse: return AsyncEnvironmentsResourceWithRawResponse(self._client.environments) - @cached_property - def errors(self) -> errors.AsyncErrorsResourceWithRawResponse: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import AsyncErrorsResourceWithRawResponse - - return AsyncErrorsResourceWithRawResponse(self._client.errors) - @cached_property def events(self) -> events.AsyncEventsResourceWithRawResponse: from .resources.events import AsyncEventsResourceWithRawResponse @@ -857,6 +887,12 @@ def secrets(self) -> secrets.AsyncSecretsResourceWithRawResponse: return AsyncSecretsResourceWithRawResponse(self._client.secrets) + @cached_property + def security_policies(self) -> security_policies.AsyncSecurityPoliciesResourceWithRawResponse: + from .resources.security_policies import AsyncSecurityPoliciesResourceWithRawResponse + + return AsyncSecurityPoliciesResourceWithRawResponse(self._client.security_policies) + @cached_property def usage(self) -> usage.AsyncUsageResourceWithRawResponse: """ @@ -897,6 +933,13 @@ def automations(self) -> automations.AutomationsResourceWithStreamingResponse: return AutomationsResourceWithStreamingResponse(self._client.automations) + @cached_property + def billing(self) -> billing.BillingResourceWithStreamingResponse: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import BillingResourceWithStreamingResponse + + return BillingResourceWithStreamingResponse(self._client.billing) + @cached_property def editors(self) -> editors.EditorsResourceWithStreamingResponse: from .resources.editors import EditorsResourceWithStreamingResponse @@ -909,16 +952,6 @@ def environments(self) -> environments.EnvironmentsResourceWithStreamingResponse return EnvironmentsResourceWithStreamingResponse(self._client.environments) - @cached_property - def errors(self) -> errors.ErrorsResourceWithStreamingResponse: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import ErrorsResourceWithStreamingResponse - - return ErrorsResourceWithStreamingResponse(self._client.errors) - @cached_property def events(self) -> events.EventsResourceWithStreamingResponse: from .resources.events import EventsResourceWithStreamingResponse @@ -977,6 +1010,12 @@ def secrets(self) -> secrets.SecretsResourceWithStreamingResponse: return SecretsResourceWithStreamingResponse(self._client.secrets) + @cached_property + def security_policies(self) -> security_policies.SecurityPoliciesResourceWithStreamingResponse: + from .resources.security_policies import SecurityPoliciesResourceWithStreamingResponse + + return SecurityPoliciesResourceWithStreamingResponse(self._client.security_policies) + @cached_property def usage(self) -> usage.UsageResourceWithStreamingResponse: """ @@ -1017,6 +1056,13 @@ def automations(self) -> automations.AsyncAutomationsResourceWithStreamingRespon return AsyncAutomationsResourceWithStreamingResponse(self._client.automations) + @cached_property + def billing(self) -> billing.AsyncBillingResourceWithStreamingResponse: + """BillingService provides billing and subscription management functionality.""" + from .resources.billing import AsyncBillingResourceWithStreamingResponse + + return AsyncBillingResourceWithStreamingResponse(self._client.billing) + @cached_property def editors(self) -> editors.AsyncEditorsResourceWithStreamingResponse: from .resources.editors import AsyncEditorsResourceWithStreamingResponse @@ -1029,16 +1075,6 @@ def environments(self) -> environments.AsyncEnvironmentsResourceWithStreamingRes return AsyncEnvironmentsResourceWithStreamingResponse(self._client.environments) - @cached_property - def errors(self) -> errors.AsyncErrorsResourceWithStreamingResponse: - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - from .resources.errors import AsyncErrorsResourceWithStreamingResponse - - return AsyncErrorsResourceWithStreamingResponse(self._client.errors) - @cached_property def events(self) -> events.AsyncEventsResourceWithStreamingResponse: from .resources.events import AsyncEventsResourceWithStreamingResponse @@ -1097,6 +1133,12 @@ def secrets(self) -> secrets.AsyncSecretsResourceWithStreamingResponse: return AsyncSecretsResourceWithStreamingResponse(self._client.secrets) + @cached_property + def security_policies(self) -> security_policies.AsyncSecurityPoliciesResourceWithStreamingResponse: + from .resources.security_policies import AsyncSecurityPoliciesResourceWithStreamingResponse + + return AsyncSecurityPoliciesResourceWithStreamingResponse(self._client.security_policies) + @cached_property def usage(self) -> usage.AsyncUsageResourceWithStreamingResponse: """ diff --git a/src/gitpod/_files.py b/src/gitpod/_files.py index cc14c14f..76da9e08 100644 --- a/src/gitpod/_files.py +++ b/src/gitpod/_files.py @@ -3,8 +3,8 @@ import io import os import pathlib -from typing import overload -from typing_extensions import TypeGuard +from typing import Sequence, cast, overload +from typing_extensions import TypeVar, TypeGuard import anyio @@ -17,7 +17,9 @@ HttpxFileContent, HttpxRequestFiles, ) -from ._utils import is_tuple_t, is_mapping_t, is_sequence_t +from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t + +_T = TypeVar("_T") def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]: @@ -97,7 +99,7 @@ async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles elif is_sequence_t(files): files = [(key, await _async_transform_file(file)) for key, file in files] else: - raise TypeError("Unexpected file type input {type(files)}, expected mapping or sequence") + raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence") return files @@ -121,3 +123,51 @@ async def async_read_file_content(file: FileContent) -> HttpxFileContent: return await anyio.Path(file).read_bytes() return file + + +def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T: + """Copy only the containers along the given paths. + + Used to guard against mutation by extract_files without copying the entire structure. + Only dicts and lists that lie on a path are copied; everything else + is returned by reference. + + For example, given paths=[["foo", "files", "file"]] and the structure: + { + "foo": { + "bar": {"baz": {}}, + "files": {"file": } + } + } + The root dict, "foo", and "files" are copied (they lie on the path). + "bar" and "baz" are returned by reference (off the path). + """ + return _deepcopy_with_paths(item, paths, 0) + + +def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T: + if not paths: + return item + if is_mapping(item): + key_to_paths: dict[str, list[Sequence[str]]] = {} + for path in paths: + if index < len(path): + key_to_paths.setdefault(path[index], []).append(path) + + # if no path continues through this mapping, it won't be mutated and copying it is redundant + if not key_to_paths: + return item + + result = dict(item) + for key, subpaths in key_to_paths.items(): + if key in result: + result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1) + return cast(_T, result) + if is_list(item): + array_paths = [path for path in paths if index < len(path) and path[index] == ""] + + # if no path expects a list here, nothing will be mutated inside it - return by reference + if not array_paths: + return cast(_T, item) + return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item]) + return item diff --git a/src/gitpod/_models.py b/src/gitpod/_models.py index 29070e05..8c5ab260 100644 --- a/src/gitpod/_models.py +++ b/src/gitpod/_models.py @@ -25,7 +25,9 @@ ClassVar, Protocol, Required, + Annotated, ParamSpec, + TypeAlias, TypedDict, TypeGuard, final, @@ -79,7 +81,15 @@ from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler + from pydantic_core import CoreSchema, core_schema from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema +else: + try: + from pydantic_core import CoreSchema, core_schema + except ImportError: + CoreSchema = None + core_schema = None __all__ = ["BaseModel", "GenericModel"] @@ -396,6 +406,76 @@ def model_dump_json( ) +class _EagerIterable(list[_T], Generic[_T]): + """ + Accepts any Iterable[T] input (including generators), consumes it + eagerly, and validates all items upfront. + + Validation preserves the original container type where possible + (e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON) + always emits a list — round-tripping through model_dump() will not + restore the original container type. + """ + + @classmethod + def __get_pydantic_core_schema__( + cls, + source_type: Any, + handler: GetCoreSchemaHandler, + ) -> CoreSchema: + (item_type,) = get_args(source_type) or (Any,) + item_schema: CoreSchema = handler.generate_schema(item_type) + list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema) + + return core_schema.no_info_wrap_validator_function( + cls._validate, + list_of_items_schema, + serialization=core_schema.plain_serializer_function_ser_schema( + cls._serialize, + info_arg=False, + ), + ) + + @staticmethod + def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any: + original_type: type[Any] = type(v) + + # Normalize to list so list_schema can validate each item + if isinstance(v, list): + items: list[_T] = v + else: + try: + items = list(v) + except TypeError as e: + raise TypeError("Value is not iterable") from e + + # Validate items against the inner schema + validated: list[_T] = handler(items) + + # Reconstruct original container type + if original_type is list: + return validated + # str(list) produces the list's repr, not a string built from items, + # so skip reconstruction for str and its subclasses. + if issubclass(original_type, str): + return validated + try: + return original_type(validated) + except (TypeError, ValueError): + # If the type cannot be reconstructed, just return the validated list + return validated + + @staticmethod + def _serialize(v: Iterable[_T]) -> list[_T]: + """Always serialize as a list so Pydantic's JSON encoder is happy.""" + if isinstance(v, list): + return v + return list(v) + + +EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable] + + def _construct_field(value: object, field: FieldInfo, key: str) -> object: if value is None: return field_get_default(field) diff --git a/src/gitpod/_qs.py b/src/gitpod/_qs.py index de8c99bc..4127c19c 100644 --- a/src/gitpod/_qs.py +++ b/src/gitpod/_qs.py @@ -2,17 +2,13 @@ from typing import Any, List, Tuple, Union, Mapping, TypeVar from urllib.parse import parse_qs, urlencode -from typing_extensions import Literal, get_args +from typing_extensions import get_args -from ._types import NotGiven, not_given +from ._types import NotGiven, ArrayFormat, NestedFormat, not_given from ._utils import flatten _T = TypeVar("_T") - -ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] -NestedFormat = Literal["dots", "brackets"] - PrimitiveData = Union[str, int, float, bool, None] # this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"] # https://github.com/microsoft/pyright/issues/3555 diff --git a/src/gitpod/_types.py b/src/gitpod/_types.py index dbebac09..8a15cebe 100644 --- a/src/gitpod/_types.py +++ b/src/gitpod/_types.py @@ -47,6 +47,9 @@ ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") +ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] +NestedFormat = Literal["dots", "brackets"] + # Approximates httpx internal ProxiesTypes and RequestFiles types # while adding support for `PathLike` instances diff --git a/src/gitpod/_utils/__init__.py b/src/gitpod/_utils/__init__.py index 10cb66d2..1c090e51 100644 --- a/src/gitpod/_utils/__init__.py +++ b/src/gitpod/_utils/__init__.py @@ -24,7 +24,6 @@ coerce_integer as coerce_integer, file_from_path as file_from_path, strip_not_given as strip_not_given, - deepcopy_minimal as deepcopy_minimal, get_async_library as get_async_library, maybe_coerce_float as maybe_coerce_float, get_required_header as get_required_header, diff --git a/src/gitpod/_utils/_utils.py b/src/gitpod/_utils/_utils.py index eec7f4a1..199cd231 100644 --- a/src/gitpod/_utils/_utils.py +++ b/src/gitpod/_utils/_utils.py @@ -17,11 +17,11 @@ ) from pathlib import Path from datetime import date, datetime -from typing_extensions import TypeGuard +from typing_extensions import TypeGuard, get_args import sniffio -from .._types import Omit, NotGiven, FileTypes, HeadersLike +from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike _T = TypeVar("_T") _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...]) @@ -40,25 +40,45 @@ def extract_files( query: Mapping[str, object], *, paths: Sequence[Sequence[str]], + array_format: ArrayFormat = "brackets", ) -> list[tuple[str, FileTypes]]: """Recursively extract files from the given dictionary based on specified paths. A path may look like this ['foo', 'files', '', 'data']. + ``array_format`` controls how ```` segments contribute to the emitted + field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and + ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``). + Note: this mutates the given dictionary. """ files: list[tuple[str, FileTypes]] = [] for path in paths: - files.extend(_extract_items(query, path, index=0, flattened_key=None)) + files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format)) return files +def _array_suffix(array_format: ArrayFormat, array_index: int) -> str: + if array_format == "brackets": + return "[]" + if array_format == "indices": + return f"[{array_index}]" + if array_format == "repeat" or array_format == "comma": + # Both repeat the bare field name for each file part; there is no + # meaningful way to comma-join binary parts. + return "" + raise NotImplementedError( + f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}" + ) + + def _extract_items( obj: object, path: Sequence[str], *, index: int, flattened_key: str | None, + array_format: ArrayFormat, ) -> list[tuple[str, FileTypes]]: try: key = path[index] @@ -75,9 +95,11 @@ def _extract_items( if is_list(obj): files: list[tuple[str, FileTypes]] = [] - for entry in obj: - assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "") - files.append((flattened_key + "[]", cast(FileTypes, entry))) + for array_index, entry in enumerate(obj): + suffix = _array_suffix(array_format, array_index) + emitted_key = (flattened_key + suffix) if flattened_key else suffix + assert_is_file_content(entry, key=emitted_key) + files.append((emitted_key, cast(FileTypes, entry))) return files assert_is_file_content(obj, key=flattened_key) @@ -86,8 +108,9 @@ def _extract_items( index += 1 if is_dict(obj): try: - # We are at the last entry in the path so we must remove the field - if (len(path)) == index: + # Remove the field if there are no more dict keys in the path, + # only "" traversal markers or end. + if all(p == "" for p in path[index:]): item = obj.pop(key) else: item = obj[key] @@ -105,6 +128,7 @@ def _extract_items( path, index=index, flattened_key=flattened_key, + array_format=array_format, ) elif is_list(obj): if key != "": @@ -116,9 +140,12 @@ def _extract_items( item, path, index=index, - flattened_key=flattened_key + "[]" if flattened_key is not None else "[]", + flattened_key=( + (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index) + ), + array_format=array_format, ) - for item in obj + for array_index, item in enumerate(obj) ] ) @@ -176,21 +203,6 @@ def is_iterable(obj: object) -> TypeGuard[Iterable[object]]: return isinstance(obj, Iterable) -def deepcopy_minimal(item: _T) -> _T: - """Minimal reimplementation of copy.deepcopy() that will only copy certain object types: - - - mappings, e.g. `dict` - - list - - This is done for performance reasons. - """ - if is_mapping(item): - return cast(_T, {k: deepcopy_minimal(v) for k, v in item.items()}) - if is_list(item): - return cast(_T, [deepcopy_minimal(entry) for entry in item]) - return item - - # copied from https://github.com/Rapptz/RoboDanny def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str: size = len(seq) diff --git a/src/gitpod/_version.py b/src/gitpod/_version.py index 7504df3f..6521e93a 100644 --- a/src/gitpod/_version.py +++ b/src/gitpod/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "gitpod" -__version__ = "0.11.0" # x-release-please-version +__version__ = "0.12.0" # x-release-please-version diff --git a/src/gitpod/pagination.py b/src/gitpod/pagination.py index b55ecc60..a206b2bd 100644 --- a/src/gitpod/pagination.py +++ b/src/gitpod/pagination.py @@ -51,6 +51,9 @@ "MembersPagePagination", "SyncMembersPage", "AsyncMembersPage", + "OrganizationsPagePagination", + "SyncOrganizationsPage", + "AsyncOrganizationsPage", "OutputsPagePagination", "SyncOutputsPage", "AsyncOutputsPage", @@ -87,6 +90,9 @@ "SecretsPagePagination", "SyncSecretsPage", "AsyncSecretsPage", + "SecurityPoliciesPagePagination", + "SyncSecurityPoliciesPage", + "AsyncSecurityPoliciesPage", "ServicesPagePagination", "SyncServicesPage", "AsyncServicesPage", @@ -99,9 +105,15 @@ "TasksPagePagination", "SyncTasksPage", "AsyncTasksPage", + "TeamUsagePagePagination", + "SyncTeamUsagePage", + "AsyncTeamUsagePage", "TokensPagePagination", "SyncTokensPage", "AsyncTokensPage", + "UserUsagePagePagination", + "SyncUserUsagePage", + "AsyncUserUsagePage", "WarmPoolsPagePagination", "SyncWarmPoolsPage", "AsyncWarmPoolsPage", @@ -819,6 +831,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"token": next_token}) +class OrganizationsPagePagination(BaseModel): + next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) + + +class SyncOrganizationsPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + organizations: List[_T] + pagination: Optional[OrganizationsPagePagination] = None + + @override + def _get_page_items(self) -> List[_T]: + organizations = self.organizations + if not organizations: + return [] + return organizations + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + +class AsyncOrganizationsPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + organizations: List[_T] + pagination: Optional[OrganizationsPagePagination] = None + + @override + def _get_page_items(self) -> List[_T]: + organizations = self.organizations + if not organizations: + return [] + return organizations + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + class OutputsPagePagination(BaseModel): next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) @@ -1419,6 +1481,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"token": next_token}) +class SecurityPoliciesPagePagination(BaseModel): + next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) + + +class SyncSecurityPoliciesPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[SecurityPoliciesPagePagination] = None + security_policies: List[_T] = FieldInfo(alias="securityPolicies") + + @override + def _get_page_items(self) -> List[_T]: + security_policies = self.security_policies + if not security_policies: + return [] + return security_policies + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + +class AsyncSecurityPoliciesPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[SecurityPoliciesPagePagination] = None + security_policies: List[_T] = FieldInfo(alias="securityPolicies") + + @override + def _get_page_items(self) -> List[_T]: + security_policies = self.security_policies + if not security_policies: + return [] + return security_policies + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + class ServicesPagePagination(BaseModel): next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) @@ -1619,6 +1731,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"token": next_token}) +class TeamUsagePagePagination(BaseModel): + next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) + + +class SyncTeamUsagePage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[TeamUsagePagePagination] = None + team_usage: List[_T] = FieldInfo(alias="teamUsage") + + @override + def _get_page_items(self) -> List[_T]: + team_usage = self.team_usage + if not team_usage: + return [] + return team_usage + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + +class AsyncTeamUsagePage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[TeamUsagePagePagination] = None + team_usage: List[_T] = FieldInfo(alias="teamUsage") + + @override + def _get_page_items(self) -> List[_T]: + team_usage = self.team_usage + if not team_usage: + return [] + return team_usage + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + class TokensPagePagination(BaseModel): next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) @@ -1669,6 +1831,56 @@ def next_page_info(self) -> Optional[PageInfo]: return PageInfo(params={"token": next_token}) +class UserUsagePagePagination(BaseModel): + next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) + + +class SyncUserUsagePage(BaseSyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[UserUsagePagePagination] = None + user_usage: List[_T] = FieldInfo(alias="userUsage") + + @override + def _get_page_items(self) -> List[_T]: + user_usage = self.user_usage + if not user_usage: + return [] + return user_usage + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + +class AsyncUserUsagePage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]): + pagination: Optional[UserUsagePagePagination] = None + user_usage: List[_T] = FieldInfo(alias="userUsage") + + @override + def _get_page_items(self) -> List[_T]: + user_usage = self.user_usage + if not user_usage: + return [] + return user_usage + + @override + def next_page_info(self) -> Optional[PageInfo]: + next_token = None + if self.pagination is not None: + if self.pagination.next_token is not None: + next_token = self.pagination.next_token + if not next_token: + return None + + return PageInfo(params={"token": next_token}) + + class WarmPoolsPagePagination(BaseModel): next_token: Optional[str] = FieldInfo(alias="nextToken", default=None) diff --git a/src/gitpod/resources/__init__.py b/src/gitpod/resources/__init__.py index 97c0390c..d322e0b5 100644 --- a/src/gitpod/resources/__init__.py +++ b/src/gitpod/resources/__init__.py @@ -24,14 +24,6 @@ AgentsResourceWithStreamingResponse, AsyncAgentsResourceWithStreamingResponse, ) -from .errors import ( - ErrorsResource, - AsyncErrorsResource, - ErrorsResourceWithRawResponse, - AsyncErrorsResourceWithRawResponse, - ErrorsResourceWithStreamingResponse, - AsyncErrorsResourceWithStreamingResponse, -) from .events import ( EventsResource, AsyncEventsResource, @@ -48,6 +40,14 @@ GroupsResourceWithStreamingResponse, AsyncGroupsResourceWithStreamingResponse, ) +from .billing import ( + BillingResource, + AsyncBillingResource, + BillingResourceWithRawResponse, + AsyncBillingResourceWithRawResponse, + BillingResourceWithStreamingResponse, + AsyncBillingResourceWithStreamingResponse, +) from .editors import ( EditorsResource, AsyncEditorsResource, @@ -136,6 +136,14 @@ OrganizationsResourceWithStreamingResponse, AsyncOrganizationsResourceWithStreamingResponse, ) +from .security_policies import ( + SecurityPoliciesResource, + AsyncSecurityPoliciesResource, + SecurityPoliciesResourceWithRawResponse, + AsyncSecurityPoliciesResourceWithRawResponse, + SecurityPoliciesResourceWithStreamingResponse, + AsyncSecurityPoliciesResourceWithStreamingResponse, +) __all__ = [ "AccountsResource", @@ -156,6 +164,12 @@ "AsyncAutomationsResourceWithRawResponse", "AutomationsResourceWithStreamingResponse", "AsyncAutomationsResourceWithStreamingResponse", + "BillingResource", + "AsyncBillingResource", + "BillingResourceWithRawResponse", + "AsyncBillingResourceWithRawResponse", + "BillingResourceWithStreamingResponse", + "AsyncBillingResourceWithStreamingResponse", "EditorsResource", "AsyncEditorsResource", "EditorsResourceWithRawResponse", @@ -168,12 +182,6 @@ "AsyncEnvironmentsResourceWithRawResponse", "EnvironmentsResourceWithStreamingResponse", "AsyncEnvironmentsResourceWithStreamingResponse", - "ErrorsResource", - "AsyncErrorsResource", - "ErrorsResourceWithRawResponse", - "AsyncErrorsResourceWithRawResponse", - "ErrorsResourceWithStreamingResponse", - "AsyncErrorsResourceWithStreamingResponse", "EventsResource", "AsyncEventsResource", "EventsResourceWithRawResponse", @@ -228,6 +236,12 @@ "AsyncSecretsResourceWithRawResponse", "SecretsResourceWithStreamingResponse", "AsyncSecretsResourceWithStreamingResponse", + "SecurityPoliciesResource", + "AsyncSecurityPoliciesResource", + "SecurityPoliciesResourceWithRawResponse", + "AsyncSecurityPoliciesResourceWithRawResponse", + "SecurityPoliciesResourceWithStreamingResponse", + "AsyncSecurityPoliciesResourceWithStreamingResponse", "UsageResource", "AsyncUsageResource", "UsageResourceWithRawResponse", diff --git a/src/gitpod/resources/agents.py b/src/gitpod/resources/agents.py index b5c22f9e..b68d84e0 100644 --- a/src/gitpod/resources/agents.py +++ b/src/gitpod/resources/agents.py @@ -42,6 +42,7 @@ from ..types.agent_code_context_param import AgentCodeContextParam from ..types.agent_create_prompt_response import AgentCreatePromptResponse from ..types.agent_update_prompt_response import AgentUpdatePromptResponse +from ..types.shared_params.codex_settings import CodexSettings from ..types.agent_retrieve_prompt_response import AgentRetrievePromptResponse from ..types.agent_start_execution_response import AgentStartExecutionResponse from ..types.agent_retrieve_execution_response import AgentRetrieveExecutionResponse @@ -486,6 +487,7 @@ def send_to_execution( *, agent_execution_id: str | Omit = omit, agent_message: AgentMessageParam | Omit = omit, + codex_settings: CodexSettings | Omit = omit, user_input: UserInputBlockParam | Omit = omit, wake_event: WakeEventParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -517,6 +519,9 @@ def send_to_execution( agent_message: AgentMessage is a message sent between agents (e.g. from a parent agent to a child agent execution, or vice versa). + codex_settings: codex_settings contains per-turn desired settings for Codex app user_input + sends. + wake_event: WakeEvent is sent by the backend to wake an agent when a registered interest fires. Delivered via SendToAgentExecution as a new oneof variant. @@ -534,6 +539,7 @@ def send_to_execution( { "agent_execution_id": agent_execution_id, "agent_message": agent_message, + "codex_settings": codex_settings, "user_input": user_input, "wake_event": wake_event, }, @@ -551,6 +557,7 @@ def start_execution( agent_id: str | Omit = omit, annotations: Dict[str, str] | Omit = omit, code_context: AgentCodeContextParam | Omit = omit, + codex_settings: CodexSettings | Omit = omit, mode: AgentMode | Omit = omit, name: str | Omit = omit, runner_id: str | Omit = omit, @@ -581,10 +588,16 @@ def start_execution( ``` Args: + agent_id: agent_id identifies the agent to start. If omitted, the backend uses the + configured default agent ID, or the Ona in-environment agent when no default is + configured. + annotations: annotations are key-value pairs for tracking external context (e.g., integration session IDs, GitHub issue references). Keys should follow domain/name convention (e.g., "agent-client-session/id"). + codex_settings: codex_settings contains desired manual settings for the Codex app agent. + mode: mode specifies the operational mode for this agent execution If not specified, defaults to AGENT_MODE_EXECUTION @@ -613,6 +626,7 @@ def start_execution( "agent_id": agent_id, "annotations": annotations, "code_context": code_context, + "codex_settings": codex_settings, "mode": mode, "name": name, "runner_id": runner_id, @@ -1167,6 +1181,7 @@ async def send_to_execution( *, agent_execution_id: str | Omit = omit, agent_message: AgentMessageParam | Omit = omit, + codex_settings: CodexSettings | Omit = omit, user_input: UserInputBlockParam | Omit = omit, wake_event: WakeEventParam | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1198,6 +1213,9 @@ async def send_to_execution( agent_message: AgentMessage is a message sent between agents (e.g. from a parent agent to a child agent execution, or vice versa). + codex_settings: codex_settings contains per-turn desired settings for Codex app user_input + sends. + wake_event: WakeEvent is sent by the backend to wake an agent when a registered interest fires. Delivered via SendToAgentExecution as a new oneof variant. @@ -1215,6 +1233,7 @@ async def send_to_execution( { "agent_execution_id": agent_execution_id, "agent_message": agent_message, + "codex_settings": codex_settings, "user_input": user_input, "wake_event": wake_event, }, @@ -1232,6 +1251,7 @@ async def start_execution( agent_id: str | Omit = omit, annotations: Dict[str, str] | Omit = omit, code_context: AgentCodeContextParam | Omit = omit, + codex_settings: CodexSettings | Omit = omit, mode: AgentMode | Omit = omit, name: str | Omit = omit, runner_id: str | Omit = omit, @@ -1262,10 +1282,16 @@ async def start_execution( ``` Args: + agent_id: agent_id identifies the agent to start. If omitted, the backend uses the + configured default agent ID, or the Ona in-environment agent when no default is + configured. + annotations: annotations are key-value pairs for tracking external context (e.g., integration session IDs, GitHub issue references). Keys should follow domain/name convention (e.g., "agent-client-session/id"). + codex_settings: codex_settings contains desired manual settings for the Codex app agent. + mode: mode specifies the operational mode for this agent execution If not specified, defaults to AGENT_MODE_EXECUTION @@ -1294,6 +1320,7 @@ async def start_execution( "agent_id": agent_id, "annotations": annotations, "code_context": code_context, + "codex_settings": codex_settings, "mode": mode, "name": name, "runner_id": runner_id, diff --git a/src/gitpod/resources/automations.py b/src/gitpod/resources/automations.py index 2cbece8b..e5b2bbf8 100644 --- a/src/gitpod/resources/automations.py +++ b/src/gitpod/resources/automations.py @@ -52,6 +52,7 @@ from ..types.automation_create_response import AutomationCreateResponse from ..types.automation_update_response import AutomationUpdateResponse from ..types.automation_retrieve_response import AutomationRetrieveResponse +from ..types.shared_params.codex_settings import CodexSettings from ..types.workflow_trigger_context_param import WorkflowTriggerContextParam from ..types.automation_start_execution_response import AutomationStartExecutionResponse from ..types.automation_retrieve_execution_response import AutomationRetrieveExecutionResponse @@ -85,6 +86,7 @@ def create( self, *, action: WorkflowActionParam, + codex_settings: CodexSettings | Omit = omit, description: str | Omit = omit, executor: Optional[Subject] | Omit = omit, name: str | Omit = omit, @@ -110,6 +112,9 @@ def create( Args: action: WorkflowAction defines the actions to be executed in a workflow. + codex_settings: Codex app agent settings. Only meaningful when agent_id refers to the Codex app + agent. + description: Description must be at most 500 characters: @@ -149,6 +154,7 @@ def create( body=maybe_transform( { "action": action, + "codex_settings": codex_settings, "description": description, "executor": executor, "name": name, @@ -215,6 +221,7 @@ def update( self, *, action: Optional[WorkflowActionParam] | Omit = omit, + codex_settings: Optional[CodexSettings] | Omit = omit, description: Optional[str] | Omit = omit, disabled: Optional[bool] | Omit = omit, executor: Optional[Subject] | Omit = omit, @@ -288,6 +295,9 @@ def update( Args: action: WorkflowAction defines the actions to be executed in a workflow. + codex_settings: Codex app agent settings. Only meaningful when agent_id refers to the Codex app + agent. + description: Description must be at most 500 characters: @@ -327,6 +337,7 @@ def update( body=maybe_transform( { "action": action, + "codex_settings": codex_settings, "description": description, "disabled": disabled, "executor": executor, @@ -987,6 +998,7 @@ async def create( self, *, action: WorkflowActionParam, + codex_settings: CodexSettings | Omit = omit, description: str | Omit = omit, executor: Optional[Subject] | Omit = omit, name: str | Omit = omit, @@ -1012,6 +1024,9 @@ async def create( Args: action: WorkflowAction defines the actions to be executed in a workflow. + codex_settings: Codex app agent settings. Only meaningful when agent_id refers to the Codex app + agent. + description: Description must be at most 500 characters: @@ -1051,6 +1066,7 @@ async def create( body=await async_maybe_transform( { "action": action, + "codex_settings": codex_settings, "description": description, "executor": executor, "name": name, @@ -1119,6 +1135,7 @@ async def update( self, *, action: Optional[WorkflowActionParam] | Omit = omit, + codex_settings: Optional[CodexSettings] | Omit = omit, description: Optional[str] | Omit = omit, disabled: Optional[bool] | Omit = omit, executor: Optional[Subject] | Omit = omit, @@ -1192,6 +1209,9 @@ async def update( Args: action: WorkflowAction defines the actions to be executed in a workflow. + codex_settings: Codex app agent settings. Only meaningful when agent_id refers to the Codex app + agent. + description: Description must be at most 500 characters: @@ -1231,6 +1251,7 @@ async def update( body=await async_maybe_transform( { "action": action, + "codex_settings": codex_settings, "description": description, "disabled": disabled, "executor": executor, diff --git a/src/gitpod/resources/billing.py b/src/gitpod/resources/billing.py new file mode 100644 index 00000000..275ce5cd --- /dev/null +++ b/src/gitpod/resources/billing.py @@ -0,0 +1,1592 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime + +import httpx + +from ..types import ( + CreditUsageExportGroupBy, + billing_get_credit_usage_export_params, + billing_get_credit_usage_report_params, + billing_get_cumulative_credit_usage_params, + billing_list_enterprise_ai_team_usage_params, + billing_list_enterprise_ai_user_usage_params, + billing_get_enterprise_ai_usage_summary_params, + billing_list_enterprise_user_credit_usage_params, + billing_get_enterprise_ai_usage_time_series_params, +) +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..pagination import SyncTeamUsagePage, SyncUserUsagePage, AsyncTeamUsagePage, AsyncUserUsagePage +from .._base_client import AsyncPaginator, make_request_options +from ..types.user_cost_budget_usage import UserCostBudgetUsage +from ..types.shared_params.date_range import DateRange +from ..types.team_enterprise_ai_usage import TeamEnterpriseAIUsage +from ..types.user_credit_budget_usage import UserCreditBudgetUsage +from ..types.credit_usage_export_group_by import CreditUsageExportGroupBy +from ..types.credit_usage_report_filter_param import CreditUsageReportFilterParam +from ..types.billing_get_credit_usage_export_response import BillingGetCreditUsageExportResponse +from ..types.billing_get_credit_usage_report_response import BillingGetCreditUsageReportResponse +from ..types.billing_get_cumulative_credit_usage_response import BillingGetCumulativeCreditUsageResponse +from ..types.enterprise_ai_usage_time_series_filter_param import EnterpriseAIUsageTimeSeriesFilterParam +from ..types.billing_get_enterprise_ai_usage_summary_response import BillingGetEnterpriseAIUsageSummaryResponse +from ..types.billing_get_enterprise_ai_usage_time_series_response import BillingGetEnterpriseAIUsageTimeSeriesResponse + +__all__ = ["BillingResource", "AsyncBillingResource"] + + +class BillingResource(SyncAPIResource): + """BillingService provides billing and subscription management functionality.""" + + @cached_property + def with_raw_response(self) -> BillingResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return BillingResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> BillingResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return BillingResourceWithStreamingResponse(self) + + def get_credit_usage_export( + self, + *, + date_range: DateRange, + organization_id: str, + group_by: CreditUsageExportGroupBy | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCreditUsageExportResponse: + """ + Returns a signed download URL for a CSV export of credit usage. + + The URL points to an HTTP endpoint that streams gzip-compressed CSV and is valid + for five minutes. The download must be made by the same principal that requested + it, carrying its own bearer token. The export range may cover up to a year. + + For organizations without enterprise credit usage enabled (no billing contract + start date), the export instead contains BYOK cost usage with a different column + set, and groupBy=RESOURCE is rejected. + + Use this method to: + + - Export per-user daily credit usage for external reporting + - Export a per-environment and per-conversation resource breakdown + + ### Examples + + - Export January's daily summary: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + groupBy: CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range to export. Both start and end dates are inclusive; time-of-day is + ignored. Unlike GetCreditUsageReport, the range may cover up to a year. + + group_by: How to group the export data. Defaults to DAILY_SUMMARY. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.BillingService/GetCreditUsageExport", + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "group_by": group_by, + }, + billing_get_credit_usage_export_params.BillingGetCreditUsageExportParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCreditUsageExportResponse, + ) + + def get_credit_usage_report( + self, + *, + date_range: DateRange, + organization_id: str, + filter: CreditUsageReportFilterParam | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCreditUsageReportResponse: + """ + Returns a daily credit usage report for an enterprise organization. + + Each day reports org-wide credits by usage type, plus per-user, per-team, + per-environment, and per-conversation breakdowns (top consumers with the + remainder aggregated into an "Others" bucket) and a per-model breakdown of + intelligence usage. + + Use this method to: + + - Chart daily credit consumption over a date range + - Attribute credit usage to users, teams, environments, and conversations + - Restrict the report to a single user or service account + + ### Examples + + - Get the report for January: + + Both dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. A user without it + can read their own usage by setting filter.subject to their own user identity; + this self-access path is not available to service accounts. + + Args: + date_range: Date range for the report. Both start and end dates are inclusive. Time-of-day + is ignored; dates are truncated to midnight in the specified timezone. The range + must not exceed 31 days. + + filter: Optional filter narrowing the returned data. When unset or empty, the response + preserves the default behavior (top-N users + "Others"). See + CreditUsageReportFilter for per-field response-scoping semantics. + + timezone: IANA timezone name (e.g. "America/New_York", "Europe/Berlin") used to bucket + daily usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.BillingService/GetCreditUsageReport", + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "timezone": timezone, + }, + billing_get_credit_usage_report_params.BillingGetCreditUsageReportParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCreditUsageReportResponse, + ) + + def get_cumulative_credit_usage( + self, + *, + organization_id: str, + as_of: Union[str, datetime, None] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCumulativeCreditUsageResponse: + """ + Returns cumulative credit usage for an organization and its teams. + + Use this method to: + + - Get the total cumulative credit consumption as of a point in time + - Get per-team cumulative usage with credit allocation (budget) comparison + - Display team credit summaries on the usage page and team detail page + - Display user budget utilization when user budgets are enabled + + ### Examples + + - Get current cumulative usage: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ``` + + - Get cumulative usage as of a specific date: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + asOf: "2026-03-31T23:59:59Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + organization_id: organization_id is the ID of the organization to get cumulative usage for. + + as_of: as_of is the point in time to compute cumulative usage up to. Defaults to now if + not set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.BillingService/GetCumulativeCreditUsage", + body=maybe_transform( + { + "organization_id": organization_id, + "as_of": as_of, + }, + billing_get_cumulative_credit_usage_params.BillingGetCumulativeCreditUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCumulativeCreditUsageResponse, + ) + + def get_enterprise_ai_usage_summary( + self, + *, + date_range: DateRange, + organization_id: str, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetEnterpriseAIUsageSummaryResponse: + """ + Returns organization-level enterprise AI usage totals for reporting. + + Reports BYOK (bring-your-own-key) token spend: cost in the organization's + billing currency plus token counts, with a per-model breakdown. Credit-based + usage from managed models is not included and the credits field is not populated + by this endpoint. + + Use this method to: + + - Report total BYOK AI spend (cost and tokens) for a date range + - Break down organization usage by model + + Only available for enterprise organizations. + + ### Examples + + - Get usage totals for January: + + Returns organization-wide BYOK spend for the month. Both dates are inclusive + and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the summary. Both start and end dates are inclusive. Time-of-day + is ignored; dates are truncated to midnight in the specified timezone. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.BillingService/GetEnterpriseAIUsageSummary", + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "timezone": timezone, + }, + billing_get_enterprise_ai_usage_summary_params.BillingGetEnterpriseAIUsageSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetEnterpriseAIUsageSummaryResponse, + ) + + def get_enterprise_ai_usage_time_series( + self, + *, + date_range: DateRange, + organization_id: str, + filter: EnterpriseAIUsageTimeSeriesFilterParam | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetEnterpriseAIUsageTimeSeriesResponse: + """ + Returns daily enterprise AI usage totals for the organization. + + Each day reports BYOK token spend (cost and tokens) with per-user, per-team, and + per-model breakdowns. Per-user entries cover the top spenders with the remainder + aggregated into an "Others" bucket; usage not attributed to a user or service + account appears only in the daily totals. The credits field is not populated by + this endpoint. + + When filter.subject is set the response contains only that subject's usage: + daily totals and the team breakdown are omitted, and the model breakdown covers + the subject only. + + Use this method to: + + - Chart daily BYOK AI spend over a date range + - Feed daily per-user usage into external dashboards + - Restrict the response to a single user or service account + + Only available for enterprise organizations. + + ### Examples + + - Get daily usage for January: + + Returns one entry per day with per-user, per-team, and per-model breakdowns. + Both dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the daily usage series. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + timezone: IANA timezone name used to bucket daily usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.BillingService/GetEnterpriseAIUsageTimeSeries", + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "timezone": timezone, + }, + billing_get_enterprise_ai_usage_time_series_params.BillingGetEnterpriseAIUsageTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetEnterpriseAIUsageTimeSeriesResponse, + ) + + def list_enterprise_ai_team_usage( + self, + *, + date_range: DateRange, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: billing_list_enterprise_ai_team_usage_params.Filter | Omit = omit, + pagination: billing_list_enterprise_ai_team_usage_params.Pagination | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncTeamUsagePage[TeamEnterpriseAIUsage]: + """ + Lists enterprise AI usage grouped by team. + + Reports BYOK token spend per team (cost and tokens) with each team's monthly + budget when one applies. The credits field is not populated by this endpoint. + + Use this method to: + + - Compare BYOK AI spend across teams + - Track team budget utilization + - Filter usage to specific teams + + Only available for enterprise organizations. + + ### Examples + + - List team usage for January: + + Returns BYOK spend per team with monthly budgets. Both dates are inclusive and + the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the team usage list. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseAITeamUsage", + page=SyncTeamUsagePage[TeamEnterpriseAIUsage], + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "pagination": pagination, + "timezone": timezone, + }, + billing_list_enterprise_ai_team_usage_params.BillingListEnterpriseAITeamUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_ai_team_usage_params.BillingListEnterpriseAITeamUsageParams, + ), + ), + model=TeamEnterpriseAIUsage, + method="post", + ) + + def list_enterprise_ai_user_usage( + self, + *, + date_range: DateRange, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: billing_list_enterprise_ai_user_usage_params.Filter | Omit = omit, + pagination: billing_list_enterprise_ai_user_usage_params.Pagination | Omit = omit, + sort: billing_list_enterprise_ai_user_usage_params.Sort | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncUserUsagePage[UserCostBudgetUsage]: + """ + Lists enterprise AI usage grouped by user with effective monthly budget data. + + Reports BYOK token spend (cost and tokens) for each user and service account + with attributed usage in the date range, including each subject's effective + monthly budget. Usage not attributed to a user or service account is excluded, + so the sum across subjects can be less than the organization totals from + GetEnterpriseAIUsageSummary. The credits field is not populated by this + endpoint. + + Budget fields (month_to_date_usage, utilization_percent, over_budget) are + computed from usage inside the requested date range measured against the monthly + limit. Send a range that starts on the first day of the month for true + month-to-date figures. + + Use this method to: + + - Export per-user BYOK AI spend to external reporting + - Identify the highest spenders in the organization + - Track per-user budget utilization and over-budget users + + Only available for enterprise organizations. + + ### Examples + + - List user usage for January: + + Returns per-user BYOK spend with effective budgets, highest spend first. Both + dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. Callers without it + can read their own usage by setting filter.subject to themselves. + + Args: + date_range: Date range for the user usage list. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + filter: Optional filter narrowing the returned user usage. When set to a subject, the + response contains only usage for that user or service account. + + sort: sort controls the ordering of results. Defaults to total spend descending. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseAIUserUsage", + page=SyncUserUsagePage[UserCostBudgetUsage], + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "pagination": pagination, + "sort": sort, + "timezone": timezone, + }, + billing_list_enterprise_ai_user_usage_params.BillingListEnterpriseAIUserUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_ai_user_usage_params.BillingListEnterpriseAIUserUsageParams, + ), + ), + model=UserCostBudgetUsage, + method="post", + ) + + def list_enterprise_user_credit_usage( + self, + *, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + as_of: Union[str, datetime, None] | Omit = omit, + pagination: billing_list_enterprise_user_credit_usage_params.Pagination | Omit = omit, + sort: billing_list_enterprise_user_credit_usage_params.Sort | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncUserUsagePage[UserCreditBudgetUsage]: + """ + Lists per-user month-to-date credit usage with effective monthly budgets. + + Results are ordered by total credits descending so the highest spenders appear + first, with user_id as a stable tiebreaker. Use cursor pagination to walk the + full set for large organizations. + + The default SORT_FIELD_USAGE ordering supports cursor pagination over any number + of users. Sorting by display name, budget, or budget utilization computes the + order in memory and is limited to organizations with at most 10,000 users; + beyond that, use SORT_FIELD_USAGE. Because month-to-date figures are recomputed + per request, hold a date range stable across a paginated walk to keep page + tokens valid. + + Use this method to: + + - Export per-user credit usage to external reporting + - Identify the highest spenders in the organization + - Track per-user budget utilization and over-budget users + + ### Examples + + - List user usage for the current month: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + pagination: + pageSize: 50 + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + organization_id: organization_id is the ID of the organization to list user credit usage for. + + as_of: as_of is the point in time to compute month-to-date usage up to. Defaults to now + if not set. + + sort: sort controls the ordering of results. Defaults to total credits descending. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseUserCreditUsage", + page=SyncUserUsagePage[UserCreditBudgetUsage], + body=maybe_transform( + { + "organization_id": organization_id, + "as_of": as_of, + "pagination": pagination, + "sort": sort, + }, + billing_list_enterprise_user_credit_usage_params.BillingListEnterpriseUserCreditUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_user_credit_usage_params.BillingListEnterpriseUserCreditUsageParams, + ), + ), + model=UserCreditBudgetUsage, + method="post", + ) + + +class AsyncBillingResource(AsyncAPIResource): + """BillingService provides billing and subscription management functionality.""" + + @cached_property + def with_raw_response(self) -> AsyncBillingResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncBillingResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncBillingResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return AsyncBillingResourceWithStreamingResponse(self) + + async def get_credit_usage_export( + self, + *, + date_range: DateRange, + organization_id: str, + group_by: CreditUsageExportGroupBy | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCreditUsageExportResponse: + """ + Returns a signed download URL for a CSV export of credit usage. + + The URL points to an HTTP endpoint that streams gzip-compressed CSV and is valid + for five minutes. The download must be made by the same principal that requested + it, carrying its own bearer token. The export range may cover up to a year. + + For organizations without enterprise credit usage enabled (no billing contract + start date), the export instead contains BYOK cost usage with a different column + set, and groupBy=RESOURCE is rejected. + + Use this method to: + + - Export per-user daily credit usage for external reporting + - Export a per-environment and per-conversation resource breakdown + + ### Examples + + - Export January's daily summary: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + groupBy: CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range to export. Both start and end dates are inclusive; time-of-day is + ignored. Unlike GetCreditUsageReport, the range may cover up to a year. + + group_by: How to group the export data. Defaults to DAILY_SUMMARY. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.BillingService/GetCreditUsageExport", + body=await async_maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "group_by": group_by, + }, + billing_get_credit_usage_export_params.BillingGetCreditUsageExportParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCreditUsageExportResponse, + ) + + async def get_credit_usage_report( + self, + *, + date_range: DateRange, + organization_id: str, + filter: CreditUsageReportFilterParam | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCreditUsageReportResponse: + """ + Returns a daily credit usage report for an enterprise organization. + + Each day reports org-wide credits by usage type, plus per-user, per-team, + per-environment, and per-conversation breakdowns (top consumers with the + remainder aggregated into an "Others" bucket) and a per-model breakdown of + intelligence usage. + + Use this method to: + + - Chart daily credit consumption over a date range + - Attribute credit usage to users, teams, environments, and conversations + - Restrict the report to a single user or service account + + ### Examples + + - Get the report for January: + + Both dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. A user without it + can read their own usage by setting filter.subject to their own user identity; + this self-access path is not available to service accounts. + + Args: + date_range: Date range for the report. Both start and end dates are inclusive. Time-of-day + is ignored; dates are truncated to midnight in the specified timezone. The range + must not exceed 31 days. + + filter: Optional filter narrowing the returned data. When unset or empty, the response + preserves the default behavior (top-N users + "Others"). See + CreditUsageReportFilter for per-field response-scoping semantics. + + timezone: IANA timezone name (e.g. "America/New_York", "Europe/Berlin") used to bucket + daily usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.BillingService/GetCreditUsageReport", + body=await async_maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "timezone": timezone, + }, + billing_get_credit_usage_report_params.BillingGetCreditUsageReportParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCreditUsageReportResponse, + ) + + async def get_cumulative_credit_usage( + self, + *, + organization_id: str, + as_of: Union[str, datetime, None] | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetCumulativeCreditUsageResponse: + """ + Returns cumulative credit usage for an organization and its teams. + + Use this method to: + + - Get the total cumulative credit consumption as of a point in time + - Get per-team cumulative usage with credit allocation (budget) comparison + - Display team credit summaries on the usage page and team detail page + - Display user budget utilization when user budgets are enabled + + ### Examples + + - Get current cumulative usage: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + ``` + + - Get cumulative usage as of a specific date: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + asOf: "2026-03-31T23:59:59Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + organization_id: organization_id is the ID of the organization to get cumulative usage for. + + as_of: as_of is the point in time to compute cumulative usage up to. Defaults to now if + not set. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.BillingService/GetCumulativeCreditUsage", + body=await async_maybe_transform( + { + "organization_id": organization_id, + "as_of": as_of, + }, + billing_get_cumulative_credit_usage_params.BillingGetCumulativeCreditUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetCumulativeCreditUsageResponse, + ) + + async def get_enterprise_ai_usage_summary( + self, + *, + date_range: DateRange, + organization_id: str, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetEnterpriseAIUsageSummaryResponse: + """ + Returns organization-level enterprise AI usage totals for reporting. + + Reports BYOK (bring-your-own-key) token spend: cost in the organization's + billing currency plus token counts, with a per-model breakdown. Credit-based + usage from managed models is not included and the credits field is not populated + by this endpoint. + + Use this method to: + + - Report total BYOK AI spend (cost and tokens) for a date range + - Break down organization usage by model + + Only available for enterprise organizations. + + ### Examples + + - Get usage totals for January: + + Returns organization-wide BYOK spend for the month. Both dates are inclusive + and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the summary. Both start and end dates are inclusive. Time-of-day + is ignored; dates are truncated to midnight in the specified timezone. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.BillingService/GetEnterpriseAIUsageSummary", + body=await async_maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "timezone": timezone, + }, + billing_get_enterprise_ai_usage_summary_params.BillingGetEnterpriseAIUsageSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetEnterpriseAIUsageSummaryResponse, + ) + + async def get_enterprise_ai_usage_time_series( + self, + *, + date_range: DateRange, + organization_id: str, + filter: EnterpriseAIUsageTimeSeriesFilterParam | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> BillingGetEnterpriseAIUsageTimeSeriesResponse: + """ + Returns daily enterprise AI usage totals for the organization. + + Each day reports BYOK token spend (cost and tokens) with per-user, per-team, and + per-model breakdowns. Per-user entries cover the top spenders with the remainder + aggregated into an "Others" bucket; usage not attributed to a user or service + account appears only in the daily totals. The credits field is not populated by + this endpoint. + + When filter.subject is set the response contains only that subject's usage: + daily totals and the team breakdown are omitted, and the model breakdown covers + the subject only. + + Use this method to: + + - Chart daily BYOK AI spend over a date range + - Feed daily per-user usage into external dashboards + - Restrict the response to a single user or service account + + Only available for enterprise organizations. + + ### Examples + + - Get daily usage for January: + + Returns one entry per day with per-user, per-team, and per-model breakdowns. + Both dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the daily usage series. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + timezone: IANA timezone name used to bucket daily usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.BillingService/GetEnterpriseAIUsageTimeSeries", + body=await async_maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "timezone": timezone, + }, + billing_get_enterprise_ai_usage_time_series_params.BillingGetEnterpriseAIUsageTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=BillingGetEnterpriseAIUsageTimeSeriesResponse, + ) + + def list_enterprise_ai_team_usage( + self, + *, + date_range: DateRange, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: billing_list_enterprise_ai_team_usage_params.Filter | Omit = omit, + pagination: billing_list_enterprise_ai_team_usage_params.Pagination | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[TeamEnterpriseAIUsage, AsyncTeamUsagePage[TeamEnterpriseAIUsage]]: + """ + Lists enterprise AI usage grouped by team. + + Reports BYOK token spend per team (cost and tokens) with each team's monthly + budget when one applies. The credits field is not populated by this endpoint. + + Use this method to: + + - Compare BYOK AI spend across teams + - Track team budget utilization + - Filter usage to specific teams + + Only available for enterprise organizations. + + ### Examples + + - List team usage for January: + + Returns BYOK spend per team with monthly budgets. Both dates are inclusive and + the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + date_range: Date range for the team usage list. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseAITeamUsage", + page=AsyncTeamUsagePage[TeamEnterpriseAIUsage], + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "pagination": pagination, + "timezone": timezone, + }, + billing_list_enterprise_ai_team_usage_params.BillingListEnterpriseAITeamUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_ai_team_usage_params.BillingListEnterpriseAITeamUsageParams, + ), + ), + model=TeamEnterpriseAIUsage, + method="post", + ) + + def list_enterprise_ai_user_usage( + self, + *, + date_range: DateRange, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: billing_list_enterprise_ai_user_usage_params.Filter | Omit = omit, + pagination: billing_list_enterprise_ai_user_usage_params.Pagination | Omit = omit, + sort: billing_list_enterprise_ai_user_usage_params.Sort | Omit = omit, + timezone: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[UserCostBudgetUsage, AsyncUserUsagePage[UserCostBudgetUsage]]: + """ + Lists enterprise AI usage grouped by user with effective monthly budget data. + + Reports BYOK token spend (cost and tokens) for each user and service account + with attributed usage in the date range, including each subject's effective + monthly budget. Usage not attributed to a user or service account is excluded, + so the sum across subjects can be less than the organization totals from + GetEnterpriseAIUsageSummary. The credits field is not populated by this + endpoint. + + Budget fields (month_to_date_usage, utilization_percent, over_budget) are + computed from usage inside the requested date range measured against the monthly + limit. Send a range that starts on the first day of the month for true + month-to-date figures. + + Use this method to: + + - Export per-user BYOK AI spend to external reporting + - Identify the highest spenders in the organization + - Track per-user budget utilization and over-budget users + + Only available for enterprise organizations. + + ### Examples + + - List user usage for January: + + Returns per-user BYOK spend with effective budgets, highest spend first. Both + dates are inclusive and the range must not exceed 31 days. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-31T00:00:00Z" + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. Callers without it + can read their own usage by setting filter.subject to themselves. + + Args: + date_range: Date range for the user usage list. Both start and end dates are inclusive. + Time-of-day is ignored; dates are truncated to midnight in the specified + timezone. + + filter: Optional filter narrowing the returned user usage. When set to a subject, the + response contains only usage for that user or service account. + + sort: sort controls the ordering of results. Defaults to total spend descending. + + timezone: IANA timezone name used to bucket usage. When empty, defaults to "UTC". + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseAIUserUsage", + page=AsyncUserUsagePage[UserCostBudgetUsage], + body=maybe_transform( + { + "date_range": date_range, + "organization_id": organization_id, + "filter": filter, + "pagination": pagination, + "sort": sort, + "timezone": timezone, + }, + billing_list_enterprise_ai_user_usage_params.BillingListEnterpriseAIUserUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_ai_user_usage_params.BillingListEnterpriseAIUserUsageParams, + ), + ), + model=UserCostBudgetUsage, + method="post", + ) + + def list_enterprise_user_credit_usage( + self, + *, + organization_id: str, + token: str | Omit = omit, + page_size: int | Omit = omit, + as_of: Union[str, datetime, None] | Omit = omit, + pagination: billing_list_enterprise_user_credit_usage_params.Pagination | Omit = omit, + sort: billing_list_enterprise_user_credit_usage_params.Sort | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[UserCreditBudgetUsage, AsyncUserUsagePage[UserCreditBudgetUsage]]: + """ + Lists per-user month-to-date credit usage with effective monthly budgets. + + Results are ordered by total credits descending so the highest spenders appear + first, with user_id as a stable tiebreaker. Use cursor pagination to walk the + full set for large organizations. + + The default SORT_FIELD_USAGE ordering supports cursor pagination over any number + of users. Sorting by display name, budget, or budget utilization computes the + order in memory and is limited to organizations with at most 10,000 users; + beyond that, use SORT_FIELD_USAGE. Because month-to-date figures are recomputed + per request, hold a date range stable across a paginated walk to keep page + tokens valid. + + Use this method to: + + - Export per-user credit usage to external reporting + - Identify the highest spenders in the organization + - Track per-user budget utilization and over-budget users + + ### Examples + + - List user usage for the current month: + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + pagination: + pageSize: 50 + ``` + + ### Authorization + + Requires `billing:read_usage` permission on the organization. + + Args: + organization_id: organization_id is the ID of the organization to list user credit usage for. + + as_of: as_of is the point in time to compute month-to-date usage up to. Defaults to now + if not set. + + sort: sort controls the ordering of results. Defaults to total credits descending. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.BillingService/ListEnterpriseUserCreditUsage", + page=AsyncUserUsagePage[UserCreditBudgetUsage], + body=maybe_transform( + { + "organization_id": organization_id, + "as_of": as_of, + "pagination": pagination, + "sort": sort, + }, + billing_list_enterprise_user_credit_usage_params.BillingListEnterpriseUserCreditUsageParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + billing_list_enterprise_user_credit_usage_params.BillingListEnterpriseUserCreditUsageParams, + ), + ), + model=UserCreditBudgetUsage, + method="post", + ) + + +class BillingResourceWithRawResponse: + def __init__(self, billing: BillingResource) -> None: + self._billing = billing + + self.get_credit_usage_export = to_raw_response_wrapper( + billing.get_credit_usage_export, + ) + self.get_credit_usage_report = to_raw_response_wrapper( + billing.get_credit_usage_report, + ) + self.get_cumulative_credit_usage = to_raw_response_wrapper( + billing.get_cumulative_credit_usage, + ) + self.get_enterprise_ai_usage_summary = to_raw_response_wrapper( + billing.get_enterprise_ai_usage_summary, + ) + self.get_enterprise_ai_usage_time_series = to_raw_response_wrapper( + billing.get_enterprise_ai_usage_time_series, + ) + self.list_enterprise_ai_team_usage = to_raw_response_wrapper( + billing.list_enterprise_ai_team_usage, + ) + self.list_enterprise_ai_user_usage = to_raw_response_wrapper( + billing.list_enterprise_ai_user_usage, + ) + self.list_enterprise_user_credit_usage = to_raw_response_wrapper( + billing.list_enterprise_user_credit_usage, + ) + + +class AsyncBillingResourceWithRawResponse: + def __init__(self, billing: AsyncBillingResource) -> None: + self._billing = billing + + self.get_credit_usage_export = async_to_raw_response_wrapper( + billing.get_credit_usage_export, + ) + self.get_credit_usage_report = async_to_raw_response_wrapper( + billing.get_credit_usage_report, + ) + self.get_cumulative_credit_usage = async_to_raw_response_wrapper( + billing.get_cumulative_credit_usage, + ) + self.get_enterprise_ai_usage_summary = async_to_raw_response_wrapper( + billing.get_enterprise_ai_usage_summary, + ) + self.get_enterprise_ai_usage_time_series = async_to_raw_response_wrapper( + billing.get_enterprise_ai_usage_time_series, + ) + self.list_enterprise_ai_team_usage = async_to_raw_response_wrapper( + billing.list_enterprise_ai_team_usage, + ) + self.list_enterprise_ai_user_usage = async_to_raw_response_wrapper( + billing.list_enterprise_ai_user_usage, + ) + self.list_enterprise_user_credit_usage = async_to_raw_response_wrapper( + billing.list_enterprise_user_credit_usage, + ) + + +class BillingResourceWithStreamingResponse: + def __init__(self, billing: BillingResource) -> None: + self._billing = billing + + self.get_credit_usage_export = to_streamed_response_wrapper( + billing.get_credit_usage_export, + ) + self.get_credit_usage_report = to_streamed_response_wrapper( + billing.get_credit_usage_report, + ) + self.get_cumulative_credit_usage = to_streamed_response_wrapper( + billing.get_cumulative_credit_usage, + ) + self.get_enterprise_ai_usage_summary = to_streamed_response_wrapper( + billing.get_enterprise_ai_usage_summary, + ) + self.get_enterprise_ai_usage_time_series = to_streamed_response_wrapper( + billing.get_enterprise_ai_usage_time_series, + ) + self.list_enterprise_ai_team_usage = to_streamed_response_wrapper( + billing.list_enterprise_ai_team_usage, + ) + self.list_enterprise_ai_user_usage = to_streamed_response_wrapper( + billing.list_enterprise_ai_user_usage, + ) + self.list_enterprise_user_credit_usage = to_streamed_response_wrapper( + billing.list_enterprise_user_credit_usage, + ) + + +class AsyncBillingResourceWithStreamingResponse: + def __init__(self, billing: AsyncBillingResource) -> None: + self._billing = billing + + self.get_credit_usage_export = async_to_streamed_response_wrapper( + billing.get_credit_usage_export, + ) + self.get_credit_usage_report = async_to_streamed_response_wrapper( + billing.get_credit_usage_report, + ) + self.get_cumulative_credit_usage = async_to_streamed_response_wrapper( + billing.get_cumulative_credit_usage, + ) + self.get_enterprise_ai_usage_summary = async_to_streamed_response_wrapper( + billing.get_enterprise_ai_usage_summary, + ) + self.get_enterprise_ai_usage_time_series = async_to_streamed_response_wrapper( + billing.get_enterprise_ai_usage_time_series, + ) + self.list_enterprise_ai_team_usage = async_to_streamed_response_wrapper( + billing.list_enterprise_ai_team_usage, + ) + self.list_enterprise_ai_user_usage = async_to_streamed_response_wrapper( + billing.list_enterprise_ai_user_usage, + ) + self.list_enterprise_user_credit_usage = async_to_streamed_response_wrapper( + billing.list_enterprise_user_credit_usage, + ) diff --git a/src/gitpod/resources/errors.py b/src/gitpod/resources/errors.py deleted file mode 100644 index 68f6e2b4..00000000 --- a/src/gitpod/resources/errors.py +++ /dev/null @@ -1,209 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable - -import httpx - -from ..types import error_report_errors_params -from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform, async_maybe_transform -from .._compat import cached_property -from .._resource import SyncAPIResource, AsyncAPIResource -from .._response import ( - to_raw_response_wrapper, - to_streamed_response_wrapper, - async_to_raw_response_wrapper, - async_to_streamed_response_wrapper, -) -from .._base_client import make_request_options -from ..types.error_event_param import ErrorEventParam - -__all__ = ["ErrorsResource", "AsyncErrorsResource"] - - -class ErrorsResource(SyncAPIResource): - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - - @cached_property - def with_raw_response(self) -> ErrorsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers - """ - return ErrorsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> ErrorsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response - """ - return ErrorsResourceWithStreamingResponse(self) - - def report_errors( - self, - *, - events: Iterable[ErrorEventParam] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - ReportErrors allows clients to report batches of errors that will be sent to - error reporting systems. The structure is fully compatible with Sentry's event - payload format. - - Use this method to: - - - Report client-side errors and exceptions - - Track application crashes and panics - - Send error context and metadata for debugging - - ### Examples - - - Report a JavaScript error with Sentry-compatible structure: The service - accepts events with comprehensive error information including stack traces, - identity context, breadcrumbs, and metadata that align with Sentry's event - payload format. - - Args: - events: Error events to be reported (batch) - now using Sentry-compatible structure - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return self._post( - "/gitpod.v1.ErrorsService/ReportErrors", - body=maybe_transform({"events": events}, error_report_errors_params.ErrorReportErrorsParams), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=object, - ) - - -class AsyncErrorsResource(AsyncAPIResource): - """ - ErrorsService provides endpoints for clients to report errors - that will be sent to error reporting systems. - """ - - @cached_property - def with_raw_response(self) -> AsyncErrorsResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. - - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers - """ - return AsyncErrorsResourceWithRawResponse(self) - - @cached_property - def with_streaming_response(self) -> AsyncErrorsResourceWithStreamingResponse: - """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. - - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response - """ - return AsyncErrorsResourceWithStreamingResponse(self) - - async def report_errors( - self, - *, - events: Iterable[ErrorEventParam] | Omit = omit, - # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. - # The extra values given here take precedence over values defined on the client or passed to this method. - extra_headers: Headers | None = None, - extra_query: Query | None = None, - extra_body: Body | None = None, - timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> object: - """ - ReportErrors allows clients to report batches of errors that will be sent to - error reporting systems. The structure is fully compatible with Sentry's event - payload format. - - Use this method to: - - - Report client-side errors and exceptions - - Track application crashes and panics - - Send error context and metadata for debugging - - ### Examples - - - Report a JavaScript error with Sentry-compatible structure: The service - accepts events with comprehensive error information including stack traces, - identity context, breadcrumbs, and metadata that align with Sentry's event - payload format. - - Args: - events: Error events to be reported (batch) - now using Sentry-compatible structure - - extra_headers: Send extra headers - - extra_query: Add additional query parameters to the request - - extra_body: Add additional JSON properties to the request - - timeout: Override the client-level default timeout for this request, in seconds - """ - return await self._post( - "/gitpod.v1.ErrorsService/ReportErrors", - body=await async_maybe_transform({"events": events}, error_report_errors_params.ErrorReportErrorsParams), - options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout - ), - cast_to=object, - ) - - -class ErrorsResourceWithRawResponse: - def __init__(self, errors: ErrorsResource) -> None: - self._errors = errors - - self.report_errors = to_raw_response_wrapper( - errors.report_errors, - ) - - -class AsyncErrorsResourceWithRawResponse: - def __init__(self, errors: AsyncErrorsResource) -> None: - self._errors = errors - - self.report_errors = async_to_raw_response_wrapper( - errors.report_errors, - ) - - -class ErrorsResourceWithStreamingResponse: - def __init__(self, errors: ErrorsResource) -> None: - self._errors = errors - - self.report_errors = to_streamed_response_wrapper( - errors.report_errors, - ) - - -class AsyncErrorsResourceWithStreamingResponse: - def __init__(self, errors: AsyncErrorsResource) -> None: - self._errors = errors - - self.report_errors = async_to_streamed_response_wrapper( - errors.report_errors, - ) diff --git a/src/gitpod/resources/events.py b/src/gitpod/resources/events.py index 179eb6cb..9164e849 100644 --- a/src/gitpod/resources/events.py +++ b/src/gitpod/resources/events.py @@ -6,7 +6,7 @@ import httpx -from ..types import event_list_params, event_watch_params +from ..types import event_list_params, event_watch_params, event_retrieve_params from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from .._utils import maybe_transform, async_maybe_transform from .._compat import cached_property @@ -23,6 +23,7 @@ from ..types.shared_params.sort import Sort from ..types.event_list_response import EventListResponse from ..types.event_watch_response import EventWatchResponse +from ..types.event_retrieve_response import EventRetrieveResponse __all__ = ["EventsResource", "AsyncEventsResource"] @@ -47,6 +48,53 @@ def with_streaming_response(self) -> EventsResourceWithStreamingResponse: """ return EventsResourceWithStreamingResponse(self) + def retrieve( + self, + *, + audit_log_entry_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> EventRetrieveResponse: + """ + Gets one audit-log entry, including any typed details stored for it. + + Use this method to: + + - Inspect the details of a specific audit-log entry + - Retrieve the evidence associated with a Veto Exec audit event + + ### Examples + + - Get an audit-log entry: + + ```yaml + auditLogEntryId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + audit_log_entry_id: audit_log_entry_id is the ID of the audit-log entry to retrieve. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.EventService/GetAuditLog", + body=maybe_transform({"audit_log_entry_id": audit_log_entry_id}, event_retrieve_params.EventRetrieveParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventRetrieveResponse, + ) + def list( self, *, @@ -234,6 +282,55 @@ def with_streaming_response(self) -> AsyncEventsResourceWithStreamingResponse: """ return AsyncEventsResourceWithStreamingResponse(self) + async def retrieve( + self, + *, + audit_log_entry_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> EventRetrieveResponse: + """ + Gets one audit-log entry, including any typed details stored for it. + + Use this method to: + + - Inspect the details of a specific audit-log entry + - Retrieve the evidence associated with a Veto Exec audit event + + ### Examples + + - Get an audit-log entry: + + ```yaml + auditLogEntryId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + audit_log_entry_id: audit_log_entry_id is the ID of the audit-log entry to retrieve. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.EventService/GetAuditLog", + body=await async_maybe_transform( + {"audit_log_entry_id": audit_log_entry_id}, event_retrieve_params.EventRetrieveParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=EventRetrieveResponse, + ) + def list( self, *, @@ -405,6 +502,9 @@ class EventsResourceWithRawResponse: def __init__(self, events: EventsResource) -> None: self._events = events + self.retrieve = to_raw_response_wrapper( + events.retrieve, + ) self.list = to_raw_response_wrapper( events.list, ) @@ -417,6 +517,9 @@ class AsyncEventsResourceWithRawResponse: def __init__(self, events: AsyncEventsResource) -> None: self._events = events + self.retrieve = async_to_raw_response_wrapper( + events.retrieve, + ) self.list = async_to_raw_response_wrapper( events.list, ) @@ -429,6 +532,9 @@ class EventsResourceWithStreamingResponse: def __init__(self, events: EventsResource) -> None: self._events = events + self.retrieve = to_streamed_response_wrapper( + events.retrieve, + ) self.list = to_streamed_response_wrapper( events.list, ) @@ -441,6 +547,9 @@ class AsyncEventsResourceWithStreamingResponse: def __init__(self, events: AsyncEventsResource) -> None: self._events = events + self.retrieve = async_to_streamed_response_wrapper( + events.retrieve, + ) self.list = async_to_streamed_response_wrapper( events.list, ) diff --git a/src/gitpod/resources/organizations/policies.py b/src/gitpod/resources/organizations/policies.py index a9d30bfb..35f8ca23 100644 --- a/src/gitpod/resources/organizations/policies.py +++ b/src/gitpod/resources/organizations/policies.py @@ -6,6 +6,7 @@ import httpx +from ...types import AdmissionLevel from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given from ..._utils import maybe_transform, async_maybe_transform from ..._compat import cached_property @@ -18,6 +19,7 @@ ) from ..._base_client import make_request_options from ...types.organizations import policy_update_params, policy_retrieve_params +from ...types.admission_level import AdmissionLevel from ...types.organizations.veto_exec_policy_param import VetoExecPolicyParam from ...types.organizations.policy_retrieve_response import PolicyRetrieveResponse @@ -104,18 +106,22 @@ def update( default_editor_id: Optional[str] | Omit = omit, default_environment_image: Optional[str] | Omit = omit, delete_archived_environments_after: Optional[str] | Omit = omit, + disable_from_scratch: Optional[bool] | Omit = omit, editor_version_restrictions: Dict[str, policy_update_params.EditorVersionRestrictions] | Omit = omit, maximum_environment_lifetime: Optional[str] | Omit = omit, maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, maximum_running_environments_per_user: Optional[str] | Omit = omit, + max_port_admission_level: Optional[AdmissionLevel] | Omit = omit, members_create_projects: Optional[bool] | Omit = omit, members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, require_custom_domain_access: Optional[bool] | Omit = omit, restrict_account_creation_to_scim: Optional[bool] | Omit = omit, security_agent_policy: Optional[policy_update_params.SecurityAgentPolicy] | Omit = omit, + security_policy_id: Optional[str] | Omit = omit, veto_exec_policy: Optional[VetoExecPolicyParam] | Omit = omit, + web_browser_disabled: Optional[bool] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -179,6 +185,9 @@ def update( kept before automatic deletion. 0 means no automatic deletion. Maximum duration is 4 weeks (2419200 seconds). + disable_from_scratch: disable_from_scratch controls whether non-admin users can create blank + environments without a Git or URL initializer. + editor_version_restrictions: editor_version_restrictions restricts which editor versions can be used. Maps editor ID to version policy with allowed major versions. @@ -201,6 +210,11 @@ def update( maximum_running_environments_per_user: maximum_running_environments_per_user limits simultaneously running environments per user + max_port_admission_level: max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + members_create_projects: members_create_projects controls whether members can create projects members_require_projects: members_require_projects controls whether environments can only be created from @@ -219,8 +233,17 @@ def update( security_agent_policy: security_agent_policy contains security agent configuration updates + security_policy_id: security_policy_id assigns a Veto Exec SecurityPolicy to newly created + environments. The public GA contract accepts policies that use only + SecurityPolicy.Spec.executables. Assignment validates materializability and + rejects unsupported executable selectors or effects. Set this field to an empty + string to clear the default assignment. + veto_exec_policy: veto_exec_policy contains the veto exec policy for environments. + web_browser_disabled: web_browser_disabled controls whether users can open the built-in web browser + from environment pages. This does not affect VS Code Browser. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -240,18 +263,22 @@ def update( "default_editor_id": default_editor_id, "default_environment_image": default_environment_image, "delete_archived_environments_after": delete_archived_environments_after, + "disable_from_scratch": disable_from_scratch, "editor_version_restrictions": editor_version_restrictions, "maximum_environment_lifetime": maximum_environment_lifetime, "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, "maximum_running_environments_per_user": maximum_running_environments_per_user, + "max_port_admission_level": max_port_admission_level, "members_create_projects": members_create_projects, "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, "require_custom_domain_access": require_custom_domain_access, "restrict_account_creation_to_scim": restrict_account_creation_to_scim, "security_agent_policy": security_agent_policy, + "security_policy_id": security_policy_id, "veto_exec_policy": veto_exec_policy, + "web_browser_disabled": web_browser_disabled, }, policy_update_params.PolicyUpdateParams, ), @@ -344,18 +371,22 @@ async def update( default_editor_id: Optional[str] | Omit = omit, default_environment_image: Optional[str] | Omit = omit, delete_archived_environments_after: Optional[str] | Omit = omit, + disable_from_scratch: Optional[bool] | Omit = omit, editor_version_restrictions: Dict[str, policy_update_params.EditorVersionRestrictions] | Omit = omit, maximum_environment_lifetime: Optional[str] | Omit = omit, maximum_environments_per_user: Optional[str] | Omit = omit, maximum_environment_timeout: Optional[str] | Omit = omit, maximum_running_environments_per_user: Optional[str] | Omit = omit, + max_port_admission_level: Optional[AdmissionLevel] | Omit = omit, members_create_projects: Optional[bool] | Omit = omit, members_require_projects: Optional[bool] | Omit = omit, port_sharing_disabled: Optional[bool] | Omit = omit, require_custom_domain_access: Optional[bool] | Omit = omit, restrict_account_creation_to_scim: Optional[bool] | Omit = omit, security_agent_policy: Optional[policy_update_params.SecurityAgentPolicy] | Omit = omit, + security_policy_id: Optional[str] | Omit = omit, veto_exec_policy: Optional[VetoExecPolicyParam] | Omit = omit, + web_browser_disabled: Optional[bool] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -419,6 +450,9 @@ async def update( kept before automatic deletion. 0 means no automatic deletion. Maximum duration is 4 weeks (2419200 seconds). + disable_from_scratch: disable_from_scratch controls whether non-admin users can create blank + environments without a Git or URL initializer. + editor_version_restrictions: editor_version_restrictions restricts which editor versions can be used. Maps editor ID to version policy with allowed major versions. @@ -441,6 +475,11 @@ async def update( maximum_running_environments_per_user: maximum_running_environments_per_user limits simultaneously running environments per user + max_port_admission_level: max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + members_create_projects: members_create_projects controls whether members can create projects members_require_projects: members_require_projects controls whether environments can only be created from @@ -459,8 +498,17 @@ async def update( security_agent_policy: security_agent_policy contains security agent configuration updates + security_policy_id: security_policy_id assigns a Veto Exec SecurityPolicy to newly created + environments. The public GA contract accepts policies that use only + SecurityPolicy.Spec.executables. Assignment validates materializability and + rejects unsupported executable selectors or effects. Set this field to an empty + string to clear the default assignment. + veto_exec_policy: veto_exec_policy contains the veto exec policy for environments. + web_browser_disabled: web_browser_disabled controls whether users can open the built-in web browser + from environment pages. This does not affect VS Code Browser. + extra_headers: Send extra headers extra_query: Add additional query parameters to the request @@ -480,18 +528,22 @@ async def update( "default_editor_id": default_editor_id, "default_environment_image": default_environment_image, "delete_archived_environments_after": delete_archived_environments_after, + "disable_from_scratch": disable_from_scratch, "editor_version_restrictions": editor_version_restrictions, "maximum_environment_lifetime": maximum_environment_lifetime, "maximum_environments_per_user": maximum_environments_per_user, "maximum_environment_timeout": maximum_environment_timeout, "maximum_running_environments_per_user": maximum_running_environments_per_user, + "max_port_admission_level": max_port_admission_level, "members_create_projects": members_create_projects, "members_require_projects": members_require_projects, "port_sharing_disabled": port_sharing_disabled, "require_custom_domain_access": require_custom_domain_access, "restrict_account_creation_to_scim": restrict_account_creation_to_scim, "security_agent_policy": security_agent_policy, + "security_policy_id": security_policy_id, "veto_exec_policy": veto_exec_policy, + "web_browser_disabled": web_browser_disabled, }, policy_update_params.PolicyUpdateParams, ), diff --git a/src/gitpod/resources/organizations/scim_configurations.py b/src/gitpod/resources/organizations/scim_configurations.py index 6176c402..4cfd9f5e 100644 --- a/src/gitpod/resources/organizations/scim_configurations.py +++ b/src/gitpod/resources/organizations/scim_configurations.py @@ -60,6 +60,7 @@ def create( *, organization_id: str, sso_configuration_id: str, + allow_unverified_email_account_linking: Optional[bool] | Omit = omit, name: Optional[str] | Omit = omit, token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -107,6 +108,10 @@ def create( sso_configuration_id: sso_configuration_id is the SSO configuration to link (required for user provisioning) + allow_unverified_email_account_linking: allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + name: name is a human-readable name for the SCIM configuration token_expires_in: token_expires_in is the duration until the token expires. Defaults to 1 year. @@ -126,6 +131,7 @@ def create( { "organization_id": organization_id, "sso_configuration_id": sso_configuration_id, + "allow_unverified_email_account_linking": allow_unverified_email_account_linking, "name": name, "token_expires_in": token_expires_in, }, @@ -194,6 +200,7 @@ def update( self, *, scim_configuration_id: str, + allow_unverified_email_account_linking: Optional[bool] | Omit = omit, enabled: Optional[bool] | Omit = omit, name: Optional[str] | Omit = omit, sso_configuration_id: Optional[str] | Omit = omit, @@ -236,6 +243,10 @@ def update( Args: scim_configuration_id: scim_configuration_id is the ID of the SCIM configuration to update + allow_unverified_email_account_linking: allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + enabled: enabled controls whether SCIM provisioning is active name: name is a human-readable name for the SCIM configuration @@ -255,6 +266,7 @@ def update( body=maybe_transform( { "scim_configuration_id": scim_configuration_id, + "allow_unverified_email_account_linking": allow_unverified_email_account_linking, "enabled": enabled, "name": name, "sso_configuration_id": sso_configuration_id, @@ -482,6 +494,7 @@ async def create( *, organization_id: str, sso_configuration_id: str, + allow_unverified_email_account_linking: Optional[bool] | Omit = omit, name: Optional[str] | Omit = omit, token_expires_in: Optional[str] | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -529,6 +542,10 @@ async def create( sso_configuration_id: sso_configuration_id is the SSO configuration to link (required for user provisioning) + allow_unverified_email_account_linking: allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + name: name is a human-readable name for the SCIM configuration token_expires_in: token_expires_in is the duration until the token expires. Defaults to 1 year. @@ -548,6 +565,7 @@ async def create( { "organization_id": organization_id, "sso_configuration_id": sso_configuration_id, + "allow_unverified_email_account_linking": allow_unverified_email_account_linking, "name": name, "token_expires_in": token_expires_in, }, @@ -616,6 +634,7 @@ async def update( self, *, scim_configuration_id: str, + allow_unverified_email_account_linking: Optional[bool] | Omit = omit, enabled: Optional[bool] | Omit = omit, name: Optional[str] | Omit = omit, sso_configuration_id: Optional[str] | Omit = omit, @@ -658,6 +677,10 @@ async def update( Args: scim_configuration_id: scim_configuration_id is the ID of the SCIM configuration to update + allow_unverified_email_account_linking: allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + enabled: enabled controls whether SCIM provisioning is active name: name is a human-readable name for the SCIM configuration @@ -677,6 +700,7 @@ async def update( body=await async_maybe_transform( { "scim_configuration_id": scim_configuration_id, + "allow_unverified_email_account_linking": allow_unverified_email_account_linking, "enabled": enabled, "name": name, "sso_configuration_id": sso_configuration_id, diff --git a/src/gitpod/resources/runners/runners.py b/src/gitpod/resources/runners/runners.py index 5a0ee2e4..6b2bd4ce 100644 --- a/src/gitpod/resources/runners/runners.py +++ b/src/gitpod/resources/runners/runners.py @@ -41,7 +41,7 @@ async_to_raw_response_wrapper, async_to_streamed_response_wrapper, ) -from ...pagination import SyncRunnersPage, AsyncRunnersPage +from ...pagination import SyncRunnersPage, AsyncRunnersPage, SyncOrganizationsPage, AsyncOrganizationsPage from ..._base_client import AsyncPaginator, make_request_options from ...types.runner import Runner from ...types.runner_kind import RunnerKind @@ -126,12 +126,12 @@ def create( ### Examples - - Create cloud runner: + - Create an AWS runner: Creates a new runner in AWS EC2. ```yaml - name: "Production Runner" + name: "AWS Runner" provider: RUNNER_PROVIDER_AWS_EC2 spec: desiredPhase: RUNNER_PHASE_ACTIVE @@ -141,9 +141,25 @@ def create( autoUpdate: true ``` - - Create local runner: + - Create a GCP runner: - Creates a new local runner on Linux. + Creates a new runner on Google Cloud Platform. + + ```yaml + name: "GCP Runner" + provider: RUNNER_PROVIDER_GCP + spec: + desiredPhase: RUNNER_PHASE_ACTIVE + configuration: + region: "us-central1" + releaseChannel: RUNNER_RELEASE_CHANNEL_STABLE + autoUpdate: true + ``` + + - Create local runner (deprecated): + + Creates a new local runner on Linux. Local runners are deprecated; use + RUNNER_PROVIDER_AWS_EC2 or RUNNER_PROVIDER_GCP instead. ```yaml name: "Local Development Runner" @@ -681,6 +697,8 @@ def list_scm_organizations( *, token: str | Omit = omit, page_size: int | Omit = omit, + pagination: runner_list_scm_organizations_params.Pagination | Omit = omit, + query: str | Omit = omit, runner_id: str | Omit = omit, scm_host: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -689,7 +707,7 @@ def list_scm_organizations( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RunnerListScmOrganizationsResponse: + ) -> SyncOrganizationsPage[RunnerListScmOrganizationsResponse]: """ Lists SCM organizations the user belongs to. @@ -709,7 +727,29 @@ def list_scm_organizations( scmHost: "github.com" ``` + - Search GitLab groups: + + Returns the first page of GitLab groups matching the substring. + + ```yaml + runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + scmHost: "gitlab.com" + query: "platform" + pagination: + pageSize: 25 + ``` + Args: + pagination: Pagination parameters. When unset, defaults to the standard PaginationRequest + defaults (page_size 25, max 100). Tokens are opaque and provider-specific. + + query: Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + scm_host: The SCM host to list organizations from (e.g., "github.com", "gitlab.com") extra_headers: Send extra headers @@ -720,10 +760,13 @@ def list_scm_organizations( timeout: Override the client-level default timeout for this request, in seconds """ - return self._post( + return self._get_api_list( "/gitpod.v1.RunnerService/ListSCMOrganizations", + page=SyncOrganizationsPage[RunnerListScmOrganizationsResponse], body=maybe_transform( { + "pagination": pagination, + "query": query, "runner_id": runner_id, "scm_host": scm_host, }, @@ -742,7 +785,8 @@ def list_scm_organizations( runner_list_scm_organizations_params.RunnerListScmOrganizationsParams, ), ), - cast_to=RunnerListScmOrganizationsResponse, + model=RunnerListScmOrganizationsResponse, + method="post", ) def parse_context_url( @@ -953,12 +997,12 @@ async def create( ### Examples - - Create cloud runner: + - Create an AWS runner: Creates a new runner in AWS EC2. ```yaml - name: "Production Runner" + name: "AWS Runner" provider: RUNNER_PROVIDER_AWS_EC2 spec: desiredPhase: RUNNER_PHASE_ACTIVE @@ -968,9 +1012,25 @@ async def create( autoUpdate: true ``` - - Create local runner: + - Create a GCP runner: + + Creates a new runner on Google Cloud Platform. + + ```yaml + name: "GCP Runner" + provider: RUNNER_PROVIDER_GCP + spec: + desiredPhase: RUNNER_PHASE_ACTIVE + configuration: + region: "us-central1" + releaseChannel: RUNNER_RELEASE_CHANNEL_STABLE + autoUpdate: true + ``` + + - Create local runner (deprecated): - Creates a new local runner on Linux. + Creates a new local runner on Linux. Local runners are deprecated; use + RUNNER_PROVIDER_AWS_EC2 or RUNNER_PROVIDER_GCP instead. ```yaml name: "Local Development Runner" @@ -1505,11 +1565,13 @@ async def create_runner_token( cast_to=RunnerCreateRunnerTokenResponse, ) - async def list_scm_organizations( + def list_scm_organizations( self, *, token: str | Omit = omit, page_size: int | Omit = omit, + pagination: runner_list_scm_organizations_params.Pagination | Omit = omit, + query: str | Omit = omit, runner_id: str | Omit = omit, scm_host: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -1518,7 +1580,7 @@ async def list_scm_organizations( extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> RunnerListScmOrganizationsResponse: + ) -> AsyncPaginator[RunnerListScmOrganizationsResponse, AsyncOrganizationsPage[RunnerListScmOrganizationsResponse]]: """ Lists SCM organizations the user belongs to. @@ -1538,7 +1600,29 @@ async def list_scm_organizations( scmHost: "github.com" ``` + - Search GitLab groups: + + Returns the first page of GitLab groups matching the substring. + + ```yaml + runnerId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + scmHost: "gitlab.com" + query: "platform" + pagination: + pageSize: 25 + ``` + Args: + pagination: Pagination parameters. When unset, defaults to the standard PaginationRequest + defaults (page_size 25, max 100). Tokens are opaque and provider-specific. + + query: Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + scm_host: The SCM host to list organizations from (e.g., "github.com", "gitlab.com") extra_headers: Send extra headers @@ -1549,10 +1633,13 @@ async def list_scm_organizations( timeout: Override the client-level default timeout for this request, in seconds """ - return await self._post( + return self._get_api_list( "/gitpod.v1.RunnerService/ListSCMOrganizations", - body=await async_maybe_transform( + page=AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], + body=maybe_transform( { + "pagination": pagination, + "query": query, "runner_id": runner_id, "scm_host": scm_host, }, @@ -1563,7 +1650,7 @@ async def list_scm_organizations( extra_query=extra_query, extra_body=extra_body, timeout=timeout, - query=await async_maybe_transform( + query=maybe_transform( { "token": token, "page_size": page_size, @@ -1571,7 +1658,8 @@ async def list_scm_organizations( runner_list_scm_organizations_params.RunnerListScmOrganizationsParams, ), ), - cast_to=RunnerListScmOrganizationsResponse, + model=RunnerListScmOrganizationsResponse, + method="post", ) async def parse_context_url( diff --git a/src/gitpod/resources/secrets.py b/src/gitpod/resources/secrets.py index 915a0c79..4d3f6150 100644 --- a/src/gitpod/resources/secrets.py +++ b/src/gitpod/resources/secrets.py @@ -56,11 +56,13 @@ def create( *, api_only: bool | Omit = omit, container_registry_basic_auth_host: str | Omit = omit, + credential_proxy: secret_create_params.CredentialProxy | Omit = omit, environment_variable: bool | Omit = omit, file_path: str | Omit = omit, name: str | Omit = omit, project_id: str | Omit = omit, scope: SecretScopeParam | Omit = omit, + source: secret_create_params.Source | Omit = omit, value: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -122,6 +124,13 @@ def create( container_registry_basic_auth_host: secret will be mounted as a docker config in the environment VM, mount will have the docker registry host + credential_proxy: credential_proxy configures transparent credential injection when environments + materialize this secret. When set, the credential proxy intercepts HTTPS traffic + to the target hosts and replaces the dummy mounted value with the real value in + the specified HTTP header. The real secret value is never exposed in the + environment. This field is orthogonal to mount — a secret can be both mounted + and proxied at the same time. + environment_variable: secret will be created as an Environment Variable with the same name as the secret @@ -136,7 +145,10 @@ def create( scope: scope is the scope of the secret - value: value is the plaintext value of the secret + source: source is the source of the secret, possibly verbatim value + + value: value is the plaintext value of the secret. When set, source must be unset or + verbatim. extra_headers: Send extra headers @@ -152,11 +164,13 @@ def create( { "api_only": api_only, "container_registry_basic_auth_host": container_registry_basic_auth_host, + "credential_proxy": credential_proxy, "environment_variable": environment_variable, "file_path": file_path, "name": name, "project_id": project_id, "scope": scope, + "source": source, "value": value, }, secret_create_params.SecretCreateParams, @@ -432,11 +446,13 @@ async def create( *, api_only: bool | Omit = omit, container_registry_basic_auth_host: str | Omit = omit, + credential_proxy: secret_create_params.CredentialProxy | Omit = omit, environment_variable: bool | Omit = omit, file_path: str | Omit = omit, name: str | Omit = omit, project_id: str | Omit = omit, scope: SecretScopeParam | Omit = omit, + source: secret_create_params.Source | Omit = omit, value: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -498,6 +514,13 @@ async def create( container_registry_basic_auth_host: secret will be mounted as a docker config in the environment VM, mount will have the docker registry host + credential_proxy: credential_proxy configures transparent credential injection when environments + materialize this secret. When set, the credential proxy intercepts HTTPS traffic + to the target hosts and replaces the dummy mounted value with the real value in + the specified HTTP header. The real secret value is never exposed in the + environment. This field is orthogonal to mount — a secret can be both mounted + and proxied at the same time. + environment_variable: secret will be created as an Environment Variable with the same name as the secret @@ -512,7 +535,10 @@ async def create( scope: scope is the scope of the secret - value: value is the plaintext value of the secret + source: source is the source of the secret, possibly verbatim value + + value: value is the plaintext value of the secret. When set, source must be unset or + verbatim. extra_headers: Send extra headers @@ -528,11 +554,13 @@ async def create( { "api_only": api_only, "container_registry_basic_auth_host": container_registry_basic_auth_host, + "credential_proxy": credential_proxy, "environment_variable": environment_variable, "file_path": file_path, "name": name, "project_id": project_id, "scope": scope, + "source": source, "value": value, }, secret_create_params.SecretCreateParams, diff --git a/src/gitpod/resources/security_policies.py b/src/gitpod/resources/security_policies.py new file mode 100644 index 00000000..0c9a23b9 --- /dev/null +++ b/src/gitpod/resources/security_policies.py @@ -0,0 +1,779 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import httpx + +from ..types import ( + security_policy_list_params, + security_policy_create_params, + security_policy_delete_params, + security_policy_update_params, + security_policy_retrieve_params, +) +from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given +from .._utils import maybe_transform, async_maybe_transform +from .._compat import cached_property +from .._resource import SyncAPIResource, AsyncAPIResource +from .._response import ( + to_raw_response_wrapper, + to_streamed_response_wrapper, + async_to_raw_response_wrapper, + async_to_streamed_response_wrapper, +) +from ..pagination import SyncSecurityPoliciesPage, AsyncSecurityPoliciesPage +from .._base_client import AsyncPaginator, make_request_options +from ..types.security_policy import SecurityPolicy +from ..types.security_policy_create_response import SecurityPolicyCreateResponse +from ..types.security_policy_update_response import SecurityPolicyUpdateResponse +from ..types.security_policy_retrieve_response import SecurityPolicyRetrieveResponse + +__all__ = ["SecurityPoliciesResource", "AsyncSecurityPoliciesResource"] + + +class SecurityPoliciesResource(SyncAPIResource): + @cached_property + def with_raw_response(self) -> SecurityPoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return SecurityPoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> SecurityPoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return SecurityPoliciesResourceWithStreamingResponse(self) + + def create( + self, + *, + metadata: security_policy_create_params.Metadata, + spec: security_policy_create_params.Spec, + organization_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyCreateResponse: + """ + Creates a new security policy. + + Use this method to: + + - Define environment access controls + - Configure audited or blocked operations + - Manage organization security posture + + ### Examples + + - Create security policy: + + Creates an audit-first Veto Exec policy with one audited bare name and one + blocked absolute path. Creation stores an inactive definition; assigning it as + the organization default validates materializability. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + metadata: + name: "Veto Exec audit-first" + spec: + executables: + defaultEffect: EFFECT_ALLOW + rules: + - path: "npx" + effect: EFFECT_AUDIT + - path: "/usr/bin/curl" + effect: EFFECT_BLOCK + ``` + + Args: + spec: Mandate/deploy security agents, e.g. CrowdStrike. Mandate credential + security/proxy use. These can be modeled later as explicit fields if needed. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.SecurityService/CreateSecurityPolicy", + body=maybe_transform( + { + "metadata": metadata, + "spec": spec, + "organization_id": organization_id, + }, + security_policy_create_params.SecurityPolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyCreateResponse, + ) + + def retrieve( + self, + *, + security_policy_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyRetrieveResponse: + """ + Gets details about a specific security policy. + + Use this method to: + + - View security policy configuration + - Inspect enforcement rules + + ### Examples + + - Get security policy: + + Retrieves a security policy by ID. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.SecurityService/GetSecurityPolicy", + body=maybe_transform( + {"security_policy_id": security_policy_id}, security_policy_retrieve_params.SecurityPolicyRetrieveParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyRetrieveResponse, + ) + + def update( + self, + *, + metadata: security_policy_update_params.Metadata | Omit = omit, + security_policy_id: str | Omit = omit, + spec: security_policy_update_params.Spec | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyUpdateResponse: + """ + Updates a security policy. + + Use this method to: + + - Rename a security policy + - Change enforcement rules + - Update auditing behavior + + ### Examples + + - Update security policy: + + Promotes one executable rule from audit to block while leaving unmatched + executables allowed. Updating an assigned policy validates materializability; + updating an unassigned policy only stores its spec. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + spec: + executables: + defaultEffect: EFFECT_ALLOW + rules: + - path: "npx" + effect: EFFECT_BLOCK + - path: "/usr/bin/curl" + effect: EFFECT_BLOCK + ``` + + Args: + spec: Mandate/deploy security agents, e.g. CrowdStrike. Mandate credential + security/proxy use. These can be modeled later as explicit fields if needed. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.SecurityService/UpdateSecurityPolicy", + body=maybe_transform( + { + "metadata": metadata, + "security_policy_id": security_policy_id, + "spec": spec, + }, + security_policy_update_params.SecurityPolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyUpdateResponse, + ) + + def list( + self, + *, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: security_policy_list_params.Filter | Omit = omit, + pagination: security_policy_list_params.Pagination | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncSecurityPoliciesPage[SecurityPolicy]: + """ + Lists security policies. + + Use this method to: + + - View all security policies in an organization + - Audit configured security controls + + ### Examples + + - List organization policies: + + Shows security policies with pagination. + + ```yaml + filter: + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + pagination: + pageSize: 20 + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.SecurityService/ListSecurityPolicies", + page=SyncSecurityPoliciesPage[SecurityPolicy], + body=maybe_transform( + { + "filter": filter, + "pagination": pagination, + }, + security_policy_list_params.SecurityPolicyListParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + security_policy_list_params.SecurityPolicyListParams, + ), + ), + model=SecurityPolicy, + method="post", + ) + + def delete( + self, + *, + security_policy_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Deletes a security policy. + + Use this method to: + + - Remove obsolete security policies + - Clean up unused policy definitions + + ### Examples + + - Delete security policy: + + Permanently removes a security policy. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.SecurityService/DeleteSecurityPolicy", + body=maybe_transform( + {"security_policy_id": security_policy_id}, security_policy_delete_params.SecurityPolicyDeleteParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class AsyncSecurityPoliciesResource(AsyncAPIResource): + @cached_property + def with_raw_response(self) -> AsyncSecurityPoliciesResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncSecurityPoliciesResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncSecurityPoliciesResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return AsyncSecurityPoliciesResourceWithStreamingResponse(self) + + async def create( + self, + *, + metadata: security_policy_create_params.Metadata, + spec: security_policy_create_params.Spec, + organization_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyCreateResponse: + """ + Creates a new security policy. + + Use this method to: + + - Define environment access controls + - Configure audited or blocked operations + - Manage organization security posture + + ### Examples + + - Create security policy: + + Creates an audit-first Veto Exec policy with one audited bare name and one + blocked absolute path. Creation stores an inactive definition; assigning it as + the organization default validates materializability. + + ```yaml + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + metadata: + name: "Veto Exec audit-first" + spec: + executables: + defaultEffect: EFFECT_ALLOW + rules: + - path: "npx" + effect: EFFECT_AUDIT + - path: "/usr/bin/curl" + effect: EFFECT_BLOCK + ``` + + Args: + spec: Mandate/deploy security agents, e.g. CrowdStrike. Mandate credential + security/proxy use. These can be modeled later as explicit fields if needed. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.SecurityService/CreateSecurityPolicy", + body=await async_maybe_transform( + { + "metadata": metadata, + "spec": spec, + "organization_id": organization_id, + }, + security_policy_create_params.SecurityPolicyCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyCreateResponse, + ) + + async def retrieve( + self, + *, + security_policy_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyRetrieveResponse: + """ + Gets details about a specific security policy. + + Use this method to: + + - View security policy configuration + - Inspect enforcement rules + + ### Examples + + - Get security policy: + + Retrieves a security policy by ID. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.SecurityService/GetSecurityPolicy", + body=await async_maybe_transform( + {"security_policy_id": security_policy_id}, security_policy_retrieve_params.SecurityPolicyRetrieveParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyRetrieveResponse, + ) + + async def update( + self, + *, + metadata: security_policy_update_params.Metadata | Omit = omit, + security_policy_id: str | Omit = omit, + spec: security_policy_update_params.Spec | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SecurityPolicyUpdateResponse: + """ + Updates a security policy. + + Use this method to: + + - Rename a security policy + - Change enforcement rules + - Update auditing behavior + + ### Examples + + - Update security policy: + + Promotes one executable rule from audit to block while leaving unmatched + executables allowed. Updating an assigned policy validates materializability; + updating an unassigned policy only stores its spec. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + spec: + executables: + defaultEffect: EFFECT_ALLOW + rules: + - path: "npx" + effect: EFFECT_BLOCK + - path: "/usr/bin/curl" + effect: EFFECT_BLOCK + ``` + + Args: + spec: Mandate/deploy security agents, e.g. CrowdStrike. Mandate credential + security/proxy use. These can be modeled later as explicit fields if needed. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.SecurityService/UpdateSecurityPolicy", + body=await async_maybe_transform( + { + "metadata": metadata, + "security_policy_id": security_policy_id, + "spec": spec, + }, + security_policy_update_params.SecurityPolicyUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=SecurityPolicyUpdateResponse, + ) + + def list( + self, + *, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: security_policy_list_params.Filter | Omit = omit, + pagination: security_policy_list_params.Pagination | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> AsyncPaginator[SecurityPolicy, AsyncSecurityPoliciesPage[SecurityPolicy]]: + """ + Lists security policies. + + Use this method to: + + - View all security policies in an organization + - Audit configured security controls + + ### Examples + + - List organization policies: + + Shows security policies with pagination. + + ```yaml + filter: + organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047" + pagination: + pageSize: 20 + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.SecurityService/ListSecurityPolicies", + page=AsyncSecurityPoliciesPage[SecurityPolicy], + body=maybe_transform( + { + "filter": filter, + "pagination": pagination, + }, + security_policy_list_params.SecurityPolicyListParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + security_policy_list_params.SecurityPolicyListParams, + ), + ), + model=SecurityPolicy, + method="post", + ) + + async def delete( + self, + *, + security_policy_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> object: + """ + Deletes a security policy. + + Use this method to: + + - Remove obsolete security policies + - Clean up unused policy definitions + + ### Examples + + - Delete security policy: + + Permanently removes a security policy. + + ```yaml + securityPolicyId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.SecurityService/DeleteSecurityPolicy", + body=await async_maybe_transform( + {"security_policy_id": security_policy_id}, security_policy_delete_params.SecurityPolicyDeleteParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=object, + ) + + +class SecurityPoliciesResourceWithRawResponse: + def __init__(self, security_policies: SecurityPoliciesResource) -> None: + self._security_policies = security_policies + + self.create = to_raw_response_wrapper( + security_policies.create, + ) + self.retrieve = to_raw_response_wrapper( + security_policies.retrieve, + ) + self.update = to_raw_response_wrapper( + security_policies.update, + ) + self.list = to_raw_response_wrapper( + security_policies.list, + ) + self.delete = to_raw_response_wrapper( + security_policies.delete, + ) + + +class AsyncSecurityPoliciesResourceWithRawResponse: + def __init__(self, security_policies: AsyncSecurityPoliciesResource) -> None: + self._security_policies = security_policies + + self.create = async_to_raw_response_wrapper( + security_policies.create, + ) + self.retrieve = async_to_raw_response_wrapper( + security_policies.retrieve, + ) + self.update = async_to_raw_response_wrapper( + security_policies.update, + ) + self.list = async_to_raw_response_wrapper( + security_policies.list, + ) + self.delete = async_to_raw_response_wrapper( + security_policies.delete, + ) + + +class SecurityPoliciesResourceWithStreamingResponse: + def __init__(self, security_policies: SecurityPoliciesResource) -> None: + self._security_policies = security_policies + + self.create = to_streamed_response_wrapper( + security_policies.create, + ) + self.retrieve = to_streamed_response_wrapper( + security_policies.retrieve, + ) + self.update = to_streamed_response_wrapper( + security_policies.update, + ) + self.list = to_streamed_response_wrapper( + security_policies.list, + ) + self.delete = to_streamed_response_wrapper( + security_policies.delete, + ) + + +class AsyncSecurityPoliciesResourceWithStreamingResponse: + def __init__(self, security_policies: AsyncSecurityPoliciesResource) -> None: + self._security_policies = security_policies + + self.create = async_to_streamed_response_wrapper( + security_policies.create, + ) + self.retrieve = async_to_streamed_response_wrapper( + security_policies.retrieve, + ) + self.update = async_to_streamed_response_wrapper( + security_policies.update, + ) + self.list = async_to_streamed_response_wrapper( + security_policies.list, + ) + self.delete = async_to_streamed_response_wrapper( + security_policies.delete, + ) diff --git a/src/gitpod/resources/usage.py b/src/gitpod/resources/usage.py index 6285e304..7cda91dc 100644 --- a/src/gitpod/resources/usage.py +++ b/src/gitpod/resources/usage.py @@ -4,9 +4,19 @@ import httpx -from ..types import usage_list_environment_runtime_records_params +from ..types import ( + Resolution, + usage_get_pr_summary_params, + usage_get_pr_time_series_params, + usage_get_co_author_summary_params, + usage_get_agent_trace_summary_params, + usage_get_co_author_time_series_params, + usage_get_adoption_usage_summary_params, + usage_get_agent_trace_time_series_params, + usage_list_environment_runtime_records_params, +) from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given -from .._utils import maybe_transform +from .._utils import maybe_transform, async_maybe_transform from .._compat import cached_property from .._resource import SyncAPIResource, AsyncAPIResource from .._response import ( @@ -17,78 +27,894 @@ ) from ..pagination import SyncRecordsPage, AsyncRecordsPage from .._base_client import AsyncPaginator, make_request_options +from ..types.resolution import Resolution from ..types.environment_usage_record import EnvironmentUsageRecord +from ..types.shared_params.date_range import DateRange +from ..types.usage_get_pr_summary_response import UsageGetPrSummaryResponse +from ..types.usage_get_pr_time_series_response import UsageGetPrTimeSeriesResponse +from ..types.usage_get_co_author_summary_response import UsageGetCoAuthorSummaryResponse +from ..types.usage_get_agent_trace_summary_response import UsageGetAgentTraceSummaryResponse +from ..types.usage_get_co_author_time_series_response import UsageGetCoAuthorTimeSeriesResponse +from ..types.usage_get_adoption_usage_summary_response import UsageGetAdoptionUsageSummaryResponse +from ..types.usage_get_agent_trace_time_series_response import UsageGetAgentTraceTimeSeriesResponse + +__all__ = ["UsageResource", "AsyncUsageResource"] + + +class UsageResource(SyncAPIResource): + """ + UsageService provides usage information about environments, users, and projects. + """ + + @cached_property + def with_raw_response(self) -> UsageResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return UsageResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> UsageResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return UsageResourceWithStreamingResponse(self) + + def get_adoption_usage_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAdoptionUsageSummaryResponse: + """ + Gets a summary of adoption and usage metrics. + + Returns all scalar values, trends, and a sparkline for the Adoption & Usage + insight category. For full-resolution time series, use the individual time + series RPCs. + + Use this method to: + + - Build adoption and usage insight cards + - Filter adoption metrics by project, user, or team + - Compare the requested date range against the previous period + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query metrics within. + + project_id: Optional project ID to filter metrics by. + + team_id: Optional team ID to scope results to members of a specific team. + + user_id: Optional user ID to filter metrics for a specific user (personal insights view). + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetAdoptionUsageSummary", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_adoption_usage_summary_params.UsageGetAdoptionUsageSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAdoptionUsageSummaryResponse, + ) + + def get_agent_trace_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAgentTraceSummaryResponse: + """ + Gets aggregated agent trace summary for the organization or a specific project. + + Use this method to: + + - Measure agent sessions and line changes + - Break down agent activity by model + - Scope agent trace insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetAgentTraceSummary", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_agent_trace_summary_params.UsageGetAgentTraceSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAgentTraceSummaryResponse, + ) + + def get_agent_trace_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAgentTraceTimeSeriesResponse: + """ + Gets agent trace data as a time series. + + Use this method to: + + - Chart agent sessions and line changes over time + - Select hourly, daily, weekly, or monthly buckets + - Scope agent trace insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetAgentTraceTimeSeries", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_agent_trace_time_series_params.UsageGetAgentTraceTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAgentTraceTimeSeriesResponse, + ) + + def get_co_author_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetCoAuthorSummaryResponse: + """ + Gets aggregated co-author summary for the organization or a specific project. + + Use this method to: + + - Measure AI-assisted commits and line changes + - Scope co-author insights to a project, user, or team + - Compare the requested date range against the previous period + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetCoAuthorSummary", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_co_author_summary_params.UsageGetCoAuthorSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetCoAuthorSummaryResponse, + ) + + def get_co_author_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetCoAuthorTimeSeriesResponse: + """ + Gets co-author contribution data as a time series. + + Use this method to: + + - Chart AI-assisted commits and line changes over time + - Select hourly, daily, weekly, or monthly buckets + - Scope co-author insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetCoAuthorTimeSeries", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_co_author_time_series_params.UsageGetCoAuthorTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetCoAuthorTimeSeriesResponse, + ) + + def get_pr_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetPrSummaryResponse: + """ + Gets aggregated PR speed summary for the organization or a specific project. + + Use this method to: + + - Measure pull request lead time and review latency + - Calculate deployment frequency from merged pull requests + - Scope PR speed insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetPrSummary", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_pr_summary_params.UsageGetPrSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetPrSummaryResponse, + ) + + def get_pr_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetPrTimeSeriesResponse: + """ + Gets PR speed metrics as a time series. + + Use this method to: + + - Chart pull request lead time, review latency, and deploy counts + - Select hourly, daily, weekly, or monthly buckets + - Scope PR speed insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/gitpod.v1.UsageService/GetPrTimeSeries", + body=maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_pr_time_series_params.UsageGetPrTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetPrTimeSeriesResponse, + ) + + def list_environment_runtime_records( + self, + *, + token: str | Omit = omit, + page_size: int | Omit = omit, + filter: usage_list_environment_runtime_records_params.Filter | Omit = omit, + pagination: usage_list_environment_runtime_records_params.Pagination | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> SyncRecordsPage[EnvironmentUsageRecord]: + """ + Lists completed environment runtime records within a specified date range. + + Returns a list of environment runtime records that were completed within the + specified date range. Records of currently running environments are not + included. + + Use this method to: + + - View environment runtime records + - Filter by project + - Create custom usage reports + + ### Example + + ```yaml + filter: + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-01-02T00:00:00Z" + pagination: + pageSize: 100 + ``` + + Args: + filter: Filter options. + + pagination: Pagination options. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._get_api_list( + "/gitpod.v1.UsageService/ListEnvironmentUsageRecords", + page=SyncRecordsPage[EnvironmentUsageRecord], + body=maybe_transform( + { + "filter": filter, + "pagination": pagination, + }, + usage_list_environment_runtime_records_params.UsageListEnvironmentRuntimeRecordsParams, + ), + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "token": token, + "page_size": page_size, + }, + usage_list_environment_runtime_records_params.UsageListEnvironmentRuntimeRecordsParams, + ), + ), + model=EnvironmentUsageRecord, + method="post", + ) + + +class AsyncUsageResource(AsyncAPIResource): + """ + UsageService provides usage information about environments, users, and projects. + """ + + @cached_property + def with_raw_response(self) -> AsyncUsageResourceWithRawResponse: + """ + This property can be used as a prefix for any HTTP method call to return + the raw response object instead of the parsed content. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + """ + return AsyncUsageResourceWithRawResponse(self) + + @cached_property + def with_streaming_response(self) -> AsyncUsageResourceWithStreamingResponse: + """ + An alternative to `.with_raw_response` that doesn't eagerly read the response body. + + For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + """ + return AsyncUsageResourceWithStreamingResponse(self) + + async def get_adoption_usage_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAdoptionUsageSummaryResponse: + """ + Gets a summary of adoption and usage metrics. + + Returns all scalar values, trends, and a sparkline for the Adoption & Usage + insight category. For full-resolution time series, use the individual time + series RPCs. + + Use this method to: + + - Build adoption and usage insight cards + - Filter adoption metrics by project, user, or team + - Compare the requested date range against the previous period + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query metrics within. + + project_id: Optional project ID to filter metrics by. + + team_id: Optional team ID to scope results to members of a specific team. + + user_id: Optional user ID to filter metrics for a specific user (personal insights view). + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.UsageService/GetAdoptionUsageSummary", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_adoption_usage_summary_params.UsageGetAdoptionUsageSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAdoptionUsageSummaryResponse, + ) + + async def get_agent_trace_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAgentTraceSummaryResponse: + """ + Gets aggregated agent trace summary for the organization or a specific project. + + Use this method to: + + - Measure agent sessions and line changes + - Break down agent activity by model + - Scope agent trace insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. -__all__ = ["UsageResource", "AsyncUsageResource"] + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + extra_headers: Send extra headers -class UsageResource(SyncAPIResource): - """ - UsageService provides usage information about environments, users, and projects. - """ + extra_query: Add additional query parameters to the request - @cached_property - def with_raw_response(self) -> UsageResourceWithRawResponse: - """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. + extra_body: Add additional JSON properties to the request - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + timeout: Override the client-level default timeout for this request, in seconds """ - return UsageResourceWithRawResponse(self) + return await self._post( + "/gitpod.v1.UsageService/GetAgentTraceSummary", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_agent_trace_summary_params.UsageGetAgentTraceSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAgentTraceSummaryResponse, + ) - @cached_property - def with_streaming_response(self) -> UsageResourceWithStreamingResponse: + async def get_agent_trace_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetAgentTraceTimeSeriesResponse: """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. + Gets agent trace data as a time series. - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + Use this method to: + + - Chart agent sessions and line changes over time + - Select hourly, daily, weekly, or monthly buckets + - Scope agent trace insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds """ - return UsageResourceWithStreamingResponse(self) + return await self._post( + "/gitpod.v1.UsageService/GetAgentTraceTimeSeries", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_agent_trace_time_series_params.UsageGetAgentTraceTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetAgentTraceTimeSeriesResponse, + ) - def list_environment_runtime_records( + async def get_co_author_summary( self, *, - token: str | Omit = omit, - page_size: int | Omit = omit, - filter: usage_list_environment_runtime_records_params.Filter | Omit = omit, - pagination: usage_list_environment_runtime_records_params.Pagination | Omit = omit, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, extra_query: Query | None = None, extra_body: Body | None = None, timeout: float | httpx.Timeout | None | NotGiven = not_given, - ) -> SyncRecordsPage[EnvironmentUsageRecord]: + ) -> UsageGetCoAuthorSummaryResponse: """ - Lists completed environment runtime records within a specified date range. - - Returns a list of environment runtime records that were completed within the - specified date range. Records of currently running environments are not - included. + Gets aggregated co-author summary for the organization or a specific project. Use this method to: - - View environment runtime records - - Filter by project - - Create custom usage reports + - Measure AI-assisted commits and line changes + - Scope co-author insights to a project, user, or team + - Compare the requested date range against the previous period ### Example ```yaml - filter: - projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" - dateRange: - startTime: "2024-01-01T00:00:00Z" - endTime: "2024-01-02T00:00:00Z" - pagination: - pageSize: 100 + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" ``` Args: - filter: Filter options. + date_range: Date range to query within. - pagination: Pagination options. + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. extra_headers: Send extra headers @@ -98,57 +924,236 @@ def list_environment_runtime_records( timeout: Override the client-level default timeout for this request, in seconds """ - return self._get_api_list( - "/gitpod.v1.UsageService/ListEnvironmentUsageRecords", - page=SyncRecordsPage[EnvironmentUsageRecord], - body=maybe_transform( + return await self._post( + "/gitpod.v1.UsageService/GetCoAuthorSummary", + body=await async_maybe_transform( { - "filter": filter, - "pagination": pagination, + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, }, - usage_list_environment_runtime_records_params.UsageListEnvironmentRuntimeRecordsParams, + usage_get_co_author_summary_params.UsageGetCoAuthorSummaryParams, ), options=make_request_options( - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - query=maybe_transform( - { - "token": token, - "page_size": page_size, - }, - usage_list_environment_runtime_records_params.UsageListEnvironmentRuntimeRecordsParams, - ), + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ), - model=EnvironmentUsageRecord, - method="post", + cast_to=UsageGetCoAuthorSummaryResponse, ) + async def get_co_author_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetCoAuthorTimeSeriesResponse: + """ + Gets co-author contribution data as a time series. + + Use this method to: -class AsyncUsageResource(AsyncAPIResource): - """ - UsageService provides usage information about environments, users, and projects. - """ + - Chart AI-assisted commits and line changes over time + - Select hourly, daily, weekly, or monthly buckets + - Scope co-author insights to a project, user, or team - @cached_property - def with_raw_response(self) -> AsyncUsageResourceWithRawResponse: + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds """ - This property can be used as a prefix for any HTTP method call to return - the raw response object instead of the parsed content. + return await self._post( + "/gitpod.v1.UsageService/GetCoAuthorTimeSeries", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_co_author_time_series_params.UsageGetCoAuthorTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetCoAuthorTimeSeriesResponse, + ) - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#accessing-raw-response-data-eg-headers + async def get_pr_summary( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetPrSummaryResponse: """ - return AsyncUsageResourceWithRawResponse(self) + Gets aggregated PR speed summary for the organization or a specific project. - @cached_property - def with_streaming_response(self) -> AsyncUsageResourceWithStreamingResponse: + Use this method to: + + - Measure pull request lead time and review latency + - Calculate deployment frequency from merged pull requests + - Scope PR speed insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds """ - An alternative to `.with_raw_response` that doesn't eagerly read the response body. + return await self._post( + "/gitpod.v1.UsageService/GetPrSummary", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_pr_summary_params.UsageGetPrSummaryParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetPrSummaryResponse, + ) - For more information, see https://www.github.com/gitpod-io/gitpod-sdk-python#with_streaming_response + async def get_pr_time_series( + self, + *, + date_range: DateRange, + project_id: str | Omit = omit, + resolution: Resolution | Omit = omit, + team_id: str | Omit = omit, + user_id: str | Omit = omit, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> UsageGetPrTimeSeriesResponse: """ - return AsyncUsageResourceWithStreamingResponse(self) + Gets PR speed metrics as a time series. + + Use this method to: + + - Chart pull request lead time, review latency, and deploy counts + - Select hourly, daily, weekly, or monthly buckets + - Scope PR speed insights to a project, user, or team + + ### Example + + ```yaml + dateRange: + startTime: "2024-01-01T00:00:00Z" + endTime: "2024-02-01T00:00:00Z" + resolution: RESOLUTION_WEEKLY + projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68" + ``` + + Args: + date_range: Date range to query within. + + project_id: Optional project ID to scope results. + + resolution: Time resolution for the series data. + + team_id: Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + + user_id: Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/gitpod.v1.UsageService/GetPrTimeSeries", + body=await async_maybe_transform( + { + "date_range": date_range, + "project_id": project_id, + "resolution": resolution, + "team_id": team_id, + "user_id": user_id, + }, + usage_get_pr_time_series_params.UsageGetPrTimeSeriesParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=UsageGetPrTimeSeriesResponse, + ) def list_environment_runtime_records( self, @@ -234,6 +1239,27 @@ class UsageResourceWithRawResponse: def __init__(self, usage: UsageResource) -> None: self._usage = usage + self.get_adoption_usage_summary = to_raw_response_wrapper( + usage.get_adoption_usage_summary, + ) + self.get_agent_trace_summary = to_raw_response_wrapper( + usage.get_agent_trace_summary, + ) + self.get_agent_trace_time_series = to_raw_response_wrapper( + usage.get_agent_trace_time_series, + ) + self.get_co_author_summary = to_raw_response_wrapper( + usage.get_co_author_summary, + ) + self.get_co_author_time_series = to_raw_response_wrapper( + usage.get_co_author_time_series, + ) + self.get_pr_summary = to_raw_response_wrapper( + usage.get_pr_summary, + ) + self.get_pr_time_series = to_raw_response_wrapper( + usage.get_pr_time_series, + ) self.list_environment_runtime_records = to_raw_response_wrapper( usage.list_environment_runtime_records, ) @@ -243,6 +1269,27 @@ class AsyncUsageResourceWithRawResponse: def __init__(self, usage: AsyncUsageResource) -> None: self._usage = usage + self.get_adoption_usage_summary = async_to_raw_response_wrapper( + usage.get_adoption_usage_summary, + ) + self.get_agent_trace_summary = async_to_raw_response_wrapper( + usage.get_agent_trace_summary, + ) + self.get_agent_trace_time_series = async_to_raw_response_wrapper( + usage.get_agent_trace_time_series, + ) + self.get_co_author_summary = async_to_raw_response_wrapper( + usage.get_co_author_summary, + ) + self.get_co_author_time_series = async_to_raw_response_wrapper( + usage.get_co_author_time_series, + ) + self.get_pr_summary = async_to_raw_response_wrapper( + usage.get_pr_summary, + ) + self.get_pr_time_series = async_to_raw_response_wrapper( + usage.get_pr_time_series, + ) self.list_environment_runtime_records = async_to_raw_response_wrapper( usage.list_environment_runtime_records, ) @@ -252,6 +1299,27 @@ class UsageResourceWithStreamingResponse: def __init__(self, usage: UsageResource) -> None: self._usage = usage + self.get_adoption_usage_summary = to_streamed_response_wrapper( + usage.get_adoption_usage_summary, + ) + self.get_agent_trace_summary = to_streamed_response_wrapper( + usage.get_agent_trace_summary, + ) + self.get_agent_trace_time_series = to_streamed_response_wrapper( + usage.get_agent_trace_time_series, + ) + self.get_co_author_summary = to_streamed_response_wrapper( + usage.get_co_author_summary, + ) + self.get_co_author_time_series = to_streamed_response_wrapper( + usage.get_co_author_time_series, + ) + self.get_pr_summary = to_streamed_response_wrapper( + usage.get_pr_summary, + ) + self.get_pr_time_series = to_streamed_response_wrapper( + usage.get_pr_time_series, + ) self.list_environment_runtime_records = to_streamed_response_wrapper( usage.list_environment_runtime_records, ) @@ -261,6 +1329,27 @@ class AsyncUsageResourceWithStreamingResponse: def __init__(self, usage: AsyncUsageResource) -> None: self._usage = usage + self.get_adoption_usage_summary = async_to_streamed_response_wrapper( + usage.get_adoption_usage_summary, + ) + self.get_agent_trace_summary = async_to_streamed_response_wrapper( + usage.get_agent_trace_summary, + ) + self.get_agent_trace_time_series = async_to_streamed_response_wrapper( + usage.get_agent_trace_time_series, + ) + self.get_co_author_summary = async_to_streamed_response_wrapper( + usage.get_co_author_summary, + ) + self.get_co_author_time_series = async_to_streamed_response_wrapper( + usage.get_co_author_time_series, + ) + self.get_pr_summary = async_to_streamed_response_wrapper( + usage.get_pr_summary, + ) + self.get_pr_time_series = async_to_streamed_response_wrapper( + usage.get_pr_time_series, + ) self.list_environment_runtime_records = async_to_streamed_response_wrapper( usage.list_environment_runtime_records, ) diff --git a/src/gitpod/types/__init__.py b/src/gitpod/types/__init__.py index 4f9dca65..674e1c93 100644 --- a/src/gitpod/types/__init__.py +++ b/src/gitpod/types/__init__.py @@ -19,6 +19,7 @@ Gateway as Gateway, Subject as Subject, TaskSpec as TaskSpec, + DateRange as DateRange, ErrorCode as ErrorCode, Principal as Principal, SecretRef as SecretRef, @@ -28,7 +29,10 @@ ResourceRole as ResourceRole, ResourceType as ResourceType, TaskMetadata as TaskMetadata, + CodexSettings as CodexSettings, TaskExecution as TaskExecution, + CodexOpenAIModel as CodexOpenAIModel, + CodexServiceTier as CodexServiceTier, EnvironmentClass as EnvironmentClass, OrganizationRole as OrganizationRole, OrganizationTier as OrganizationTier, @@ -36,6 +40,8 @@ TaskExecutionSpec as TaskExecutionSpec, TaskExecutionPhase as TaskExecutionPhase, TaskExecutionStatus as TaskExecutionStatus, + CodexReasoningEffort as CodexReasoningEffort, + KernelControlsAction as KernelControlsAction, CountResponseRelation as CountResponseRelation, TaskExecutionMetadata as TaskExecutionMetadata, EnvironmentVariableItem as EnvironmentVariableItem, @@ -43,15 +49,19 @@ EnvironmentVariableSource as EnvironmentVariableSource, ) from .account import Account as Account +from .process import Process as Process from .project import Project as Project from .prebuild import Prebuild as Prebuild from .workflow import Workflow as Workflow from .log_level import LogLevel as LogLevel from .warm_pool import WarmPool as WarmPool from .agent_mode import AgentMode as AgentMode +from .pr_summary import PrSummary as PrSummary +from .resolution import Resolution as Resolution +from .usage_type import UsageType as UsageType from .veto_param import VetoParam as VetoParam from .environment import Environment as Environment -from .error_level import ErrorLevel as ErrorLevel +from .goal_status import GoalStatus as GoalStatus from .prompt_spec import PromptSpec as PromptSpec from .runner_kind import RunnerKind as RunnerKind from .runner_spec import RunnerSpec as RunnerSpec @@ -65,21 +75,27 @@ from .runner_status import RunnerStatus as RunnerStatus from .update_window import UpdateWindow as UpdateWindow from .workflow_step import WorkflowStep as WorkflowStep +from .co_author_tool import CoAuthorTool as CoAuthorTool from .editor_version import EditorVersion as EditorVersion from .invite_domains import InviteDomains as InviteDomains from .login_provider import LoginProvider as LoginProvider +from .pr_time_bucket import PrTimeBucket as PrTimeBucket from .prebuild_phase import PrebuildPhase as PrebuildPhase from .runner_variant import RunnerVariant as RunnerVariant +from .tool_breakdown import ToolBreakdown as ToolBreakdown from .warm_pool_spec import WarmPoolSpec as WarmPoolSpec from .admission_level import AdmissionLevel as AdmissionLevel from .agent_execution import AgentExecution as AgentExecution from .bpf_debug_level import BpfDebugLevel as BpfDebugLevel +from .credits_by_type import CreditsByType as CreditsByType from .prebuild_status import PrebuildStatus as PrebuildStatus from .prompt_metadata import PromptMetadata as PromptMetadata from .runner_provider import RunnerProvider as RunnerProvider +from .security_policy import SecurityPolicy as SecurityPolicy +from .supported_model import SupportedModel as SupportedModel from .warm_pool_phase import WarmPoolPhase as WarmPoolPhase from .workflow_action import WorkflowAction as WorkflowAction -from .breadcrumb_param import BreadcrumbParam as BreadcrumbParam +from .billing_currency import BillingCurrency as BillingCurrency from .environment_role import EnvironmentRole as EnvironmentRole from .environment_spec import EnvironmentSpec as EnvironmentSpec from .id_token_version import IDTokenVersion as IDTokenVersion @@ -88,20 +104,24 @@ from .wake_event_param import WakeEventParam as WakeEventParam from .warm_pool_status import WarmPoolStatus as WarmPoolStatus from .workflow_trigger import WorkflowTrigger as WorkflowTrigger +from .co_author_summary import CoAuthorSummary as CoAuthorSummary from .environment_phase import EnvironmentPhase as EnvironmentPhase -from .error_event_param import ErrorEventParam as ErrorEventParam from .event_list_params import EventListParams as EventListParams from .group_list_params import GroupListParams as GroupListParams from .prebuild_metadata import PrebuildMetadata as PrebuildMetadata from .runner_capability import RunnerCapability as RunnerCapability from .runner_spec_param import RunnerSpecParam as RunnerSpecParam -from .stack_frame_param import StackFrameParam as StackFrameParam +from .team_credit_usage import TeamCreditUsage as TeamCreditUsage +from .time_series_point import TimeSeriesPoint as TimeSeriesPoint +from .user_credit_usage import UserCreditUsage as UserCreditUsage from .account_membership import AccountMembership as AccountMembership from .agent_code_context import AgentCodeContext as AgentCodeContext +from .daily_credit_usage import DailyCreditUsage as DailyCreditUsage +from .codex_openai_model import CodexOpenAIModel as CodexOpenAIModel +from .codex_service_tier import CodexServiceTier as CodexServiceTier from .editor_list_params import EditorListParams as EditorListParams from .environment_status import EnvironmentStatus as EnvironmentStatus from .event_watch_params import EventWatchParams as EventWatchParams -from .request_info_param import RequestInfoParam as RequestInfoParam from .resource_operation import ResourceOperation as ResourceOperation from .runner_list_params import RunnerListParams as RunnerListParams from .secret_list_params import SecretListParams as SecretListParams @@ -109,6 +129,8 @@ from .warm_pool_metadata import WarmPoolMetadata as WarmPoolMetadata from .workflow_execution import WorkflowExecution as WorkflowExecution from .agent_message_param import AgentMessageParam as AgentMessageParam +from .agent_trace_summary import AgentTraceSummary as AgentTraceSummary +from .enterprise_ai_usage import EnterpriseAIUsage as EnterpriseAIUsage from .event_list_response import EventListResponse as EventListResponse from .gateway_list_params import GatewayListParams as GatewayListParams from .group_create_params import GroupCreateParams as GroupCreateParams @@ -122,7 +144,6 @@ from .workflow_step_param import WorkflowStepParam as WorkflowStepParam from .environment_metadata import EnvironmentMetadata as EnvironmentMetadata from .event_watch_response import EventWatchResponse as EventWatchResponse -from .exception_info_param import ExceptionInfoParam as ExceptionInfoParam from .invite_domains_param import InviteDomainsParam as InviteDomainsParam from .prebuild_list_params import PrebuildListParams as PrebuildListParams from .runner_configuration import RunnerConfiguration as RunnerConfiguration @@ -133,6 +154,8 @@ from .secret_delete_params import SecretDeleteParams as SecretDeleteParams from .user_get_user_params import UserGetUserParams as UserGetUserParams from .account_delete_params import AccountDeleteParams as AccountDeleteParams +from .co_author_time_bucket import CoAuthorTimeBucket as CoAuthorTimeBucket +from .event_retrieve_params import EventRetrieveParams as EventRetrieveParams from .group_create_response import GroupCreateResponse as GroupCreateResponse from .group_retrieve_params import GroupRetrieveParams as GroupRetrieveParams from .group_update_response import GroupUpdateResponse as GroupUpdateResponse @@ -153,13 +176,18 @@ from .runner_release_channel import RunnerReleaseChannel as RunnerReleaseChannel from .runner_retrieve_params import RunnerRetrieveParams as RunnerRetrieveParams from .secret_create_response import SecretCreateResponse as SecretCreateResponse +from .user_cost_budget_usage import UserCostBudgetUsage as UserCostBudgetUsage from .user_get_user_response import UserGetUserResponse as UserGetUserResponse from .user_input_block_param import UserInputBlockParam as UserInputBlockParam from .workflow_trigger_param import WorkflowTriggerParam as WorkflowTriggerParam from .account_retrieve_params import AccountRetrieveParams as AccountRetrieveParams +from .agent_trace_time_bucket import AgentTraceTimeBucket as AgentTraceTimeBucket +from .audit_log_entry_details import AuditLogEntryDetails as AuditLogEntryDetails +from .cumulative_credit_usage import CumulativeCreditUsage as CumulativeCreditUsage from .environment_initializer import EnvironmentInitializer as EnvironmentInitializer from .environment_list_params import EnvironmentListParams as EnvironmentListParams from .environment_stop_params import EnvironmentStopParams as EnvironmentStopParams +from .event_retrieve_response import EventRetrieveResponse as EventRetrieveResponse from .group_retrieve_response import GroupRetrieveResponse as GroupRetrieveResponse from .project_create_response import ProjectCreateResponse as ProjectCreateResponse from .project_retrieve_params import ProjectRetrieveParams as ProjectRetrieveParams @@ -171,6 +199,7 @@ from .automation_delete_params import AutomationDeleteParams as AutomationDeleteParams from .automation_update_params import AutomationUpdateParams as AutomationUpdateParams from .editor_retrieve_response import EditorRetrieveResponse as EditorRetrieveResponse +from .environment_credit_usage import EnvironmentCreditUsage as EnvironmentCreditUsage from .environment_start_params import EnvironmentStartParams as EnvironmentStartParams from .environment_usage_record import EnvironmentUsageRecord as EnvironmentUsageRecord from .organization_join_params import OrganizationJoinParams as OrganizationJoinParams @@ -178,14 +207,19 @@ from .prebuild_create_response import PrebuildCreateResponse as PrebuildCreateResponse from .prebuild_retrieve_params import PrebuildRetrieveParams as PrebuildRetrieveParams from .runner_retrieve_response import RunnerRetrieveResponse as RunnerRetrieveResponse +from .team_enterprise_ai_usage import TeamEnterpriseAIUsage as TeamEnterpriseAIUsage +from .user_credit_budget_usage import UserCreditBudgetUsage as UserCreditBudgetUsage +from .user_enterprise_ai_usage import UserEnterpriseAIUsage as UserEnterpriseAIUsage from .workflow_trigger_context import WorkflowTriggerContext as WorkflowTriggerContext from .account_retrieve_response import AccountRetrieveResponse as AccountRetrieveResponse from .agent_list_prompts_params import AgentListPromptsParams as AgentListPromptsParams +from .byok_rate_card_token_type import ByokRateCardTokenType as ByokRateCardTokenType +from .daily_enterprise_ai_usage import DailyEnterpriseAIUsage as DailyEnterpriseAIUsage from .editor_resolve_url_params import EditorResolveURLParams as EditorResolveURLParams +from .enterprise_ai_token_usage import EnterpriseAITokenUsage as EnterpriseAITokenUsage from .environment_create_params import EnvironmentCreateParams as EnvironmentCreateParams from .environment_delete_params import EnvironmentDeleteParams as EnvironmentDeleteParams from .environment_update_params import EnvironmentUpdateParams as EnvironmentUpdateParams -from .exception_mechanism_param import ExceptionMechanismParam as ExceptionMechanismParam from .organization_leave_params import OrganizationLeaveParams as OrganizationLeaveParams from .project_retrieve_response import ProjectRetrieveResponse as ProjectRetrieveResponse from .recommended_editors_param import RecommendedEditorsParam as RecommendedEditorsParam @@ -198,7 +232,7 @@ from .automation_create_response import AutomationCreateResponse as AutomationCreateResponse from .automation_retrieve_params import AutomationRetrieveParams as AutomationRetrieveParams from .automation_update_response import AutomationUpdateResponse as AutomationUpdateResponse -from .error_report_errors_params import ErrorReportErrorsParams as ErrorReportErrorsParams +from .enterprise_ai_usage_budget import EnterpriseAIUsageBudget as EnterpriseAIUsageBudget from .organization_create_params import OrganizationCreateParams as OrganizationCreateParams from .organization_delete_params import OrganizationDeleteParams as OrganizationDeleteParams from .organization_join_response import OrganizationJoinResponse as OrganizationJoinResponse @@ -210,17 +244,23 @@ from .runner_configuration_param import RunnerConfigurationParam as RunnerConfigurationParam from .secret_update_value_params import SecretUpdateValueParams as SecretUpdateValueParams from .agent_stop_execution_params import AgentStopExecutionParams as AgentStopExecutionParams +from .agent_trace_model_breakdown import AgentTraceModelBreakdown as AgentTraceModelBreakdown from .editor_resolve_url_response import EditorResolveURLResponse as EditorResolveURLResponse from .environment_activity_signal import EnvironmentActivitySignal as EnvironmentActivitySignal from .environment_create_response import EnvironmentCreateResponse as EnvironmentCreateResponse from .environment_retrieve_params import EnvironmentRetrieveParams as EnvironmentRetrieveParams from .metrics_configuration_param import MetricsConfigurationParam as MetricsConfigurationParam +from .security_policy_list_params import SecurityPolicyListParams as SecurityPolicyListParams +from .usage_get_pr_summary_params import UsageGetPrSummaryParams as UsageGetPrSummaryParams from .agent_create_prompt_response import AgentCreatePromptResponse as AgentCreatePromptResponse +from .agent_execution_credit_usage import AgentExecutionCreditUsage as AgentExecutionCreditUsage from .agent_list_executions_params import AgentListExecutionsParams as AgentListExecutionsParams from .agent_retrieve_prompt_params import AgentRetrievePromptParams as AgentRetrievePromptParams from .agent_start_execution_params import AgentStartExecutionParams as AgentStartExecutionParams from .agent_update_prompt_response import AgentUpdatePromptResponse as AgentUpdatePromptResponse from .automation_retrieve_response import AutomationRetrieveResponse as AutomationRetrieveResponse +from .credit_usage_export_group_by import CreditUsageExportGroupBy as CreditUsageExportGroupBy +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel as EnterpriseAIUsageByModel from .environment_unarchive_params import EnvironmentUnarchiveParams as EnvironmentUnarchiveParams from .identity_get_id_token_params import IdentityGetIDTokenParams as IdentityGetIDTokenParams from .kernel_controls_config_param import KernelControlsConfigParam as KernelControlsConfigParam @@ -231,9 +271,14 @@ from .project_bulk_create_response import ProjectBulkCreateResponse as ProjectBulkCreateResponse from .project_bulk_delete_response import ProjectBulkDeleteResponse as ProjectBulkDeleteResponse from .project_bulk_update_response import ProjectBulkUpdateResponse as ProjectBulkUpdateResponse +from .team_cumulative_credit_usage import TeamCumulativeCreditUsage as TeamCumulativeCreditUsage from .agent_delete_execution_params import AgentDeleteExecutionParams as AgentDeleteExecutionParams from .environment_initializer_param import EnvironmentInitializerParam as EnvironmentInitializerParam from .environment_retrieve_response import EnvironmentRetrieveResponse as EnvironmentRetrieveResponse +from .security_policy_create_params import SecurityPolicyCreateParams as SecurityPolicyCreateParams +from .security_policy_delete_params import SecurityPolicyDeleteParams as SecurityPolicyDeleteParams +from .security_policy_update_params import SecurityPolicyUpdateParams as SecurityPolicyUpdateParams +from .usage_get_pr_summary_response import UsageGetPrSummaryResponse as UsageGetPrSummaryResponse from .account_list_sso_logins_params import AccountListSSOLoginsParams as AccountListSSOLoginsParams from .agent_retrieve_prompt_response import AgentRetrievePromptResponse as AgentRetrievePromptResponse from .agent_send_to_execution_params import AgentSendToExecutionParams as AgentSendToExecutionParams @@ -248,8 +293,13 @@ from .prebuild_list_warm_pools_params import PrebuildListWarmPoolsParams as PrebuildListWarmPoolsParams from .runner_create_logs_token_params import RunnerCreateLogsTokenParams as RunnerCreateLogsTokenParams from .runner_parse_context_url_params import RunnerParseContextURLParams as RunnerParseContextURLParams +from .security_policy_create_response import SecurityPolicyCreateResponse as SecurityPolicyCreateResponse +from .security_policy_retrieve_params import SecurityPolicyRetrieveParams as SecurityPolicyRetrieveParams +from .security_policy_update_response import SecurityPolicyUpdateResponse as SecurityPolicyUpdateResponse +from .usage_get_pr_time_series_params import UsageGetPrTimeSeriesParams as UsageGetPrTimeSeriesParams from .account_get_sso_login_url_params import AccountGetSSOLoginURLParams as AccountGetSSOLoginURLParams from .account_list_sso_logins_response import AccountListSSOLoginsResponse as AccountListSSOLoginsResponse +from .credit_usage_report_filter_param import CreditUsageReportFilterParam as CreditUsageReportFilterParam from .identity_exchange_token_response import IdentityExchangeTokenResponse as IdentityExchangeTokenResponse from .organization_list_members_params import OrganizationListMembersParams as OrganizationListMembersParams from .prebuild_create_warm_pool_params import PrebuildCreateWarmPoolParams as PrebuildCreateWarmPoolParams @@ -258,17 +308,22 @@ from .agent_retrieve_execution_response import AgentRetrieveExecutionResponse as AgentRetrieveExecutionResponse from .automation_list_executions_params import AutomationListExecutionsParams as AutomationListExecutionsParams from .automation_start_execution_params import AutomationStartExecutionParams as AutomationStartExecutionParams +from .enterprise_ai_usage_budget_source import EnterpriseAIUsageBudgetSource as EnterpriseAIUsageBudgetSource +from .enterprise_ai_usage_by_token_type import EnterpriseAIUsageByTokenType as EnterpriseAIUsageByTokenType from .environment_activity_signal_param import EnvironmentActivitySignalParam as EnvironmentActivitySignalParam from .prebuild_create_logs_token_params import PrebuildCreateLogsTokenParams as PrebuildCreateLogsTokenParams from .runner_create_logs_token_response import RunnerCreateLogsTokenResponse as RunnerCreateLogsTokenResponse from .runner_create_runner_token_params import RunnerCreateRunnerTokenParams as RunnerCreateRunnerTokenParams from .runner_parse_context_url_response import RunnerParseContextURLResponse as RunnerParseContextURLResponse from .runner_search_repositories_params import RunnerSearchRepositoriesParams as RunnerSearchRepositoriesParams +from .security_policy_retrieve_response import SecurityPolicyRetrieveResponse as SecurityPolicyRetrieveResponse +from .usage_get_pr_time_series_response import UsageGetPrTimeSeriesResponse as UsageGetPrTimeSeriesResponse from .account_get_sso_login_url_response import AccountGetSSOLoginURLResponse as AccountGetSSOLoginURLResponse from .automation_cancel_execution_params import AutomationCancelExecutionParams as AutomationCancelExecutionParams from .prebuild_create_warm_pool_response import PrebuildCreateWarmPoolResponse as PrebuildCreateWarmPoolResponse from .prebuild_retrieve_warm_pool_params import PrebuildRetrieveWarmPoolParams as PrebuildRetrieveWarmPoolParams from .prebuild_update_warm_pool_response import PrebuildUpdateWarmPoolResponse as PrebuildUpdateWarmPoolResponse +from .usage_get_co_author_summary_params import UsageGetCoAuthorSummaryParams as UsageGetCoAuthorSummaryParams from .user_get_authenticated_user_params import UserGetAuthenticatedUserParams as UserGetAuthenticatedUserParams from .account_list_login_providers_params import AccountListLoginProvidersParams as AccountListLoginProvidersParams from .automation_start_execution_response import AutomationStartExecutionResponse as AutomationStartExecutionResponse @@ -280,6 +335,8 @@ from .prebuild_retrieve_warm_pool_response import PrebuildRetrieveWarmPoolResponse as PrebuildRetrieveWarmPoolResponse from .project_prebuild_configuration_param import ProjectPrebuildConfigurationParam as ProjectPrebuildConfigurationParam from .runner_list_scm_organizations_params import RunnerListScmOrganizationsParams as RunnerListScmOrganizationsParams +from .usage_get_agent_trace_summary_params import UsageGetAgentTraceSummaryParams as UsageGetAgentTraceSummaryParams +from .usage_get_co_author_summary_response import UsageGetCoAuthorSummaryResponse as UsageGetCoAuthorSummaryResponse from .user_get_authenticated_user_response import UserGetAuthenticatedUserResponse as UserGetAuthenticatedUserResponse from .runner_check_repository_access_params import ( RunnerCheckRepositoryAccessParams as RunnerCheckRepositoryAccessParams, @@ -287,6 +344,12 @@ from .automation_retrieve_execution_response import ( AutomationRetrieveExecutionResponse as AutomationRetrieveExecutionResponse, ) +from .billing_get_credit_usage_export_params import ( + BillingGetCreditUsageExportParams as BillingGetCreditUsageExportParams, +) +from .billing_get_credit_usage_report_params import ( + BillingGetCreditUsageReportParams as BillingGetCreditUsageReportParams, +) from .environment_create_from_project_params import ( EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams, ) @@ -299,33 +362,64 @@ from .runner_list_scm_organizations_response import ( RunnerListScmOrganizationsResponse as RunnerListScmOrganizationsResponse, ) +from .usage_get_agent_trace_summary_response import ( + UsageGetAgentTraceSummaryResponse as UsageGetAgentTraceSummaryResponse, +) +from .usage_get_co_author_time_series_params import UsageGetCoAuthorTimeSeriesParams as UsageGetCoAuthorTimeSeriesParams +from .enterprise_ai_user_budget_policy_source import ( + EnterpriseAIUserBudgetPolicySource as EnterpriseAIUserBudgetPolicySource, +) from .runner_check_repository_access_response import ( RunnerCheckRepositoryAccessResponse as RunnerCheckRepositoryAccessResponse, ) +from .usage_get_adoption_usage_summary_params import ( + UsageGetAdoptionUsageSummaryParams as UsageGetAdoptionUsageSummaryParams, +) from .automation_list_execution_actions_params import ( AutomationListExecutionActionsParams as AutomationListExecutionActionsParams, ) from .automation_list_execution_outputs_params import ( AutomationListExecutionOutputsParams as AutomationListExecutionOutputsParams, ) +from .billing_get_credit_usage_export_response import ( + BillingGetCreditUsageExportResponse as BillingGetCreditUsageExportResponse, +) +from .billing_get_credit_usage_report_response import ( + BillingGetCreditUsageReportResponse as BillingGetCreditUsageReportResponse, +) from .environment_create_from_project_response import ( EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse, ) from .project_create_from_environment_response import ( ProjectCreateFromEnvironmentResponse as ProjectCreateFromEnvironmentResponse, ) +from .usage_get_agent_trace_time_series_params import ( + UsageGetAgentTraceTimeSeriesParams as UsageGetAgentTraceTimeSeriesParams, +) +from .usage_get_co_author_time_series_response import ( + UsageGetCoAuthorTimeSeriesResponse as UsageGetCoAuthorTimeSeriesResponse, +) from .automation_cancel_execution_action_params import ( AutomationCancelExecutionActionParams as AutomationCancelExecutionActionParams, ) +from .usage_get_adoption_usage_summary_response import ( + UsageGetAdoptionUsageSummaryResponse as UsageGetAdoptionUsageSummaryResponse, +) from .account_list_joinable_organizations_params import ( AccountListJoinableOrganizationsParams as AccountListJoinableOrganizationsParams, ) from .automation_list_execution_outputs_response import ( AutomationListExecutionOutputsResponse as AutomationListExecutionOutputsResponse, ) +from .billing_get_cumulative_credit_usage_params import ( + BillingGetCumulativeCreditUsageParams as BillingGetCumulativeCreditUsageParams, +) from .identity_get_authenticated_identity_params import ( IdentityGetAuthenticatedIdentityParams as IdentityGetAuthenticatedIdentityParams, ) +from .usage_get_agent_trace_time_series_response import ( + UsageGetAgentTraceTimeSeriesResponse as UsageGetAgentTraceTimeSeriesResponse, +) from .automation_retrieve_execution_action_params import ( AutomationRetrieveExecutionActionParams as AutomationRetrieveExecutionActionParams, ) @@ -335,6 +429,18 @@ from .runner_check_authentication_for_host_params import ( RunnerCheckAuthenticationForHostParams as RunnerCheckAuthenticationForHostParams, ) +from .billing_get_cumulative_credit_usage_response import ( + BillingGetCumulativeCreditUsageResponse as BillingGetCumulativeCreditUsageResponse, +) +from .billing_list_enterprise_ai_team_usage_params import ( + BillingListEnterpriseAITeamUsageParams as BillingListEnterpriseAITeamUsageParams, +) +from .billing_list_enterprise_ai_user_usage_params import ( + BillingListEnterpriseAIUserUsageParams as BillingListEnterpriseAIUserUsageParams, +) +from .enterprise_ai_usage_time_series_filter_param import ( + EnterpriseAIUsageTimeSeriesFilterParam as EnterpriseAIUsageTimeSeriesFilterParam, +) from .identity_get_authenticated_identity_response import ( IdentityGetAuthenticatedIdentityResponse as IdentityGetAuthenticatedIdentityResponse, ) @@ -350,9 +456,24 @@ from .usage_list_environment_runtime_records_params import ( UsageListEnvironmentRuntimeRecordsParams as UsageListEnvironmentRuntimeRecordsParams, ) +from .billing_get_enterprise_ai_usage_summary_params import ( + BillingGetEnterpriseAIUsageSummaryParams as BillingGetEnterpriseAIUsageSummaryParams, +) from .agent_create_execution_conversation_token_params import ( AgentCreateExecutionConversationTokenParams as AgentCreateExecutionConversationTokenParams, ) +from .billing_get_enterprise_ai_usage_summary_response import ( + BillingGetEnterpriseAIUsageSummaryResponse as BillingGetEnterpriseAIUsageSummaryResponse, +) +from .billing_list_enterprise_user_credit_usage_params import ( + BillingListEnterpriseUserCreditUsageParams as BillingListEnterpriseUserCreditUsageParams, +) from .agent_create_execution_conversation_token_response import ( AgentCreateExecutionConversationTokenResponse as AgentCreateExecutionConversationTokenResponse, ) +from .billing_get_enterprise_ai_usage_time_series_params import ( + BillingGetEnterpriseAIUsageTimeSeriesParams as BillingGetEnterpriseAIUsageTimeSeriesParams, +) +from .billing_get_enterprise_ai_usage_time_series_response import ( + BillingGetEnterpriseAIUsageTimeSeriesResponse as BillingGetEnterpriseAIUsageTimeSeriesResponse, +) diff --git a/src/gitpod/types/agent_execution.py b/src/gitpod/types/agent_execution.py index 07f02eda..50b6a760 100644 --- a/src/gitpod/types/agent_execution.py +++ b/src/gitpod/types/agent_execution.py @@ -8,7 +8,9 @@ from .._models import BaseModel from .agent_mode import AgentMode +from .goal_status import GoalStatus from .shared.subject import Subject +from .supported_model import SupportedModel from .agent_code_context import AgentCodeContext __all__ = [ @@ -16,11 +18,11 @@ "Metadata", "Spec", "SpecLimits", - "SpecLoopCondition", "Status", "StatusCurrentOperation", "StatusCurrentOperationLlm", "StatusCurrentOperationToolUse", + "StatusGoal", "StatusMcpIntegrationStatus", "StatusOutputs", "StatusUsedEnvironment", @@ -247,14 +249,6 @@ class SpecLimits(BaseModel): max_output_tokens: Optional[str] = FieldInfo(alias="maxOutputTokens", default=None) -class SpecLoopCondition(BaseModel): - id: Optional[str] = None - - description: Optional[str] = None - - expression: Optional[str] = None - - class Spec(BaseModel): """ Spec is the configuration of the agent that's required for the @@ -272,8 +266,6 @@ class Spec(BaseModel): limits: Optional[SpecLimits] = None - loop_conditions: Optional[List[SpecLoopCondition]] = FieldInfo(alias="loopConditions", default=None) - session: Optional[str] = None spec_version: Optional[str] = FieldInfo(alias="specVersion", default=None) @@ -308,6 +300,34 @@ class StatusCurrentOperation(BaseModel): tool_use: Optional[StatusCurrentOperationToolUse] = FieldInfo(alias="toolUse", default=None) +class StatusGoal(BaseModel): + """goal projects the current agent goal, if any.""" + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + """created_at is when the current goal was created, when available.""" + + objective: Optional[str] = None + """objective is the current goal text tracked by the agent.""" + + status: Optional[GoalStatus] = None + """status is the lifecycle state of the current goal.""" + + time_used: Optional[str] = FieldInfo(alias="timeUsed", default=None) + """time_used is the elapsed wall-clock time reported by the agent for this goal.""" + + token_budget: Optional[str] = FieldInfo(alias="tokenBudget", default=None) + """ + token_budget is the token budget reported by the agent for this goal, when one + exists. + """ + + tokens_used: Optional[str] = FieldInfo(alias="tokensUsed", default=None) + """tokens_used is the token usage reported by the agent for this goal.""" + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + """updated_at is the most recent goal update timestamp, when available.""" + + class StatusMcpIntegrationStatus(BaseModel): """ MCPIntegrationStatus represents the status of a single MCP integration @@ -393,6 +413,9 @@ class Status(BaseModel): ] = FieldInfo(alias="failureReason", default=None) """failure_reason contains a structured reason code for the failure.""" + goal: Optional[StatusGoal] = None + """goal projects the current agent goal, if any.""" + input_tokens_used: Optional[str] = FieldInfo(alias="inputTokensUsed", default=None) iterations: Optional[str] = None @@ -437,31 +460,7 @@ class Status(BaseModel): b.status_version then a was the status before b. """ - supported_model: Optional[ - Literal[ - "SUPPORTED_MODEL_UNSPECIFIED", - "SUPPORTED_MODEL_SONNET_3_5", - "SUPPORTED_MODEL_SONNET_3_7", - "SUPPORTED_MODEL_SONNET_3_7_EXTENDED", - "SUPPORTED_MODEL_SONNET_4", - "SUPPORTED_MODEL_SONNET_4_EXTENDED", - "SUPPORTED_MODEL_SONNET_4_5", - "SUPPORTED_MODEL_SONNET_4_5_EXTENDED", - "SUPPORTED_MODEL_SONNET_4_6", - "SUPPORTED_MODEL_SONNET_4_6_EXTENDED", - "SUPPORTED_MODEL_OPUS_4", - "SUPPORTED_MODEL_OPUS_4_EXTENDED", - "SUPPORTED_MODEL_OPUS_4_5", - "SUPPORTED_MODEL_OPUS_4_5_EXTENDED", - "SUPPORTED_MODEL_OPUS_4_6", - "SUPPORTED_MODEL_OPUS_4_6_EXTENDED", - "SUPPORTED_MODEL_HAIKU_4_5", - "SUPPORTED_MODEL_OPENAI_4O", - "SUPPORTED_MODEL_OPENAI_4O_MINI", - "SUPPORTED_MODEL_OPENAI_O1", - "SUPPORTED_MODEL_OPENAI_O1_MINI", - ] - ] = FieldInfo(alias="supportedModel", default=None) + supported_model: Optional[SupportedModel] = FieldInfo(alias="supportedModel", default=None) """supported_model is the LLM model being used by the agent execution.""" transcript_url: Optional[str] = FieldInfo(alias="transcriptUrl", default=None) diff --git a/src/gitpod/types/agent_execution_credit_usage.py b/src/gitpod/types/agent_execution_credit_usage.py new file mode 100644 index 00000000..bac02f1c --- /dev/null +++ b/src/gitpod/types/agent_execution_credit_usage.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType + +__all__ = ["AgentExecutionCreditUsage"] + + +class AgentExecutionCreditUsage(BaseModel): + """ + AgentExecutionCreditUsage contains a single agent execution's credit usage for a day, broken down by type. + """ + + agent_execution_id: Optional[str] = FieldInfo(alias="agentExecutionId", default=None) + """Empty when representing the "Others" aggregation bucket.""" + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + usage: Optional[List[CreditsByType]] = None diff --git a/src/gitpod/types/agent_list_executions_params.py b/src/gitpod/types/agent_list_executions_params.py index f139d42c..096c97f1 100644 --- a/src/gitpod/types/agent_list_executions_params.py +++ b/src/gitpod/types/agent_list_executions_params.py @@ -22,6 +22,12 @@ class AgentListExecutionsParams(TypedDict, total=False): class Filter(TypedDict, total=False): + agent_execution_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="agentExecutionIds")] + """ + agent_execution_ids filters the response to only the specified executions. + Useful for checking existence of a known set of execution IDs. + """ + agent_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="agentIds")] annotations: Dict[str, str] diff --git a/src/gitpod/types/agent_mode.py b/src/gitpod/types/agent_mode.py index a58c3798..b668b79b 100644 --- a/src/gitpod/types/agent_mode.py +++ b/src/gitpod/types/agent_mode.py @@ -5,5 +5,10 @@ __all__ = ["AgentMode"] AgentMode: TypeAlias = Literal[ - "AGENT_MODE_UNSPECIFIED", "AGENT_MODE_EXECUTION", "AGENT_MODE_PLANNING", "AGENT_MODE_RALPH", "AGENT_MODE_SPEC" + "AGENT_MODE_UNSPECIFIED", + "AGENT_MODE_EXECUTION", + "AGENT_MODE_PLANNING", + "AGENT_MODE_RALPH", + "AGENT_MODE_SPEC", + "AGENT_MODE_GOAL", ] diff --git a/src/gitpod/types/agent_send_to_execution_params.py b/src/gitpod/types/agent_send_to_execution_params.py index 2ad05f82..0ed543e0 100644 --- a/src/gitpod/types/agent_send_to_execution_params.py +++ b/src/gitpod/types/agent_send_to_execution_params.py @@ -8,6 +8,7 @@ from .wake_event_param import WakeEventParam from .agent_message_param import AgentMessageParam from .user_input_block_param import UserInputBlockParam +from .shared_params.codex_settings import CodexSettings __all__ = ["AgentSendToExecutionParams"] @@ -21,6 +22,12 @@ class AgentSendToExecutionParams(TypedDict, total=False): from a parent agent to a child agent execution, or vice versa). """ + codex_settings: Annotated[CodexSettings, PropertyInfo(alias="codexSettings")] + """ + codex_settings contains per-turn desired settings for Codex app user_input + sends. + """ + user_input: Annotated[UserInputBlockParam, PropertyInfo(alias="userInput")] wake_event: Annotated[WakeEventParam, PropertyInfo(alias="wakeEvent")] diff --git a/src/gitpod/types/agent_start_execution_params.py b/src/gitpod/types/agent_start_execution_params.py index 4e3f82b1..29da4adf 100644 --- a/src/gitpod/types/agent_start_execution_params.py +++ b/src/gitpod/types/agent_start_execution_params.py @@ -8,12 +8,18 @@ from .._utils import PropertyInfo from .agent_mode import AgentMode from .agent_code_context_param import AgentCodeContextParam +from .shared_params.codex_settings import CodexSettings __all__ = ["AgentStartExecutionParams"] class AgentStartExecutionParams(TypedDict, total=False): agent_id: Annotated[str, PropertyInfo(alias="agentId")] + """agent_id identifies the agent to start. + + If omitted, the backend uses the configured default agent ID, or the Ona + in-environment agent when no default is configured. + """ annotations: Dict[str, str] """ @@ -24,6 +30,9 @@ class AgentStartExecutionParams(TypedDict, total=False): code_context: Annotated[AgentCodeContextParam, PropertyInfo(alias="codeContext")] + codex_settings: Annotated[CodexSettings, PropertyInfo(alias="codexSettings")] + """codex_settings contains desired manual settings for the Codex app agent.""" + mode: AgentMode """ mode specifies the operational mode for this agent execution If not specified, diff --git a/src/gitpod/types/agent_trace_model_breakdown.py b/src/gitpod/types/agent_trace_model_breakdown.py new file mode 100644 index 00000000..f2f3e44b --- /dev/null +++ b/src/gitpod/types/agent_trace_model_breakdown.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .supported_model import SupportedModel + +__all__ = ["AgentTraceModelBreakdown"] + + +class AgentTraceModelBreakdown(BaseModel): + """AgentTraceModelBreakdown contains stats for a single LLM model.""" + + lines_added: Optional[str] = FieldInfo(alias="linesAdded", default=None) + """Lines added by sessions using this model.""" + + lines_removed: Optional[str] = FieldInfo(alias="linesRemoved", default=None) + """Lines removed by sessions using this model.""" + + model: Optional[SupportedModel] = None + """The model these stats are for.""" + + sessions: Optional[str] = None + """Number of sessions that used this model.""" diff --git a/src/gitpod/types/agent_trace_summary.py b/src/gitpod/types/agent_trace_summary.py new file mode 100644 index 00000000..2a2054c3 --- /dev/null +++ b/src/gitpod/types/agent_trace_summary.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .agent_trace_model_breakdown import AgentTraceModelBreakdown + +__all__ = ["AgentTraceSummary"] + + +class AgentTraceSummary(BaseModel): + """AgentTraceSummary contains aggregate totals for a date range.""" + + by_model: Optional[List[AgentTraceModelBreakdown]] = FieldInfo(alias="byModel", default=None) + """Per-model breakdown of session stats.""" + + total_lines_added: Optional[str] = FieldInfo(alias="totalLinesAdded", default=None) + """Total lines added across all sessions.""" + + total_lines_added_trend: Optional[float] = FieldInfo(alias="totalLinesAddedTrend", default=None) + """Fractional change in total_lines_added compared to the previous period.""" + + total_lines_removed: Optional[str] = FieldInfo(alias="totalLinesRemoved", default=None) + """Total lines removed across all sessions.""" + + total_lines_removed_trend: Optional[float] = FieldInfo(alias="totalLinesRemovedTrend", default=None) + """Fractional change in total_lines_removed compared to the previous period.""" + + total_sessions: Optional[str] = FieldInfo(alias="totalSessions", default=None) + """Total number of agent trace sessions in the date range.""" + + total_sessions_trend: Optional[float] = FieldInfo(alias="totalSessionsTrend", default=None) + """ + Fractional change in total_sessions compared to the previous period of equal + length. Computed as (current - previous) / previous. Zero when there is no + previous data. + """ diff --git a/src/gitpod/types/agent_trace_time_bucket.py b/src/gitpod/types/agent_trace_time_bucket.py new file mode 100644 index 00000000..bf3e8880 --- /dev/null +++ b/src/gitpod/types/agent_trace_time_bucket.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .agent_trace_model_breakdown import AgentTraceModelBreakdown + +__all__ = ["AgentTraceTimeBucket"] + + +class AgentTraceTimeBucket(BaseModel): + """AgentTraceTimeBucket contains stats for a single time period.""" + + by_model: Optional[List[AgentTraceModelBreakdown]] = FieldInfo(alias="byModel", default=None) + """Per-model breakdown for this bucket.""" + + start_time: Optional[datetime] = FieldInfo(alias="startTime", default=None) + """Start of this time bucket.""" + + total_lines_added: Optional[str] = FieldInfo(alias="totalLinesAdded", default=None) + """Total lines added in this bucket.""" + + total_lines_removed: Optional[str] = FieldInfo(alias="totalLinesRemoved", default=None) + """Total lines removed in this bucket.""" + + total_sessions: Optional[str] = FieldInfo(alias="totalSessions", default=None) + """Number of agent trace sessions in this bucket.""" diff --git a/src/gitpod/types/audit_log_entry_details.py b/src/gitpod/types/audit_log_entry_details.py new file mode 100644 index 00000000..6f8218b9 --- /dev/null +++ b/src/gitpod/types/audit_log_entry_details.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .process import Process +from .._models import BaseModel +from .shared.kernel_controls_action import KernelControlsAction + +__all__ = ["AuditLogEntryDetails", "VetoExec"] + + +class VetoExec(BaseModel): + """veto_exec contains Veto Exec event details without process.cmdline.""" + + process: Process + """process contains metadata about the process that triggered the event.""" + + timestamp: datetime + """timestamp is when the event occurred in the environment.""" + + action: Optional[KernelControlsAction] = None + """action is the enforcement action taken (block or audit).""" + + environment_id: Optional[str] = FieldInfo(alias="environmentId", default=None) + """environment_id is the environment where the event occurred.""" + + executable: Optional[str] = None + """ + executable is the digest of the binary content (e.g., "sha256:a1b2c3d4..."). 256 + allows for longer hash algorithms or prefixed identifiers. May be empty when the + event source cannot compute the hash. + """ + + filename: Optional[str] = None + """ + filename is the kernel-resolved path of the binary. Kernel PATH_MAX = 4096 + (include/uapi/linux/limits.h). May be empty if the event source could not + resolve it. + """ + + +class AuditLogEntryDetails(BaseModel): + """ + AuditLogEntryDetails contains the typed evidence stored with an audit-log entry. + """ + + veto_exec: VetoExec = FieldInfo(alias="vetoExec") + """veto_exec contains Veto Exec event details without process.cmdline.""" diff --git a/src/gitpod/types/automation_create_params.py b/src/gitpod/types/automation_create_params.py index cb8ade23..0aa6cf43 100644 --- a/src/gitpod/types/automation_create_params.py +++ b/src/gitpod/types/automation_create_params.py @@ -3,11 +3,13 @@ from __future__ import annotations from typing import Iterable, Optional -from typing_extensions import Required, TypedDict +from typing_extensions import Required, Annotated, TypedDict +from .._utils import PropertyInfo from .shared_params.subject import Subject from .workflow_action_param import WorkflowActionParam from .workflow_trigger_param import WorkflowTriggerParam +from .shared_params.codex_settings import CodexSettings __all__ = ["AutomationCreateParams"] @@ -16,6 +18,12 @@ class AutomationCreateParams(TypedDict, total=False): action: Required[WorkflowActionParam] """WorkflowAction defines the actions to be executed in a workflow.""" + codex_settings: Annotated[CodexSettings, PropertyInfo(alias="codexSettings")] + """Codex app agent settings. + + Only meaningful when agent_id refers to the Codex app agent. + """ + description: str """Description must be at most 500 characters: diff --git a/src/gitpod/types/automation_update_params.py b/src/gitpod/types/automation_update_params.py index cae3bafb..972ced3f 100644 --- a/src/gitpod/types/automation_update_params.py +++ b/src/gitpod/types/automation_update_params.py @@ -9,6 +9,7 @@ from .shared_params.subject import Subject from .workflow_action_param import WorkflowActionParam from .workflow_trigger_param import WorkflowTriggerParam +from .shared_params.codex_settings import CodexSettings __all__ = ["AutomationUpdateParams"] @@ -17,6 +18,12 @@ class AutomationUpdateParams(TypedDict, total=False): action: Optional[WorkflowActionParam] """WorkflowAction defines the actions to be executed in a workflow.""" + codex_settings: Annotated[Optional[CodexSettings], PropertyInfo(alias="codexSettings")] + """Codex app agent settings. + + Only meaningful when agent_id refers to the Codex app agent. + """ + description: Optional[str] """Description must be at most 500 characters: diff --git a/src/gitpod/types/billing_currency.py b/src/gitpod/types/billing_currency.py new file mode 100644 index 00000000..0f936e88 --- /dev/null +++ b/src/gitpod/types/billing_currency.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["BillingCurrency"] + +BillingCurrency: TypeAlias = Literal[ + "BILLING_CURRENCY_UNSPECIFIED", "BILLING_CURRENCY_USD", "BILLING_CURRENCY_EUR", "BILLING_CURRENCY_GBP" +] diff --git a/src/gitpod/types/billing_get_credit_usage_export_params.py b/src/gitpod/types/billing_get_credit_usage_export_params.py new file mode 100644 index 00000000..7fabd832 --- /dev/null +++ b/src/gitpod/types/billing_get_credit_usage_export_params.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange +from .credit_usage_export_group_by import CreditUsageExportGroupBy + +__all__ = ["BillingGetCreditUsageExportParams"] + + +class BillingGetCreditUsageExportParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to export. + + Both start and end dates are inclusive; time-of-day is ignored. Unlike + GetCreditUsageReport, the range may cover up to a year. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + group_by: Annotated[CreditUsageExportGroupBy, PropertyInfo(alias="groupBy")] + """How to group the export data. Defaults to DAILY_SUMMARY.""" diff --git a/src/gitpod/types/billing_get_credit_usage_export_response.py b/src/gitpod/types/billing_get_credit_usage_export_response.py new file mode 100644 index 00000000..316a998d --- /dev/null +++ b/src/gitpod/types/billing_get_credit_usage_export_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["BillingGetCreditUsageExportResponse"] + + +class BillingGetCreditUsageExportResponse(BaseModel): + download_url: Optional[str] = FieldInfo(alias="downloadUrl", default=None) + """Signed download URL for the CSV export. + + Valid for five minutes, and only for the principal that requested it. + """ diff --git a/src/gitpod/types/billing_get_credit_usage_report_params.py b/src/gitpod/types/billing_get_credit_usage_report_params.py new file mode 100644 index 00000000..60732312 --- /dev/null +++ b/src/gitpod/types/billing_get_credit_usage_report_params.py @@ -0,0 +1,37 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange +from .credit_usage_report_filter_param import CreditUsageReportFilterParam + +__all__ = ["BillingGetCreditUsageReportParams"] + + +class BillingGetCreditUsageReportParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range for the report. + + Both start and end dates are inclusive. Time-of-day is ignored; dates are + truncated to midnight in the specified timezone. The range must not exceed 31 + days. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + filter: CreditUsageReportFilterParam + """Optional filter narrowing the returned data. + + When unset or empty, the response preserves the default behavior (top-N users + + "Others"). See CreditUsageReportFilter for per-field response-scoping semantics. + """ + + timezone: str + """IANA timezone name (e.g. + + "America/New_York", "Europe/Berlin") used to bucket daily usage. When empty, + defaults to "UTC". + """ diff --git a/src/gitpod/types/billing_get_credit_usage_report_response.py b/src/gitpod/types/billing_get_credit_usage_report_response.py new file mode 100644 index 00000000..be7e3938 --- /dev/null +++ b/src/gitpod/types/billing_get_credit_usage_report_response.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .daily_credit_usage import DailyCreditUsage + +__all__ = ["BillingGetCreditUsageReportResponse"] + + +class BillingGetCreditUsageReportResponse(BaseModel): + daily_usage: Optional[List[DailyCreditUsage]] = FieldInfo(alias="dailyUsage", default=None) + """One entry per day in the requested date range.""" + + period_start: Optional[datetime] = FieldInfo(alias="periodStart", default=None) + """ + Start of the billing period for this organization. Used by the frontend to + filter out months before usage tracking began. + """ + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + """When the report data was last computed.""" diff --git a/src/gitpod/types/billing_get_cumulative_credit_usage_params.py b/src/gitpod/types/billing_get_cumulative_credit_usage_params.py new file mode 100644 index 00000000..2071f344 --- /dev/null +++ b/src/gitpod/types/billing_get_cumulative_credit_usage_params.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["BillingGetCumulativeCreditUsageParams"] + + +class BillingGetCumulativeCreditUsageParams(TypedDict, total=False): + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + """organization_id is the ID of the organization to get cumulative usage for.""" + + as_of: Annotated[Union[str, datetime, None], PropertyInfo(alias="asOf", format="iso8601")] + """ + as_of is the point in time to compute cumulative usage up to. Defaults to now if + not set. + """ diff --git a/src/gitpod/types/billing_get_cumulative_credit_usage_response.py b/src/gitpod/types/billing_get_cumulative_credit_usage_response.py new file mode 100644 index 00000000..a3dd1b4b --- /dev/null +++ b/src/gitpod/types/billing_get_cumulative_credit_usage_response.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .cumulative_credit_usage import CumulativeCreditUsage +from .user_credit_budget_usage import UserCreditBudgetUsage +from .team_cumulative_credit_usage import TeamCumulativeCreditUsage + +__all__ = ["BillingGetCumulativeCreditUsageResponse"] + + +class BillingGetCumulativeCreditUsageResponse(BaseModel): + org_usage: Optional[CumulativeCreditUsage] = FieldInfo(alias="orgUsage", default=None) + """Org-wide cumulative usage, broken down by type and total.""" + + period_start: Optional[datetime] = FieldInfo(alias="periodStart", default=None) + """ + Start of the cumulative calculation period. Cumulative totals are computed from + this date forward. + """ + + team_usage: Optional[List[TeamCumulativeCreditUsage]] = FieldInfo(alias="teamUsage", default=None) + """ + Per-team cumulative usage with credit allocation comparison. Returns all teams + (no top-N limit). + """ + + unteamed_usage: Optional[CumulativeCreditUsage] = FieldInfo(alias="unteamedUsage", default=None) + """Usage by members not assigned to any team.""" + + user_usage: Optional[List[UserCreditBudgetUsage]] = FieldInfo(alias="userUsage", default=None) + """ + Per-user month-to-date usage for every user with usage in the period. The budget + fields on each entry are populated only when a monthly budget applies to that + user. This list is not paginated or capped; for large organizations prefer + ListEnterpriseUserCreditUsage. + """ diff --git a/src/gitpod/types/billing_get_enterprise_ai_usage_summary_params.py b/src/gitpod/types/billing_get_enterprise_ai_usage_summary_params.py new file mode 100644 index 00000000..6bacad25 --- /dev/null +++ b/src/gitpod/types/billing_get_enterprise_ai_usage_summary_params.py @@ -0,0 +1,24 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["BillingGetEnterpriseAIUsageSummaryParams"] + + +class BillingGetEnterpriseAIUsageSummaryParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range for the summary. + + Both start and end dates are inclusive. Time-of-day is ignored; dates are + truncated to midnight in the specified timezone. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + timezone: str + """IANA timezone name used to bucket usage. When empty, defaults to "UTC".""" diff --git a/src/gitpod/types/billing_get_enterprise_ai_usage_summary_response.py b/src/gitpod/types/billing_get_enterprise_ai_usage_summary_response.py new file mode 100644 index 00000000..aefcf09f --- /dev/null +++ b/src/gitpod/types/billing_get_enterprise_ai_usage_summary_response.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage +from .enterprise_ai_usage_budget import EnterpriseAIUsageBudget +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel + +__all__ = ["BillingGetEnterpriseAIUsageSummaryResponse"] + + +class BillingGetEnterpriseAIUsageSummaryResponse(BaseModel): + budget: Optional[EnterpriseAIUsageBudget] = None + """budget is unset when no monthly budget applies to the organization.""" + + calculated_at: Optional[datetime] = FieldInfo(alias="calculatedAt", default=None) + """ + calculated_at is the time through which usage has been calculated. Usage after + this timestamp may still be processing. + """ + + usage: Optional[EnterpriseAIUsage] = None + + usage_by_model: Optional[List[EnterpriseAIUsageByModel]] = FieldInfo(alias="usageByModel", default=None) diff --git a/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_params.py b/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_params.py new file mode 100644 index 00000000..a3a91138 --- /dev/null +++ b/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_params.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange +from .enterprise_ai_usage_time_series_filter_param import EnterpriseAIUsageTimeSeriesFilterParam + +__all__ = ["BillingGetEnterpriseAIUsageTimeSeriesParams"] + + +class BillingGetEnterpriseAIUsageTimeSeriesParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range for the daily usage series. + + Both start and end dates are inclusive. Time-of-day is ignored; dates are + truncated to midnight in the specified timezone. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + filter: EnterpriseAIUsageTimeSeriesFilterParam + + timezone: str + """IANA timezone name used to bucket daily usage. When empty, defaults to "UTC".""" diff --git a/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_response.py b/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_response.py new file mode 100644 index 00000000..10b708c8 --- /dev/null +++ b/src/gitpod/types/billing_get_enterprise_ai_usage_time_series_response.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .daily_enterprise_ai_usage import DailyEnterpriseAIUsage + +__all__ = ["BillingGetEnterpriseAIUsageTimeSeriesResponse"] + + +class BillingGetEnterpriseAIUsageTimeSeriesResponse(BaseModel): + calculated_at: Optional[datetime] = FieldInfo(alias="calculatedAt", default=None) + """ + calculated_at is the time through which usage has been calculated. Usage after + this timestamp may still be processing. + """ + + daily_usage: Optional[List[DailyEnterpriseAIUsage]] = FieldInfo(alias="dailyUsage", default=None) diff --git a/src/gitpod/types/billing_list_enterprise_ai_team_usage_params.py b/src/gitpod/types/billing_list_enterprise_ai_team_usage_params.py new file mode 100644 index 00000000..b3374390 --- /dev/null +++ b/src/gitpod/types/billing_list_enterprise_ai_team_usage_params.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["BillingListEnterpriseAITeamUsageParams", "Filter", "Pagination"] + + +class BillingListEnterpriseAITeamUsageParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range for the team usage list. + + Both start and end dates are inclusive. Time-of-day is ignored; dates are + truncated to midnight in the specified timezone. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + token: str + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + filter: Filter + + pagination: Pagination + + timezone: str + """IANA timezone name used to bucket usage. When empty, defaults to "UTC".""" + + +class Filter(TypedDict, total=False): + team_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="teamIds")] + + +class Pagination(TypedDict, total=False): + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ diff --git a/src/gitpod/types/billing_list_enterprise_ai_user_usage_params.py b/src/gitpod/types/billing_list_enterprise_ai_user_usage_params.py new file mode 100644 index 00000000..9d375be4 --- /dev/null +++ b/src/gitpod/types/billing_list_enterprise_ai_user_usage_params.py @@ -0,0 +1,86 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared.sort_order import SortOrder +from .shared_params.subject import Subject +from .shared_params.date_range import DateRange + +__all__ = ["BillingListEnterpriseAIUserUsageParams", "Filter", "Pagination", "Sort"] + + +class BillingListEnterpriseAIUserUsageParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range for the user usage list. + + Both start and end dates are inclusive. Time-of-day is ignored; dates are + truncated to midnight in the specified timezone. + """ + + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + + token: str + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + filter: Filter + """Optional filter narrowing the returned user usage. + + When set to a subject, the response contains only usage for that user or service + account. + """ + + pagination: Pagination + + sort: Sort + """sort controls the ordering of results. Defaults to total spend descending.""" + + timezone: str + """IANA timezone name used to bucket usage. When empty, defaults to "UTC".""" + + +class Filter(TypedDict, total=False): + """Optional filter narrowing the returned user usage. + + When set to a subject, + the response contains only usage for that user or service account. + """ + + subject: Optional[Subject] + """Restrict the user usage list to a single subject. + + The subject must be PRINCIPAL_USER or PRINCIPAL_SERVICE_ACCOUNT and belong to + the request's organization. + """ + + +class Pagination(TypedDict, total=False): + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ + + +class Sort(TypedDict, total=False): + """sort controls the ordering of results. Defaults to total spend descending.""" + + field: Literal[ + "SORT_FIELD_UNSPECIFIED", + "SORT_FIELD_USAGE", + "SORT_FIELD_DISPLAY_NAME", + "SORT_FIELD_BUDGET", + "SORT_FIELD_BUDGET_USED", + ] + + order: SortOrder diff --git a/src/gitpod/types/billing_list_enterprise_user_credit_usage_params.py b/src/gitpod/types/billing_list_enterprise_user_credit_usage_params.py new file mode 100644 index 00000000..0c77216e --- /dev/null +++ b/src/gitpod/types/billing_list_enterprise_user_credit_usage_params.py @@ -0,0 +1,60 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Literal, Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared.sort_order import SortOrder + +__all__ = ["BillingListEnterpriseUserCreditUsageParams", "Pagination", "Sort"] + + +class BillingListEnterpriseUserCreditUsageParams(TypedDict, total=False): + organization_id: Required[Annotated[str, PropertyInfo(alias="organizationId")]] + """organization_id is the ID of the organization to list user credit usage for.""" + + token: str + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + as_of: Annotated[Union[str, datetime, None], PropertyInfo(alias="asOf", format="iso8601")] + """ + as_of is the point in time to compute month-to-date usage up to. Defaults to now + if not set. + """ + + pagination: Pagination + + sort: Sort + """sort controls the ordering of results. Defaults to total credits descending.""" + + +class Pagination(TypedDict, total=False): + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ + + +class Sort(TypedDict, total=False): + """sort controls the ordering of results. Defaults to total credits descending.""" + + field: Literal[ + "SORT_FIELD_UNSPECIFIED", + "SORT_FIELD_USAGE", + "SORT_FIELD_DISPLAY_NAME", + "SORT_FIELD_BUDGET", + "SORT_FIELD_BUDGET_USED", + ] + + order: SortOrder diff --git a/src/gitpod/types/breadcrumb_param.py b/src/gitpod/types/breadcrumb_param.py deleted file mode 100644 index cef8444d..00000000 --- a/src/gitpod/types/breadcrumb_param.py +++ /dev/null @@ -1,34 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict, Union -from datetime import datetime -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo -from .error_level import ErrorLevel - -__all__ = ["BreadcrumbParam"] - - -class BreadcrumbParam(TypedDict, total=False): - """Breadcrumb information (Sentry-compatible)""" - - category: str - """Breadcrumb category""" - - data: Dict[str, str] - """Additional breadcrumb data""" - - level: ErrorLevel - """Breadcrumb level""" - - message: str - """Breadcrumb message""" - - timestamp: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """When the breadcrumb occurred""" - - type: str - """Breadcrumb type (e.g., "navigation", "http", "user", "error")""" diff --git a/src/gitpod/types/byok_rate_card_token_type.py b/src/gitpod/types/byok_rate_card_token_type.py new file mode 100644 index 00000000..728ed057 --- /dev/null +++ b/src/gitpod/types/byok_rate_card_token_type.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["ByokRateCardTokenType"] + +ByokRateCardTokenType: TypeAlias = Literal[ + "BYOK_RATE_CARD_TOKEN_TYPE_UNSPECIFIED", + "BYOK_RATE_CARD_TOKEN_TYPE_INPUT", + "BYOK_RATE_CARD_TOKEN_TYPE_OUTPUT", + "BYOK_RATE_CARD_TOKEN_TYPE_CACHE_READ", + "BYOK_RATE_CARD_TOKEN_TYPE_CACHE_WRITE", +] diff --git a/src/gitpod/types/co_author_summary.py b/src/gitpod/types/co_author_summary.py new file mode 100644 index 00000000..ff214ca9 --- /dev/null +++ b/src/gitpod/types/co_author_summary.py @@ -0,0 +1,45 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .tool_breakdown import ToolBreakdown + +__all__ = ["CoAuthorSummary"] + + +class CoAuthorSummary(BaseModel): + """CoAuthorSummary contains aggregate totals for a date range.""" + + by_tool: Optional[List[ToolBreakdown]] = FieldInfo(alias="byTool", default=None) + """Per-tool breakdown of contribution stats.""" + + distinct_authors: Optional[str] = FieldInfo(alias="distinctAuthors", default=None) + """Number of distinct authors (by author_hash).""" + + distinct_authors_trend: Optional[float] = FieldInfo(alias="distinctAuthorsTrend", default=None) + """Fractional change in distinct_authors compared to the previous period.""" + + total_commits: Optional[str] = FieldInfo(alias="totalCommits", default=None) + """Total number of commits in the date range.""" + + total_commits_trend: Optional[float] = FieldInfo(alias="totalCommitsTrend", default=None) + """ + Fractional change in total_commits compared to the previous period of equal + length. Computed as (current - previous) / previous. Zero when there is no + previous data. + """ + + total_lines_added: Optional[str] = FieldInfo(alias="totalLinesAdded", default=None) + """Total lines added across all commits.""" + + total_lines_added_trend: Optional[float] = FieldInfo(alias="totalLinesAddedTrend", default=None) + """Fractional change in total_lines_added compared to the previous period.""" + + total_lines_removed: Optional[str] = FieldInfo(alias="totalLinesRemoved", default=None) + """Total lines removed across all commits.""" + + total_lines_removed_trend: Optional[float] = FieldInfo(alias="totalLinesRemovedTrend", default=None) + """Fractional change in total_lines_removed compared to the previous period.""" diff --git a/src/gitpod/types/co_author_time_bucket.py b/src/gitpod/types/co_author_time_bucket.py new file mode 100644 index 00000000..6a462b87 --- /dev/null +++ b/src/gitpod/types/co_author_time_bucket.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .tool_breakdown import ToolBreakdown + +__all__ = ["CoAuthorTimeBucket"] + + +class CoAuthorTimeBucket(BaseModel): + """CoAuthorTimeBucket contains stats for a single time period.""" + + ai_ratio: Optional[float] = FieldInfo(alias="aiRatio", default=None) + """Ratio of AI-assisted lines added to total lines added (0.0–1.0).""" + + by_tool: Optional[List[ToolBreakdown]] = FieldInfo(alias="byTool", default=None) + """Per-tool breakdown for this bucket.""" + + distinct_authors: Optional[str] = FieldInfo(alias="distinctAuthors", default=None) + """Number of distinct authors (by author_hash) in this bucket.""" + + start_time: Optional[datetime] = FieldInfo(alias="startTime", default=None) + """Start of this time bucket.""" + + total_commits: Optional[str] = FieldInfo(alias="totalCommits", default=None) + """Total number of commits in this bucket (across all tools).""" + + total_lines_added: Optional[str] = FieldInfo(alias="totalLinesAdded", default=None) + """Total lines added in this bucket (across all tools).""" + + total_lines_removed: Optional[str] = FieldInfo(alias="totalLinesRemoved", default=None) + """Total lines removed in this bucket (across all tools).""" diff --git a/src/gitpod/types/co_author_tool.py b/src/gitpod/types/co_author_tool.py new file mode 100644 index 00000000..9c713060 --- /dev/null +++ b/src/gitpod/types/co_author_tool.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CoAuthorTool"] + +CoAuthorTool: TypeAlias = Literal[ + "CO_AUTHOR_TOOL_UNSPECIFIED", + "CO_AUTHOR_TOOL_NO_COAUTHOR", + "CO_AUTHOR_TOOL_HUMAN_COAUTHOR", + "CO_AUTHOR_TOOL_ONA", + "CO_AUTHOR_TOOL_GITHUB_COPILOT", + "CO_AUTHOR_TOOL_CURSOR", + "CO_AUTHOR_TOOL_OTHER", + "CO_AUTHOR_TOOL_CLAUDE", + "CO_AUTHOR_TOOL_CODEX", +] diff --git a/src/gitpod/types/credit_usage_export_group_by.py b/src/gitpod/types/credit_usage_export_group_by.py new file mode 100644 index 00000000..a370c4e6 --- /dev/null +++ b/src/gitpod/types/credit_usage_export_group_by.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CreditUsageExportGroupBy"] + +CreditUsageExportGroupBy: TypeAlias = Literal[ + "CREDIT_USAGE_EXPORT_GROUP_BY_UNSPECIFIED", + "CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY", + "CREDIT_USAGE_EXPORT_GROUP_BY_RESOURCE", +] diff --git a/src/gitpod/types/credit_usage_report_filter_param.py b/src/gitpod/types/credit_usage_report_filter_param.py new file mode 100644 index 00000000..fd8ed90b --- /dev/null +++ b/src/gitpod/types/credit_usage_report_filter_param.py @@ -0,0 +1,36 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +from .shared_params.subject import Subject + +__all__ = ["CreditUsageReportFilterParam"] + + +class CreditUsageReportFilterParam(TypedDict, total=False): + """ + CreditUsageReportFilter narrows the data returned by GetCreditUsageReport. + Wrapping filters in a message (rather than adding bare fields) lets future + filters (team, environment, resource kind) be added without further breaking + changes. + """ + + subject: Optional[Subject] + """Restrict the per-user breakdown to a single subject. + + The subject must be PRINCIPAL_USER or PRINCIPAL_SERVICE_ACCOUNT and belong to + the request's organization. When unset, the report returns the default top-N + users + "Others" breakdown. + + When this field is set: + + - daily_usage[*].user_usage contains rows only for the requested subject; no + "Others" aggregation bucket is produced. + - daily_usage[*].org_usage, team_usage, environment_usage, and + conversation_usage are omitted (empty). Callers that need those sections + should issue an unfiltered call. + - period_start and updated_at remain populated. + """ diff --git a/src/gitpod/types/credits_by_type.py b/src/gitpod/types/credits_by_type.py new file mode 100644 index 00000000..53100f22 --- /dev/null +++ b/src/gitpod/types/credits_by_type.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .usage_type import UsageType + +__all__ = ["CreditsByType"] + + +class CreditsByType(BaseModel): + """CreditsByType contains credits consumed for a single usage type.""" + + credits: Optional[float] = None + + usage_type: Optional[UsageType] = FieldInfo(alias="usageType", default=None) + """UsageType identifies the category of usage.""" diff --git a/src/gitpod/types/cumulative_credit_usage.py b/src/gitpod/types/cumulative_credit_usage.py new file mode 100644 index 00000000..5dc5c00a --- /dev/null +++ b/src/gitpod/types/cumulative_credit_usage.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType + +__all__ = ["CumulativeCreditUsage"] + + +class CumulativeCreditUsage(BaseModel): + """CumulativeCreditUsage contains cumulative credit consumption totals.""" + + total_credits: Optional[float] = FieldInfo(alias="totalCredits", default=None) + """Total credits consumed.""" + + usage_by_type: Optional[List[CreditsByType]] = FieldInfo(alias="usageByType", default=None) + """Credits consumed broken down by usage type.""" diff --git a/src/gitpod/types/daily_credit_usage.py b/src/gitpod/types/daily_credit_usage.py new file mode 100644 index 00000000..3248fc28 --- /dev/null +++ b/src/gitpod/types/daily_credit_usage.py @@ -0,0 +1,50 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType +from .team_credit_usage import TeamCreditUsage +from .user_credit_usage import UserCreditUsage +from .environment_credit_usage import EnvironmentCreditUsage +from .agent_execution_credit_usage import AgentExecutionCreditUsage +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel + +__all__ = ["DailyCreditUsage"] + + +class DailyCreditUsage(BaseModel): + """DailyCreditUsage contains credit usage for a single day.""" + + conversation_usage: Optional[List[AgentExecutionCreditUsage]] = FieldInfo(alias="conversationUsage", default=None) + """ + Per-agent-execution usage for this day (top conversations + "Others"). Empty + agent_execution_id represents the "Others" aggregation bucket. + """ + + date: Optional[datetime] = None + """Start of the day (midnight in the requested timezone).""" + + environment_usage: Optional[List[EnvironmentCreditUsage]] = FieldInfo(alias="environmentUsage", default=None) + """ + Per-environment usage for this day (top environments + "Others"). Empty + environment_id represents the "Others" aggregation bucket. + """ + + org_usage: Optional[List[CreditsByType]] = FieldInfo(alias="orgUsage", default=None) + """Org-wide usage broken down by type.""" + + team_usage: Optional[List[TeamCreditUsage]] = FieldInfo(alias="teamUsage", default=None) + """ + Per-team usage for this day (top teams + "Others"). Empty team_id represents the + "Others" aggregation bucket. + """ + + usage_by_model: Optional[List[EnterpriseAIUsageByModel]] = FieldInfo(alias="usageByModel", default=None) + """Org-wide intelligence usage broken down by model.""" + + user_usage: Optional[List[UserCreditUsage]] = FieldInfo(alias="userUsage", default=None) + """Per-user usage for this day (top users + "Others").""" diff --git a/src/gitpod/types/daily_enterprise_ai_usage.py b/src/gitpod/types/daily_enterprise_ai_usage.py new file mode 100644 index 00000000..d69c435e --- /dev/null +++ b/src/gitpod/types/daily_enterprise_ai_usage.py @@ -0,0 +1,124 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage +from .team_enterprise_ai_usage import TeamEnterpriseAIUsage +from .user_enterprise_ai_usage import UserEnterpriseAIUsage +from .enterprise_ai_usage_budget import EnterpriseAIUsageBudget +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel + +__all__ = ["DailyEnterpriseAIUsage"] + + +class DailyEnterpriseAIUsage(BaseModel): + date: datetime + """ + A Timestamp represents a point in time independent of any time zone or local + calendar, encoded as a count of seconds and fractions of seconds at nanosecond + resolution. The count is relative to an epoch at UTC midnight on January 1, + 1970, in the proleptic Gregorian calendar which extends the Gregorian calendar + backwards to year one. + + All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + second table is needed for interpretation, using a + [24-hour linear smear](https://developers.google.com/time/smear). + + The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + restricting to that range, we ensure that we can convert to and from + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. + + # Examples + + Example 1: Compute Timestamp from POSIX `time()`. + + Timestamp timestamp; + timestamp.set_seconds(time(NULL)); + timestamp.set_nanos(0); + + Example 2: Compute Timestamp from POSIX `gettimeofday()`. + + struct timeval tv; + gettimeofday(&tv, NULL); + + Timestamp timestamp; + timestamp.set_seconds(tv.tv_sec); + timestamp.set_nanos(tv.tv_usec * 1000); + + Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. + + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + + // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z + // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. + Timestamp timestamp; + timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); + timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); + + Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. + + long millis = System.currentTimeMillis(); + + Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) + .setNanos((int) ((millis % 1000) * 1000000)).build(); + + Example 5: Compute Timestamp from Java `Instant.now()`. + + Instant now = Instant.now(); + + Timestamp timestamp = + Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + .setNanos(now.getNano()).build(); + + Example 6: Compute Timestamp from current time in Python. + + timestamp = Timestamp() + timestamp.GetCurrentTime() + + # JSON Mapping + + In JSON format, the Timestamp type is encoded as a string in the + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the format is + "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always + expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are + zero-padded to two digits each. The fractional seconds, which can go up to 9 + digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix + indicates the timezone ("UTC"); the timezone is required. A proto3 JSON + serializer should always use UTC (as indicated by "Z") when printing the + Timestamp type and a proto3 JSON parser should be able to accept both UTC and + other timezones (as indicated by an offset). + + For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on + January 15, 2017. + + In JavaScript, one can convert a Date object to this format using the standard + [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + method. In Python, a standard `datetime.datetime` object can be converted to + this format using + [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with the + time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the + Joda Time's + [`ISODateTimeFormat.dateTime()`]() + to obtain a formatter capable of generating timestamps in this format. + """ + + budget: Optional[EnterpriseAIUsageBudget] = None + """budget is unset when no monthly budget applies to the organization.""" + + team_usage: Optional[List[TeamEnterpriseAIUsage]] = FieldInfo(alias="teamUsage", default=None) + + usage: Optional[EnterpriseAIUsage] = None + + usage_by_model: Optional[List[EnterpriseAIUsageByModel]] = FieldInfo(alias="usageByModel", default=None) + """Usage for this day broken down by model. + + When the request filters by subject, contains only that subject's model usage. + """ + + user_usage: Optional[List[UserEnterpriseAIUsage]] = FieldInfo(alias="userUsage", default=None) diff --git a/src/gitpod/types/enterprise_ai_token_usage.py b/src/gitpod/types/enterprise_ai_token_usage.py new file mode 100644 index 00000000..a00854cf --- /dev/null +++ b/src/gitpod/types/enterprise_ai_token_usage.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["EnterpriseAITokenUsage"] + + +class EnterpriseAITokenUsage(BaseModel): + cache_tokens: Optional[str] = FieldInfo(alias="cacheTokens", default=None) + + input_tokens: Optional[str] = FieldInfo(alias="inputTokens", default=None) + + output_tokens: Optional[str] = FieldInfo(alias="outputTokens", default=None) + + total_tokens: Optional[str] = FieldInfo(alias="totalTokens", default=None) diff --git a/src/gitpod/types/enterprise_ai_usage.py b/src/gitpod/types/enterprise_ai_usage.py new file mode 100644 index 00000000..70618de5 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .billing_currency import BillingCurrency +from .enterprise_ai_token_usage import EnterpriseAITokenUsage + +__all__ = ["EnterpriseAIUsage"] + + +class EnterpriseAIUsage(BaseModel): + cost_microunits: Optional[str] = FieldInfo(alias="costMicrounits", default=None) + + credits: Optional[float] = None + + currency: Optional[BillingCurrency] = None + + tokens: Optional[EnterpriseAITokenUsage] = None diff --git a/src/gitpod/types/enterprise_ai_usage_budget.py b/src/gitpod/types/enterprise_ai_usage_budget.py new file mode 100644 index 00000000..70f4fdd5 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage_budget.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .billing_currency import BillingCurrency +from .enterprise_ai_usage import EnterpriseAIUsage +from .enterprise_ai_usage_budget_source import EnterpriseAIUsageBudgetSource + +__all__ = ["EnterpriseAIUsageBudget"] + + +class EnterpriseAIUsageBudget(BaseModel): + currency: Optional[BillingCurrency] = None + + monthly_cost_limit_microunits: Optional[str] = FieldInfo(alias="monthlyCostLimitMicrounits", default=None) + + monthly_credit_limit: Optional[str] = FieldInfo(alias="monthlyCreditLimit", default=None) + + month_to_date_usage: Optional[EnterpriseAIUsage] = FieldInfo(alias="monthToDateUsage", default=None) + + source: Optional[EnterpriseAIUsageBudgetSource] = None + + utilization_percent: Optional[float] = FieldInfo(alias="utilizationPercent", default=None) diff --git a/src/gitpod/types/enterprise_ai_usage_budget_source.py b/src/gitpod/types/enterprise_ai_usage_budget_source.py new file mode 100644 index 00000000..2c35d283 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage_budget_source.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["EnterpriseAIUsageBudgetSource"] + +EnterpriseAIUsageBudgetSource: TypeAlias = Literal[ + "ENTERPRISE_AI_USAGE_BUDGET_SOURCE_UNSPECIFIED", + "ENTERPRISE_AI_USAGE_BUDGET_SOURCE_ORGANIZATION", + "ENTERPRISE_AI_USAGE_BUDGET_SOURCE_TEAM", +] diff --git a/src/gitpod/types/enterprise_ai_usage_by_model.py b/src/gitpod/types/enterprise_ai_usage_by_model.py new file mode 100644 index 00000000..4e3182b9 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage_by_model.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage +from .enterprise_ai_usage_by_token_type import EnterpriseAIUsageByTokenType + +__all__ = ["EnterpriseAIUsageByModel"] + + +class EnterpriseAIUsageByModel(BaseModel): + model: Optional[str] = None + + unpriced_usage: Optional[EnterpriseAIUsage] = FieldInfo(alias="unpricedUsage", default=None) + """Usage excluded from spend because no matching BYOK rate was configured.""" + + unpriced_usage_by_token_type: Optional[List[EnterpriseAIUsageByTokenType]] = FieldInfo( + alias="unpricedUsageByTokenType", default=None + ) + + usage: Optional[EnterpriseAIUsage] = None + + usage_by_token_type: Optional[List[EnterpriseAIUsageByTokenType]] = FieldInfo( + alias="usageByTokenType", default=None + ) diff --git a/src/gitpod/types/enterprise_ai_usage_by_token_type.py b/src/gitpod/types/enterprise_ai_usage_by_token_type.py new file mode 100644 index 00000000..5adb9de0 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage_by_token_type.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage +from .byok_rate_card_token_type import ByokRateCardTokenType + +__all__ = ["EnterpriseAIUsageByTokenType"] + + +class EnterpriseAIUsageByTokenType(BaseModel): + token_type: Optional[ByokRateCardTokenType] = FieldInfo(alias="tokenType", default=None) + + usage: Optional[EnterpriseAIUsage] = None diff --git a/src/gitpod/types/enterprise_ai_usage_time_series_filter_param.py b/src/gitpod/types/enterprise_ai_usage_time_series_filter_param.py new file mode 100644 index 00000000..9aee6f31 --- /dev/null +++ b/src/gitpod/types/enterprise_ai_usage_time_series_filter_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +from .shared_params.subject import Subject + +__all__ = ["EnterpriseAIUsageTimeSeriesFilterParam"] + + +class EnterpriseAIUsageTimeSeriesFilterParam(TypedDict, total=False): + subject: Optional[Subject] + """Restrict the per-user breakdown to a single subject.""" diff --git a/src/gitpod/types/enterprise_ai_user_budget_policy_source.py b/src/gitpod/types/enterprise_ai_user_budget_policy_source.py new file mode 100644 index 00000000..ddf3f42b --- /dev/null +++ b/src/gitpod/types/enterprise_ai_user_budget_policy_source.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["EnterpriseAIUserBudgetPolicySource"] + +EnterpriseAIUserBudgetPolicySource: TypeAlias = Literal[ + "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_UNSPECIFIED", + "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_NONE", + "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_ORGANIZATION", + "ENTERPRISE_AI_USER_BUDGET_POLICY_SOURCE_USER", +] diff --git a/src/gitpod/types/environment_credit_usage.py b/src/gitpod/types/environment_credit_usage.py new file mode 100644 index 00000000..51331dd6 --- /dev/null +++ b/src/gitpod/types/environment_credit_usage.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType + +__all__ = ["EnvironmentCreditUsage"] + + +class EnvironmentCreditUsage(BaseModel): + """ + EnvironmentCreditUsage contains a single environment's credit usage for a day, broken down by type. + """ + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + environment_id: Optional[str] = FieldInfo(alias="environmentId", default=None) + """Empty when representing the "Others" aggregation bucket.""" + + usage: Optional[List[CreditsByType]] = None diff --git a/src/gitpod/types/environment_role.py b/src/gitpod/types/environment_role.py index 2dd22df2..8dead9fc 100644 --- a/src/gitpod/types/environment_role.py +++ b/src/gitpod/types/environment_role.py @@ -5,5 +5,9 @@ __all__ = ["EnvironmentRole"] EnvironmentRole: TypeAlias = Literal[ - "ENVIRONMENT_ROLE_UNSPECIFIED", "ENVIRONMENT_ROLE_DEFAULT", "ENVIRONMENT_ROLE_PREBUILD", "ENVIRONMENT_ROLE_WORKFLOW" + "ENVIRONMENT_ROLE_UNSPECIFIED", + "ENVIRONMENT_ROLE_DEFAULT", + "ENVIRONMENT_ROLE_PREBUILD", + "ENVIRONMENT_ROLE_WORKFLOW", + "ENVIRONMENT_ROLE_BASE_SNAPSHOT_BUILD", ] diff --git a/src/gitpod/types/environment_spec.py b/src/gitpod/types/environment_spec.py index 798637b0..3118aa0e 100644 --- a/src/gitpod/types/environment_spec.py +++ b/src/gitpod/types/environment_spec.py @@ -144,12 +144,6 @@ class SecretCredentialProxy(BaseModel): as a git credential) and proxied at the same time. """ - format: Optional[Literal["FORMAT_UNSPECIFIED", "FORMAT_PLAIN", "FORMAT_BASE64"]] = None - """format describes how the secret value is encoded. - - The proxy uses this to decode the value before injecting it into the header. - """ - header: Optional[str] = None """header is the HTTP header name to inject (e.g. "Authorization").""" diff --git a/src/gitpod/types/environment_spec_param.py b/src/gitpod/types/environment_spec_param.py index 783a9330..dfad7957 100644 --- a/src/gitpod/types/environment_spec_param.py +++ b/src/gitpod/types/environment_spec_param.py @@ -152,12 +152,6 @@ class SecretCredentialProxy(TypedDict, total=False): as a git credential) and proxied at the same time. """ - format: Literal["FORMAT_UNSPECIFIED", "FORMAT_PLAIN", "FORMAT_BASE64"] - """format describes how the secret value is encoded. - - The proxy uses this to decode the value before injecting it into the header. - """ - header: str """header is the HTTP header name to inject (e.g. "Authorization").""" diff --git a/src/gitpod/types/environment_status.py b/src/gitpod/types/environment_status.py index 45ad12ca..d5ed5c65 100644 --- a/src/gitpod/types/environment_status.py +++ b/src/gitpod/types/environment_status.py @@ -91,6 +91,12 @@ class ContentGitChangedFile(BaseModel): ] = FieldInfo(alias="changeType", default=None) """ChangeType is the type of change that happened to the file""" + old_path: Optional[str] = FieldInfo(alias="oldPath", default=None) + """ + old_path is the previous path of the file before a rename or copy. Only set when + change_type is RENAMED or COPIED. + """ + path: Optional[str] = None """path is the path of the file""" diff --git a/src/gitpod/types/environments/automations/service_spec.py b/src/gitpod/types/environments/automations/service_spec.py index 98b9b1f6..4f451cd8 100644 --- a/src/gitpod/types/environments/automations/service_spec.py +++ b/src/gitpod/types/environments/automations/service_spec.py @@ -62,6 +62,12 @@ class ServiceSpec(BaseModel): env: Optional[List[EnvironmentVariableItem]] = None """env specifies environment variables for the service.""" + readiness_timeout: Optional[str] = FieldInfo(alias="readinessTimeout", default=None) + """ + readiness_timeout is the maximum duration a service may remain in the Starting + phase while readiness checks run. 0s disables the timeout. + """ + runs_on: Optional[RunsOn] = FieldInfo(alias="runsOn", default=None) """runs_on specifies the environment the service should run on.""" diff --git a/src/gitpod/types/environments/automations/service_spec_param.py b/src/gitpod/types/environments/automations/service_spec_param.py index 93bed6a8..dc93d720 100644 --- a/src/gitpod/types/environments/automations/service_spec_param.py +++ b/src/gitpod/types/environments/automations/service_spec_param.py @@ -63,6 +63,12 @@ class ServiceSpecParam(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] """env specifies environment variables for the service.""" + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + readiness_timeout is the maximum duration a service may remain in the Starting + phase while readiness checks run. 0s disables the timeout. + """ + runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] """runs_on specifies the environment the service should run on.""" diff --git a/src/gitpod/types/environments/automations/service_update_params.py b/src/gitpod/types/environments/automations/service_update_params.py index 7ec0e436..bbcef01e 100644 --- a/src/gitpod/types/environments/automations/service_update_params.py +++ b/src/gitpod/types/environments/automations/service_update_params.py @@ -69,6 +69,67 @@ class Spec(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + A Duration represents a signed, fixed-length span of time represented as a count + of seconds and fractions of seconds at nanosecond resolution. It is independent + of any calendar and concepts like "day" or "month". It is related to Timestamp + in that the difference between two Timestamp values is a Duration and it can be + added or subtracted from a Timestamp. Range is approximately +-10,000 years. + + # Examples + + Example 1: Compute Duration from two Timestamps in pseudo code. + + Timestamp start = ...; + Timestamp end = ...; + Duration duration = ...; + + duration.seconds = end.seconds - start.seconds; + duration.nanos = end.nanos - start.nanos; + + if (duration.seconds < 0 && duration.nanos > 0) { + duration.seconds += 1; + duration.nanos -= 1000000000; + } else if (duration.seconds > 0 && duration.nanos < 0) { + duration.seconds -= 1; + duration.nanos += 1000000000; + } + + Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. + + Timestamp start = ...; + Duration duration = ...; + Timestamp end = ...; + + end.seconds = start.seconds + duration.seconds; + end.nanos = start.nanos + duration.nanos; + + if (end.nanos < 0) { + end.seconds -= 1; + end.nanos += 1000000000; + } else if (end.nanos >= 1000000000) { + end.seconds += 1; + end.nanos -= 1000000000; + } + + Example 3: Compute Duration from datetime.timedelta in Python. + + td = datetime.timedelta(days=3, minutes=10) + duration = Duration() + duration.FromTimedelta(td) + + # JSON Mapping + + In JSON format, the Duration type is encoded as a string rather than an object, + where the string ends in the suffix "s" (indicating seconds) and is preceded by + the number of seconds, with nanoseconds expressed as fractional seconds. For + example, 3 seconds with 0 nanoseconds should be encoded in JSON format as "3s", + while 3 seconds and 1 nanosecond should be expressed in JSON format as + "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON + format as "3.000001s". + """ + runs_on: Annotated[Optional[RunsOn], PropertyInfo(alias="runsOn")] diff --git a/src/gitpod/types/environments/automations/task_update_params.py b/src/gitpod/types/environments/automations/task_update_params.py index 10f30ca2..6a7555a9 100644 --- a/src/gitpod/types/environments/automations/task_update_params.py +++ b/src/gitpod/types/environments/automations/task_update_params.py @@ -42,4 +42,6 @@ class Spec(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] + prebuild_requires_success: Annotated[Optional[bool], PropertyInfo(alias="prebuildRequiresSuccess")] + runs_on: Annotated[Optional[RunsOn], PropertyInfo(alias="runsOn")] diff --git a/src/gitpod/types/environments/automations_file_param.py b/src/gitpod/types/environments/automations_file_param.py index 226782ce..eeda8859 100644 --- a/src/gitpod/types/environments/automations_file_param.py +++ b/src/gitpod/types/environments/automations_file_param.py @@ -49,12 +49,74 @@ class Services(TypedDict, total=False): name: str + readiness_timeout: Annotated[str, PropertyInfo(alias="readinessTimeout")] + """ + A Duration represents a signed, fixed-length span of time represented as a count + of seconds and fractions of seconds at nanosecond resolution. It is independent + of any calendar and concepts like "day" or "month". It is related to Timestamp + in that the difference between two Timestamp values is a Duration and it can be + added or subtracted from a Timestamp. Range is approximately +-10,000 years. + + # Examples + + Example 1: Compute Duration from two Timestamps in pseudo code. + + Timestamp start = ...; + Timestamp end = ...; + Duration duration = ...; + + duration.seconds = end.seconds - start.seconds; + duration.nanos = end.nanos - start.nanos; + + if (duration.seconds < 0 && duration.nanos > 0) { + duration.seconds += 1; + duration.nanos -= 1000000000; + } else if (duration.seconds > 0 && duration.nanos < 0) { + duration.seconds -= 1; + duration.nanos += 1000000000; + } + + Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. + + Timestamp start = ...; + Duration duration = ...; + Timestamp end = ...; + + end.seconds = start.seconds + duration.seconds; + end.nanos = start.nanos + duration.nanos; + + if (end.nanos < 0) { + end.seconds -= 1; + end.nanos += 1000000000; + } else if (end.nanos >= 1000000000) { + end.seconds += 1; + end.nanos -= 1000000000; + } + + Example 3: Compute Duration from datetime.timedelta in Python. + + td = datetime.timedelta(days=3, minutes=10) + duration = Duration() + duration.FromTimedelta(td) + + # JSON Mapping + + In JSON format, the Duration type is encoded as a string rather than an object, + where the string ends in the suffix "s" (indicating seconds) and is preceded by + the number of seconds, with nanoseconds expressed as fractional seconds. For + example, 3 seconds with 0 nanoseconds should be encoded in JSON format as "3s", + while 3 seconds and 1 nanosecond should be expressed in JSON format as + "3.000000001s", and 3 seconds and 1 microsecond should be expressed in JSON + format as "3.000001s". + """ + role: Literal["", "default", "editor", "ai-agent"] runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] triggered_by: Annotated[ - List[Literal["manual", "postEnvironmentStart", "postDevcontainerStart"]], PropertyInfo(alias="triggeredBy") + List[Literal["manual", "postEnvironmentStart", "postDevcontainerStart", "prebuild"]], + PropertyInfo(alias="triggeredBy"), ] @@ -67,6 +129,14 @@ class Tasks(TypedDict, total=False): name: str + prebuild_requires_success: Annotated[bool, PropertyInfo(alias="prebuildRequiresSuccess")] + """ + prebuild_requires_success controls whether a non-successful outcome of this task + should fail the prebuild. When true and the task is triggered by a prebuild + trigger, any terminal phase other than SUCCEEDED will cause the prebuild to + fail. Defaults to false. + """ + runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] triggered_by: Annotated[ diff --git a/src/gitpod/types/error_event_param.py b/src/gitpod/types/error_event_param.py deleted file mode 100644 index 5b909e4c..00000000 --- a/src/gitpod/types/error_event_param.py +++ /dev/null @@ -1,74 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict, Union, Iterable -from datetime import datetime -from typing_extensions import Annotated, TypedDict - -from .._types import SequenceNotStr -from .._utils import PropertyInfo -from .error_level import ErrorLevel -from .breadcrumb_param import BreadcrumbParam -from .request_info_param import RequestInfoParam -from .exception_info_param import ExceptionInfoParam - -__all__ = ["ErrorEventParam"] - - -class ErrorEventParam(TypedDict, total=False): - """ErrorEvent contains comprehensive error information (Sentry-compatible)""" - - breadcrumbs: Iterable[BreadcrumbParam] - """Breadcrumbs leading up to the error""" - - environment: str - """Environment (e.g., "production", "staging", "development")""" - - event_id: Annotated[str, PropertyInfo(alias="eventId")] - """Unique event identifier (required by Sentry)""" - - exceptions: Iterable[ExceptionInfoParam] - """Exception information (primary error data)""" - - extra: Dict[str, str] - """Additional arbitrary metadata""" - - fingerprint: SequenceNotStr[str] - """Custom fingerprint for grouping""" - - identity_id: Annotated[str, PropertyInfo(alias="identityId")] - """Identity ID of the user (UUID)""" - - level: ErrorLevel - """Error severity level""" - - logger: str - """Logger name""" - - modules: Dict[str, str] - """Modules/dependencies information""" - - platform: str - """Platform identifier (required by Sentry)""" - - release: str - """Release version""" - - request: RequestInfoParam - """Request information""" - - sdk: Dict[str, str] - """SDK information""" - - server_name: Annotated[str, PropertyInfo(alias="serverName")] - """Server/host name""" - - tags: Dict[str, str] - """Tags for filtering and grouping""" - - timestamp: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")] - """When the event occurred (required by Sentry)""" - - transaction: str - """Transaction name (e.g., route name, function name)""" diff --git a/src/gitpod/types/error_level.py b/src/gitpod/types/error_level.py deleted file mode 100644 index 573d3f85..00000000 --- a/src/gitpod/types/error_level.py +++ /dev/null @@ -1,14 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from typing_extensions import Literal, TypeAlias - -__all__ = ["ErrorLevel"] - -ErrorLevel: TypeAlias = Literal[ - "ERROR_LEVEL_UNSPECIFIED", - "ERROR_LEVEL_DEBUG", - "ERROR_LEVEL_INFO", - "ERROR_LEVEL_WARNING", - "ERROR_LEVEL_ERROR", - "ERROR_LEVEL_FATAL", -] diff --git a/src/gitpod/types/error_report_errors_params.py b/src/gitpod/types/error_report_errors_params.py deleted file mode 100644 index 6aa61989..00000000 --- a/src/gitpod/types/error_report_errors_params.py +++ /dev/null @@ -1,15 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import TypedDict - -from .error_event_param import ErrorEventParam - -__all__ = ["ErrorReportErrorsParams"] - - -class ErrorReportErrorsParams(TypedDict, total=False): - events: Iterable[ErrorEventParam] - """Error events to be reported (batch) - now using Sentry-compatible structure""" diff --git a/src/gitpod/types/event_list_response.py b/src/gitpod/types/event_list_response.py index a5d723d3..91aa3f77 100644 --- a/src/gitpod/types/event_list_response.py +++ b/src/gitpod/types/event_list_response.py @@ -2,6 +2,7 @@ from typing import Optional from datetime import datetime +from typing_extensions import Literal from pydantic import Field as FieldInfo @@ -113,6 +114,21 @@ class EventListResponse(BaseModel): to obtain a formatter capable of generating timestamps in this format. """ + kind: Optional[ + Literal[ + "AUDIT_LOG_ENTRY_KIND_UNSPECIFIED", + "AUDIT_LOG_ENTRY_KIND_AGENT_SECURITY_EXEC_BLOCKED", + "AUDIT_LOG_ENTRY_KIND_AGENT_SECURITY_EXEC_AUDITED", + "AUDIT_LOG_ENTRY_KIND_RESOURCE_CHANGE", + "AUDIT_LOG_ENTRY_KIND_CREDENTIAL_ACCESS", + "AUDIT_LOG_ENTRY_KIND_ENVIRONMENT_VETO", + ] + ] = None + """ + AuditLogEntryKind identifies the coarse query and rendering family of an + audit-log entry. + """ + subject_id: Optional[str] = FieldInfo(alias="subjectId", default=None) subject_type: Optional[ResourceType] = FieldInfo(alias="subjectType", default=None) diff --git a/src/gitpod/types/event_retrieve_params.py b/src/gitpod/types/event_retrieve_params.py new file mode 100644 index 00000000..eec88f8e --- /dev/null +++ b/src/gitpod/types/event_retrieve_params.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["EventRetrieveParams"] + + +class EventRetrieveParams(TypedDict, total=False): + audit_log_entry_id: Required[Annotated[str, PropertyInfo(alias="auditLogEntryId")]] + """audit_log_entry_id is the ID of the audit-log entry to retrieve.""" diff --git a/src/gitpod/types/event_retrieve_response.py b/src/gitpod/types/event_retrieve_response.py new file mode 100644 index 00000000..380669c8 --- /dev/null +++ b/src/gitpod/types/event_retrieve_response.py @@ -0,0 +1,148 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .shared.principal import Principal +from .shared.resource_type import ResourceType +from .audit_log_entry_details import AuditLogEntryDetails + +__all__ = ["EventRetrieveResponse", "Entry"] + + +class Entry(BaseModel): + """entry contains the common audit-log fields also returned by ListAuditLogs.""" + + id: Optional[str] = None + + action: Optional[str] = None + + actor_id: Optional[str] = FieldInfo(alias="actorId", default=None) + + actor_principal: Optional[Principal] = FieldInfo(alias="actorPrincipal", default=None) + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + """ + A Timestamp represents a point in time independent of any time zone or local + calendar, encoded as a count of seconds and fractions of seconds at nanosecond + resolution. The count is relative to an epoch at UTC midnight on January 1, + 1970, in the proleptic Gregorian calendar which extends the Gregorian calendar + backwards to year one. + + All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + second table is needed for interpretation, using a + [24-hour linear smear](https://developers.google.com/time/smear). + + The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + restricting to that range, we ensure that we can convert to and from + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. + + # Examples + + Example 1: Compute Timestamp from POSIX `time()`. + + Timestamp timestamp; + timestamp.set_seconds(time(NULL)); + timestamp.set_nanos(0); + + Example 2: Compute Timestamp from POSIX `gettimeofday()`. + + struct timeval tv; + gettimeofday(&tv, NULL); + + Timestamp timestamp; + timestamp.set_seconds(tv.tv_sec); + timestamp.set_nanos(tv.tv_usec * 1000); + + Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. + + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + + // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z + // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. + Timestamp timestamp; + timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); + timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); + + Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. + + long millis = System.currentTimeMillis(); + + Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) + .setNanos((int) ((millis % 1000) * 1000000)).build(); + + Example 5: Compute Timestamp from Java `Instant.now()`. + + Instant now = Instant.now(); + + Timestamp timestamp = + Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + .setNanos(now.getNano()).build(); + + Example 6: Compute Timestamp from current time in Python. + + timestamp = Timestamp() + timestamp.GetCurrentTime() + + # JSON Mapping + + In JSON format, the Timestamp type is encoded as a string in the + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the format is + "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always + expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are + zero-padded to two digits each. The fractional seconds, which can go up to 9 + digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix + indicates the timezone ("UTC"); the timezone is required. A proto3 JSON + serializer should always use UTC (as indicated by "Z") when printing the + Timestamp type and a proto3 JSON parser should be able to accept both UTC and + other timezones (as indicated by an offset). + + For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on + January 15, 2017. + + In JavaScript, one can convert a Date object to this format using the standard + [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + method. In Python, a standard `datetime.datetime` object can be converted to + this format using + [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with the + time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the + Joda Time's + [`ISODateTimeFormat.dateTime()`]() + to obtain a formatter capable of generating timestamps in this format. + """ + + kind: Optional[ + Literal[ + "AUDIT_LOG_ENTRY_KIND_UNSPECIFIED", + "AUDIT_LOG_ENTRY_KIND_AGENT_SECURITY_EXEC_BLOCKED", + "AUDIT_LOG_ENTRY_KIND_AGENT_SECURITY_EXEC_AUDITED", + "AUDIT_LOG_ENTRY_KIND_RESOURCE_CHANGE", + "AUDIT_LOG_ENTRY_KIND_CREDENTIAL_ACCESS", + "AUDIT_LOG_ENTRY_KIND_ENVIRONMENT_VETO", + ] + ] = None + """ + AuditLogEntryKind identifies the coarse query and rendering family of an + audit-log entry. + """ + + subject_id: Optional[str] = FieldInfo(alias="subjectId", default=None) + + subject_type: Optional[ResourceType] = FieldInfo(alias="subjectType", default=None) + + +class EventRetrieveResponse(BaseModel): + entry: Entry + """entry contains the common audit-log fields also returned by ListAuditLogs.""" + + details: Optional[AuditLogEntryDetails] = None + """ + details contains typed evidence captured with the audit entry. It is absent when + the entry has no supported, valid details. + """ diff --git a/src/gitpod/types/exception_info_param.py b/src/gitpod/types/exception_info_param.py deleted file mode 100644 index ee6f2291..00000000 --- a/src/gitpod/types/exception_info_param.py +++ /dev/null @@ -1,34 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Iterable -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo -from .stack_frame_param import StackFrameParam -from .exception_mechanism_param import ExceptionMechanismParam - -__all__ = ["ExceptionInfoParam"] - - -class ExceptionInfoParam(TypedDict, total=False): - """Exception information (Sentry-compatible)""" - - mechanism: ExceptionMechanismParam - """Exception mechanism""" - - module: str - """Module or package where the exception type is defined""" - - stacktrace: Iterable[StackFrameParam] - """Stack trace frames""" - - thread_id: Annotated[str, PropertyInfo(alias="threadId")] - """Thread ID if applicable""" - - type: str - """Exception type/class name""" - - value: str - """Exception message/value""" diff --git a/src/gitpod/types/exception_mechanism_param.py b/src/gitpod/types/exception_mechanism_param.py deleted file mode 100644 index 1fd017ac..00000000 --- a/src/gitpod/types/exception_mechanism_param.py +++ /dev/null @@ -1,27 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict -from typing_extensions import TypedDict - -__all__ = ["ExceptionMechanismParam"] - - -class ExceptionMechanismParam(TypedDict, total=False): - """Exception mechanism information (Sentry-compatible)""" - - data: Dict[str, str] - """Additional mechanism-specific data""" - - description: str - """Human-readable description of the mechanism""" - - handled: bool - """Whether the exception was handled by user code""" - - synthetic: bool - """Whether this is a synthetic exception (created by SDK)""" - - type: str - """Type of mechanism (e.g., "generic", "promise", "onerror")""" diff --git a/src/gitpod/types/goal_status.py b/src/gitpod/types/goal_status.py new file mode 100644 index 00000000..b5fd18f1 --- /dev/null +++ b/src/gitpod/types/goal_status.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["GoalStatus"] + +GoalStatus: TypeAlias = Literal[ + "GOAL_STATUS_UNSPECIFIED", + "GOAL_STATUS_ACTIVE", + "GOAL_STATUS_PAUSED", + "GOAL_STATUS_COMPLETED", + "GOAL_STATUS_BUDGET_EXHAUSTED", + "GOAL_STATUS_BLOCKED", + "GOAL_STATUS_USAGE_LIMITED", +] diff --git a/src/gitpod/types/organizations/__init__.py b/src/gitpod/types/organizations/__init__.py index 6787a9a4..8ceaed9c 100644 --- a/src/gitpod/types/organizations/__init__.py +++ b/src/gitpod/types/organizations/__init__.py @@ -7,6 +7,7 @@ from .provider_type import ProviderType as ProviderType from .veto_exec_policy import VetoExecPolicy as VetoExecPolicy from .sso_configuration import SSOConfiguration as SSOConfiguration +from .codex_model_policy import CodexModelPolicy as CodexModelPolicy from .scim_configuration import ScimConfiguration as ScimConfiguration from .announcement_banner import AnnouncementBanner as AnnouncementBanner from .crowd_strike_config import CrowdStrikeConfig as CrowdStrikeConfig @@ -19,10 +20,10 @@ from .custom_domain_provider import CustomDomainProvider as CustomDomainProvider from .invite_create_response import InviteCreateResponse as InviteCreateResponse from .invite_retrieve_params import InviteRetrieveParams as InviteRetrieveParams -from .kernel_controls_action import KernelControlsAction as KernelControlsAction from .policy_retrieve_params import PolicyRetrieveParams as PolicyRetrieveParams from .veto_exec_policy_param import VetoExecPolicyParam as VetoExecPolicyParam from .sso_configuration_state import SSOConfigurationState as SSOConfigurationState +from .codex_model_policy_param import CodexModelPolicyParam as CodexModelPolicyParam from .invite_retrieve_response import InviteRetrieveResponse as InviteRetrieveResponse from .policy_retrieve_response import PolicyRetrieveResponse as PolicyRetrieveResponse from .domain_verification_state import DomainVerificationState as DomainVerificationState diff --git a/src/gitpod/types/organizations/agent_policy.py b/src/gitpod/types/organizations/agent_policy.py index 28c4315a..36b4fe4f 100644 --- a/src/gitpod/types/organizations/agent_policy.py +++ b/src/gitpod/types/organizations/agent_policy.py @@ -5,7 +5,11 @@ from pydantic import Field as FieldInfo from ..._models import BaseModel +from .codex_model_policy import CodexModelPolicy +from ..shared.codex_openai_model import CodexOpenAIModel +from ..shared.codex_service_tier import CodexServiceTier from .conversation_sharing_policy import ConversationSharingPolicy +from ..shared.codex_reasoning_effort import CodexReasoningEffort __all__ = ["AgentPolicy"] @@ -31,6 +35,43 @@ class AgentPolicy(BaseModel): disabled for agents """ + allowed_agent_ids: Optional[List[str]] = FieldInfo(alias="allowedAgentIds", default=None) + """ + allowed_agent_ids contains the agent IDs users may select when the codex_rollout + feature flag is enabled. Empty means all agents are allowed. + """ + + allowed_codex_models: Optional[List[CodexOpenAIModel]] = FieldInfo(alias="allowedCodexModels", default=None) + """Deprecated: use codex_model_policy. + + This legacy allowlist cannot distinguish omitted from intentionally empty on + update requests. Empty means all Codex models are allowed. + """ + + allowed_codex_reasoning_efforts: Optional[List[CodexReasoningEffort]] = FieldInfo( + alias="allowedCodexReasoningEfforts", default=None + ) + """ + allowed_codex_reasoning_efforts contains the Codex reasoning efforts users may + select when the codex_rollout feature flag is enabled. Empty means all Codex + reasoning efforts are allowed. + """ + + allowed_codex_service_tiers: Optional[List[CodexServiceTier]] = FieldInfo( + alias="allowedCodexServiceTiers", default=None + ) + """ + allowed_codex_service_tiers contains the Codex service tiers users may select + when the codex_rollout feature flag is enabled. Empty means all Codex service + tiers are allowed. + """ + + codex_model_policy: Optional[CodexModelPolicy] = FieldInfo(alias="codexModelPolicy", default=None) + """ + codex_model_policy contains explicit per-model Codex availability states. + Missing policy or missing model entries mean allowed. + """ + conversation_sharing_policy: Optional[ConversationSharingPolicy] = FieldInfo( alias="conversationSharingPolicy", default=None ) diff --git a/src/gitpod/types/organizations/codex_model_policy.py b/src/gitpod/types/organizations/codex_model_policy.py new file mode 100644 index 00000000..e139d624 --- /dev/null +++ b/src/gitpod/types/organizations/codex_model_policy.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, Optional +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["CodexModelPolicy"] + + +class CodexModelPolicy(BaseModel): + """CodexModelPolicy controls per-model availability for Codex.""" + + api_model_states: Optional[ + Dict[ + str, + Literal[ + "CODEX_MODEL_POLICY_STATE_UNSPECIFIED", + "CODEX_MODEL_POLICY_STATE_ALLOWED", + "CODEX_MODEL_POLICY_STATE_DISABLED", + ], + ] + ] = FieldInfo(alias="modelStates", default=None) + """ + model_states maps CodexOpenAIModel enum names to explicit policy states. Missing + entries are treated as allowed. + """ diff --git a/src/gitpod/types/organizations/codex_model_policy_param.py b/src/gitpod/types/organizations/codex_model_policy_param.py new file mode 100644 index 00000000..87a308dc --- /dev/null +++ b/src/gitpod/types/organizations/codex_model_policy_param.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["CodexModelPolicyParam"] + + +class CodexModelPolicyParam(TypedDict, total=False): + """CodexModelPolicy controls per-model availability for Codex.""" + + model_states: Annotated[ + Dict[ + str, + Literal[ + "CODEX_MODEL_POLICY_STATE_UNSPECIFIED", + "CODEX_MODEL_POLICY_STATE_ALLOWED", + "CODEX_MODEL_POLICY_STATE_DISABLED", + ], + ], + PropertyInfo(alias="modelStates"), + ] + """ + model_states maps CodexOpenAIModel enum names to explicit policy states. Missing + entries are treated as allowed. + """ diff --git a/src/gitpod/types/organizations/organization_policies.py b/src/gitpod/types/organizations/organization_policies.py index 0816b40f..8f99a37a 100644 --- a/src/gitpod/types/organizations/organization_policies.py +++ b/src/gitpod/types/organizations/organization_policies.py @@ -52,6 +52,12 @@ class OrganizationPolicies(BaseModel): repo """ + disable_from_scratch: bool = FieldInfo(alias="disableFromScratch") + """ + disable_from_scratch controls whether non-admin users can create blank + environments without a Git or URL initializer. + """ + maximum_environments_per_user: str = FieldInfo(alias="maximumEnvironmentsPerUser") """ maximum_environments_per_user limits total environments (running or stopped) per @@ -96,6 +102,12 @@ class OrganizationPolicies(BaseModel): the organization, only users provisioned via SCIM can create accounts. """ + web_browser_disabled: bool = FieldInfo(alias="webBrowserDisabled") + """ + web_browser_disabled controls whether users can open the built-in web browser + from environment pages. This does not affect VS Code Browser. + """ + delete_archived_environments_after: Optional[str] = FieldInfo(alias="deleteArchivedEnvironmentsAfter", default=None) """ delete_archived_environments_after controls how long archived environments are @@ -139,5 +151,14 @@ class OrganizationPolicies(BaseModel): environments. """ + security_policy_id: Optional[str] = FieldInfo(alias="securityPolicyId", default=None) + """ + security_policy_id references the Veto Exec SecurityPolicy assigned to newly + created environments. The public GA contract accepts policies that use only + SecurityPolicy.Spec.executables. Assignment validates materializability and + rejects unsupported executable selectors or effects. If empty, new environments + have no SecurityPolicy by default. + """ + veto_exec_policy: Optional[VetoExecPolicy] = FieldInfo(alias="vetoExecPolicy", default=None) """veto_exec_policy contains the veto exec policy for environments.""" diff --git a/src/gitpod/types/organizations/policy_update_params.py b/src/gitpod/types/organizations/policy_update_params.py index e0776802..5ab015ad 100644 --- a/src/gitpod/types/organizations/policy_update_params.py +++ b/src/gitpod/types/organizations/policy_update_params.py @@ -2,13 +2,18 @@ from __future__ import annotations -from typing import Dict, Optional +from typing import Dict, List, Optional from typing_extensions import Required, Annotated, TypedDict from ..._types import SequenceNotStr from ..._utils import PropertyInfo +from ..admission_level import AdmissionLevel from .veto_exec_policy_param import VetoExecPolicyParam +from .codex_model_policy_param import CodexModelPolicyParam +from ..shared.codex_openai_model import CodexOpenAIModel +from ..shared.codex_service_tier import CodexServiceTier from .conversation_sharing_policy import ConversationSharingPolicy +from ..shared.codex_reasoning_effort import CodexReasoningEffort __all__ = [ "PolicyUpdateParams", @@ -57,6 +62,12 @@ class PolicyUpdateParams(TypedDict, total=False): is 4 weeks (2419200 seconds). """ + disable_from_scratch: Annotated[Optional[bool], PropertyInfo(alias="disableFromScratch")] + """ + disable_from_scratch controls whether non-admin users can create blank + environments without a Git or URL initializer. + """ + editor_version_restrictions: Annotated[ Dict[str, EditorVersionRestrictions], PropertyInfo(alias="editorVersionRestrictions") ] @@ -98,6 +109,14 @@ class PolicyUpdateParams(TypedDict, total=False): per user """ + max_port_admission_level: Annotated[Optional[AdmissionLevel], PropertyInfo(alias="maxPortAdmissionLevel")] + """ + max_port_admission_level caps the maximum admission level a user-opened port may + use. UNSPECIFIED means no cap (any AdmissionLevel value is allowed). System + ports (VS Code Browser, agents) are exempt. The legacy port_sharing_disabled + field, when true, takes precedence and blocks all user-initiated port sharing. + """ + members_create_projects: Annotated[Optional[bool], PropertyInfo(alias="membersCreateProjects")] """members_create_projects controls whether members can create projects""" @@ -130,13 +149,64 @@ class PolicyUpdateParams(TypedDict, total=False): security_agent_policy: Annotated[Optional[SecurityAgentPolicy], PropertyInfo(alias="securityAgentPolicy")] """security_agent_policy contains security agent configuration updates""" + security_policy_id: Annotated[Optional[str], PropertyInfo(alias="securityPolicyId")] + """ + security_policy_id assigns a Veto Exec SecurityPolicy to newly created + environments. The public GA contract accepts policies that use only + SecurityPolicy.Spec.executables. Assignment validates materializability and + rejects unsupported executable selectors or effects. Set this field to an empty + string to clear the default assignment. + """ + veto_exec_policy: Annotated[Optional[VetoExecPolicyParam], PropertyInfo(alias="vetoExecPolicy")] """veto_exec_policy contains the veto exec policy for environments.""" + web_browser_disabled: Annotated[Optional[bool], PropertyInfo(alias="webBrowserDisabled")] + """ + web_browser_disabled controls whether users can open the built-in web browser + from environment pages. This does not affect VS Code Browser. + """ + class AgentPolicy(TypedDict, total=False): """agent_policy contains agent-specific policy settings""" + allowed_agent_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="allowedAgentIds")] + """ + allowed_agent_ids contains the agent IDs users may select when the codex_rollout + feature flag is enabled. Empty means all agents are allowed. + """ + + allowed_codex_models: Annotated[List[CodexOpenAIModel], PropertyInfo(alias="allowedCodexModels")] + """Deprecated: use codex_model_policy. + + This legacy allowlist cannot distinguish omitted from intentionally empty on + update requests. Empty means all Codex models are allowed. + """ + + allowed_codex_reasoning_efforts: Annotated[ + List[CodexReasoningEffort], PropertyInfo(alias="allowedCodexReasoningEfforts") + ] + """ + allowed_codex_reasoning_efforts contains the Codex reasoning efforts users may + select when the codex_rollout feature flag is enabled. Empty means all Codex + reasoning efforts are allowed. + """ + + allowed_codex_service_tiers: Annotated[List[CodexServiceTier], PropertyInfo(alias="allowedCodexServiceTiers")] + """ + allowed_codex_service_tiers contains the Codex service tiers users may select + when the codex_rollout feature flag is enabled. Empty means all Codex service + tiers are allowed. + """ + + codex_model_policy: Annotated[CodexModelPolicyParam, PropertyInfo(alias="codexModelPolicy")] + """ + codex_model_policy contains explicit per-model Codex availability states. Omit + to leave the current model policy unchanged. Send an empty policy to clear + explicit model states. + """ + command_deny_list: Annotated[SequenceNotStr[str], PropertyInfo(alias="commandDenyList")] """ command_deny_list contains a list of commands that agents are not allowed to diff --git a/src/gitpod/types/organizations/scim_configuration.py b/src/gitpod/types/organizations/scim_configuration.py index 8b12ff05..f3879104 100644 --- a/src/gitpod/types/organizations/scim_configuration.py +++ b/src/gitpod/types/organizations/scim_configuration.py @@ -30,6 +30,15 @@ class ScimConfiguration(BaseModel): updated_at: datetime = FieldInfo(alias="updatedAt") """updated_at is when the SCIM configuration was last updated""" + allow_unverified_email_account_linking: Optional[bool] = FieldInfo( + alias="allowUnverifiedEmailAccountLinking", default=None + ) + """ + allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + """ + enabled: Optional[bool] = None """enabled indicates if SCIM provisioning is active""" diff --git a/src/gitpod/types/organizations/scim_configuration_create_params.py b/src/gitpod/types/organizations/scim_configuration_create_params.py index e8f5a2ee..225662ca 100644 --- a/src/gitpod/types/organizations/scim_configuration_create_params.py +++ b/src/gitpod/types/organizations/scim_configuration_create_params.py @@ -23,6 +23,15 @@ class ScimConfigurationCreateParams(TypedDict, total=False): provisioning) """ + allow_unverified_email_account_linking: Annotated[ + Optional[bool], PropertyInfo(alias="allowUnverifiedEmailAccountLinking") + ] + """ + allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + """ + name: Optional[str] """name is a human-readable name for the SCIM configuration""" diff --git a/src/gitpod/types/organizations/scim_configuration_update_params.py b/src/gitpod/types/organizations/scim_configuration_update_params.py index da919176..d0c0862f 100644 --- a/src/gitpod/types/organizations/scim_configuration_update_params.py +++ b/src/gitpod/types/organizations/scim_configuration_update_params.py @@ -14,6 +14,15 @@ class ScimConfigurationUpdateParams(TypedDict, total=False): scim_configuration_id: Required[Annotated[str, PropertyInfo(alias="scimConfigurationId")]] """scim_configuration_id is the ID of the SCIM configuration to update""" + allow_unverified_email_account_linking: Annotated[ + Optional[bool], PropertyInfo(alias="allowUnverifiedEmailAccountLinking") + ] + """ + allow_unverified_email_account_linking allows SCIM to link provisioned users to + existing accounts when the identity provider does not mark the email address as + verified + """ + enabled: Optional[bool] """enabled controls whether SCIM provisioning is active""" diff --git a/src/gitpod/types/organizations/veto_exec_policy.py b/src/gitpod/types/organizations/veto_exec_policy.py index 05e22cbd..1bc599e7 100644 --- a/src/gitpod/types/organizations/veto_exec_policy.py +++ b/src/gitpod/types/organizations/veto_exec_policy.py @@ -3,7 +3,7 @@ from typing import List, Optional from ..._models import BaseModel -from .kernel_controls_action import KernelControlsAction +from ..shared.kernel_controls_action import KernelControlsAction __all__ = ["VetoExecPolicy"] diff --git a/src/gitpod/types/organizations/veto_exec_policy_param.py b/src/gitpod/types/organizations/veto_exec_policy_param.py index c328c5c2..03a20812 100644 --- a/src/gitpod/types/organizations/veto_exec_policy_param.py +++ b/src/gitpod/types/organizations/veto_exec_policy_param.py @@ -5,7 +5,7 @@ from typing_extensions import TypedDict from ..._types import SequenceNotStr -from .kernel_controls_action import KernelControlsAction +from ..shared.kernel_controls_action import KernelControlsAction __all__ = ["VetoExecPolicyParam"] diff --git a/src/gitpod/types/pr_summary.py b/src/gitpod/types/pr_summary.py new file mode 100644 index 00000000..4ae37e26 --- /dev/null +++ b/src/gitpod/types/pr_summary.py @@ -0,0 +1,52 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["PrSummary"] + + +class PrSummary(BaseModel): + """PrSummary contains aggregate PR speed metrics for a date range.""" + + deployment_frequency: Optional[float] = FieldInfo(alias="deploymentFrequency", default=None) + """PRs merged to the default branch per week.""" + + deployment_frequency_trend: Optional[float] = FieldInfo(alias="deploymentFrequencyTrend", default=None) + """ + Fractional change in deployment_frequency vs previous period. Computed as + (current - previous) / previous. + """ + + lead_time_seconds: Optional[float] = FieldInfo(alias="leadTimeSeconds", default=None) + """Median lead time for changes in seconds (first commit → merge).""" + + lead_time_trend: Optional[float] = FieldInfo(alias="leadTimeTrend", default=None) + """ + Fractional change in lead_time_seconds vs previous period. Computed as + (current - previous) / previous. + """ + + prs_merged_count: Optional[str] = FieldInfo(alias="prsMergedCount", default=None) + """Total PRs merged in the date range.""" + + prs_merged_trend: Optional[float] = FieldInfo(alias="prsMergedTrend", default=None) + """ + Fractional change in prs_merged_count vs previous period. Computed as (current - + previous) / previous. + """ + + time_to_first_approval_seconds: Optional[float] = FieldInfo(alias="timeToFirstApprovalSeconds", default=None) + """ + Median time to first approval in seconds. Zero when no PRs in the range had + approvals. + """ + + time_to_first_approval_trend: Optional[float] = FieldInfo(alias="timeToFirstApprovalTrend", default=None) + """ + Fractional change in time_to_first_approval_seconds vs previous period. Computed + as (current - previous) / previous. + """ diff --git a/src/gitpod/types/pr_time_bucket.py b/src/gitpod/types/pr_time_bucket.py new file mode 100644 index 00000000..2eefacb3 --- /dev/null +++ b/src/gitpod/types/pr_time_bucket.py @@ -0,0 +1,32 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["PrTimeBucket"] + + +class PrTimeBucket(BaseModel): + """PrTimeBucket contains PR speed metrics for a single time period.""" + + deploys: Optional[str] = None + """Total number of deploys (merged PRs) in this bucket.""" + + lead_time_seconds: Optional[float] = FieldInfo(alias="leadTimeSeconds", default=None) + """Median lead time in seconds for PRs merged in this bucket.""" + + prs_merged_count: Optional[str] = FieldInfo(alias="prsMergedCount", default=None) + """Number of PRs merged in this bucket.""" + + start_time: Optional[datetime] = FieldInfo(alias="startTime", default=None) + """Start of this time bucket.""" + + time_to_first_approval_seconds: Optional[float] = FieldInfo(alias="timeToFirstApprovalSeconds", default=None) + """ + Median time to first approval in seconds for PRs in this bucket. Zero when no + PRs in the bucket had approvals. + """ diff --git a/src/gitpod/types/process.py b/src/gitpod/types/process.py new file mode 100644 index 00000000..75222167 --- /dev/null +++ b/src/gitpod/types/process.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["Process"] + + +class Process(BaseModel): + """Process describes process metadata for a security event. + + PID fields use int32 to match the kernel's pid_t (signed int). + Linux PID max is 4,194,304 (2^22), well within int32 range. + Postgres has no unsigned integer type: Ent maps uint32 to bigint + (8 bytes) while int32 maps to integer (4 bytes). Using int32 + aligns proto, Go, and Postgres types without wasting storage. + """ + + name: Optional[str] = None + """name is the process name (comm). 2x kernel TASK_COMM_LEN=16""" + + pgid: Optional[int] = None + """pgid is the process group ID.""" + + pid: Optional[int] = None + """pid is the userspace process ID (kernel thread group ID, tgid).""" + + ppid: Optional[int] = None + """ppid is the parent process ID.""" + + sid: Optional[int] = None + """sid is the session ID.""" + + started_at: Optional[datetime] = FieldInfo(alias="startedAt", default=None) + """started_at is when the process started.""" + + tid: Optional[int] = None + """tid is the userspace thread ID (kernel pid).""" diff --git a/src/gitpod/types/request_info_param.py b/src/gitpod/types/request_info_param.py deleted file mode 100644 index 8e764855..00000000 --- a/src/gitpod/types/request_info_param.py +++ /dev/null @@ -1,29 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict -from typing_extensions import Annotated, TypedDict - -from .._utils import PropertyInfo - -__all__ = ["RequestInfoParam"] - - -class RequestInfoParam(TypedDict, total=False): - """Request information (Sentry-compatible)""" - - data: str - """Request body (truncated if large)""" - - headers: Dict[str, str] - """Request headers""" - - method: str - """HTTP method""" - - query_string: Annotated[Dict[str, str], PropertyInfo(alias="queryString")] - """Query parameters""" - - url: str - """Request URL""" diff --git a/src/gitpod/types/resolution.py b/src/gitpod/types/resolution.py new file mode 100644 index 00000000..b28e212e --- /dev/null +++ b/src/gitpod/types/resolution.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["Resolution"] + +Resolution: TypeAlias = Literal[ + "RESOLUTION_UNSPECIFIED", "RESOLUTION_HOURLY", "RESOLUTION_DAILY", "RESOLUTION_WEEKLY", "RESOLUTION_MONTHLY" +] diff --git a/src/gitpod/types/runner_capability.py b/src/gitpod/types/runner_capability.py index c2e50b46..911a89a7 100644 --- a/src/gitpod/types/runner_capability.py +++ b/src/gitpod/types/runner_capability.py @@ -18,4 +18,10 @@ "RUNNER_CAPABILITY_RUNNER_SIDE_AGENT", "RUNNER_CAPABILITY_WARM_POOL", "RUNNER_CAPABILITY_ASG_WARM_POOL", + "RUNNER_CAPABILITY_PORT_AUTHENTICATION", + "RUNNER_CAPABILITY_HORIZONTAL_SCALING", + "RUNNER_CAPABILITY_AGENT_EXECUTION_CNF", + "RUNNER_CAPABILITY_REDIS_STREAM", + "RUNNER_CAPABILITY_BASE_SNAPSHOT", + "RUNNER_CAPABILITY_DYNAMIC_LLM_REQUEST_HEADERS", ] diff --git a/src/gitpod/types/runner_list_scm_organizations_params.py b/src/gitpod/types/runner_list_scm_organizations_params.py index bd1f788b..a852d57b 100644 --- a/src/gitpod/types/runner_list_scm_organizations_params.py +++ b/src/gitpod/types/runner_list_scm_organizations_params.py @@ -6,7 +6,7 @@ from .._utils import PropertyInfo -__all__ = ["RunnerListScmOrganizationsParams"] +__all__ = ["RunnerListScmOrganizationsParams", "Pagination"] class RunnerListScmOrganizationsParams(TypedDict, total=False): @@ -14,7 +14,43 @@ class RunnerListScmOrganizationsParams(TypedDict, total=False): page_size: Annotated[int, PropertyInfo(alias="pageSize")] + pagination: Pagination + """Pagination parameters. + + When unset, defaults to the standard PaginationRequest defaults (page_size 25, + max 100). Tokens are opaque and provider-specific. + """ + + query: str + """Optional substring filter applied to the organization name. + + - GitLab: forwarded to the upstream `search` parameter (server-side, + case-insensitive substring on name/path). + - GitHub and Bitbucket: not implemented as they don't support searching Empty + value means no filter. + """ + runner_id: Annotated[str, PropertyInfo(alias="runnerId")] scm_host: Annotated[str, PropertyInfo(alias="scmHost")] """The SCM host to list organizations from (e.g., "github.com", "gitlab.com")""" + + +class Pagination(TypedDict, total=False): + """Pagination parameters. + + When unset, defaults to the standard PaginationRequest defaults + (page_size 25, max 100). Tokens are opaque and provider-specific. + """ + + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ diff --git a/src/gitpod/types/runner_list_scm_organizations_response.py b/src/gitpod/types/runner_list_scm_organizations_response.py index 8e9db077..8c8c50e8 100644 --- a/src/gitpod/types/runner_list_scm_organizations_response.py +++ b/src/gitpod/types/runner_list_scm_organizations_response.py @@ -1,19 +1,24 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import List, Optional +from typing import Optional from pydantic import Field as FieldInfo from .._models import BaseModel -__all__ = ["RunnerListScmOrganizationsResponse", "Organization"] +__all__ = ["RunnerListScmOrganizationsResponse"] -class Organization(BaseModel): +class RunnerListScmOrganizationsResponse(BaseModel): is_admin: Optional[bool] = FieldInfo(alias="isAdmin", default=None) """ - Whether the user has admin permissions in this organization. Admin permissions - typically allow creating organization-level webhooks. + Deprecated: this field is unused by all known consumers and is scheduled for + removal in a future release. Do not read it. + + Originally intended to gate organization-level webhook creation in the + dashboard, but that gating was never implemented. Populating this field on the + GitLab path requires a second fully-paginated ListGroups call, which is the main + reason we are deprecating it. """ name: Optional[str] = None @@ -21,8 +26,3 @@ class Organization(BaseModel): url: Optional[str] = None """Organization URL (e.g., "https://github.com/gitpod-io")""" - - -class RunnerListScmOrganizationsResponse(BaseModel): - organizations: Optional[List[Organization]] = None - """List of organizations the user belongs to""" diff --git a/src/gitpod/types/secret.py b/src/gitpod/types/secret.py index 052d62a9..528bb970 100644 --- a/src/gitpod/types/secret.py +++ b/src/gitpod/types/secret.py @@ -1,6 +1,6 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -from typing import Optional +from typing import List, Optional from datetime import datetime from pydantic import Field as FieldInfo @@ -9,7 +9,48 @@ from .secret_scope import SecretScope from .shared.subject import Subject -__all__ = ["Secret"] +__all__ = ["Secret", "CredentialProxy", "Source", "SourceOidcJfrog"] + + +class CredentialProxy(BaseModel): + """ + credential_proxy configures transparent credential injection via the + credential proxy. When set, the credential proxy intercepts HTTPS + traffic to the target hosts and replaces the dummy mounted value with + the real value in the specified HTTP header. The real secret value is + never exposed in the environment. + This field is orthogonal to mount — a secret can be both mounted and + proxied at the same time. + """ + + header: Optional[str] = None + """header is the HTTP header name to inject (e.g. "Authorization").""" + + target_hosts: Optional[List[str]] = FieldInfo(alias="targetHosts", default=None) + """ + target_hosts lists the hostnames to intercept (for example "github.com" or + "\\**.github.com"). Wildcards are subdomain-only and do not match the apex domain. + """ + + +class SourceOidcJfrog(BaseModel): + host: Optional[str] = None + """host must be a hostname or IP address with optional port: + + ``` + this.matches("^([A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?[.])*[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(:([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$") + ``` + """ + + provider_name: Optional[str] = FieldInfo(alias="providerName", default=None) + + +class Source(BaseModel): + """Source of the secret""" + + oidc_jfrog: Optional[SourceOidcJfrog] = FieldInfo(alias="oidcJfrog", default=None) + + verbatim: Optional[bool] = None class Secret(BaseModel): @@ -116,6 +157,16 @@ class Secret(BaseModel): creator: Optional[Subject] = None """creator is the identity of the creator of the secret""" + credential_proxy: Optional[CredentialProxy] = FieldInfo(alias="credentialProxy", default=None) + """ + credential_proxy configures transparent credential injection via the credential + proxy. When set, the credential proxy intercepts HTTPS traffic to the target + hosts and replaces the dummy mounted value with the real value in the specified + HTTP header. The real secret value is never exposed in the environment. This + field is orthogonal to mount — a secret can be both mounted and proxied at the + same time. + """ + environment_variable: Optional[bool] = FieldInfo(alias="environmentVariable", default=None) """ secret will be created as an Environment Variable with the same name as the @@ -133,6 +184,9 @@ class Secret(BaseModel): scope: Optional[SecretScope] = None + source: Optional[Source] = None + """Source of the secret""" + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) """ A Timestamp represents a point in time independent of any time zone or local diff --git a/src/gitpod/types/secret_create_params.py b/src/gitpod/types/secret_create_params.py index 99e545f3..a72d473b 100644 --- a/src/gitpod/types/secret_create_params.py +++ b/src/gitpod/types/secret_create_params.py @@ -4,10 +4,11 @@ from typing_extensions import Annotated, TypedDict +from .._types import SequenceNotStr from .._utils import PropertyInfo from .secret_scope_param import SecretScopeParam -__all__ = ["SecretCreateParams"] +__all__ = ["SecretCreateParams", "CredentialProxy", "Source", "SourceOidcJfrog"] class SecretCreateParams(TypedDict, total=False): @@ -24,6 +25,16 @@ class SecretCreateParams(TypedDict, total=False): the docker registry host """ + credential_proxy: Annotated[CredentialProxy, PropertyInfo(alias="credentialProxy")] + """ + credential_proxy configures transparent credential injection when environments + materialize this secret. When set, the credential proxy intercepts HTTPS traffic + to the target hosts and replaces the dummy mounted value with the real value in + the specified HTTP header. The real secret value is never exposed in the + environment. This field is orthogonal to mount — a secret can be both mounted + and proxied at the same time. + """ + environment_variable: Annotated[bool, PropertyInfo(alias="environmentVariable")] """ secret will be created as an Environment Variable with the same name as the @@ -50,5 +61,52 @@ class SecretCreateParams(TypedDict, total=False): scope: SecretScopeParam """scope is the scope of the secret""" + source: Source + """source is the source of the secret, possibly verbatim value""" + value: str - """value is the plaintext value of the secret""" + """value is the plaintext value of the secret. + + When set, source must be unset or verbatim. + """ + + +class CredentialProxy(TypedDict, total=False): + """ + credential_proxy configures transparent credential injection when + environments materialize this secret. When set, the credential proxy + intercepts HTTPS traffic to the target hosts and replaces the dummy + mounted value with the real value in the specified HTTP header. The real + secret value is never exposed in the environment. + This field is orthogonal to mount — a secret can be both mounted and + proxied at the same time. + """ + + header: str + """header is the HTTP header name to inject (e.g. "Authorization").""" + + target_hosts: Annotated[SequenceNotStr[str], PropertyInfo(alias="targetHosts")] + """ + target_hosts lists the hostnames to intercept (for example "github.com" or + "\\**.github.com"). Wildcards are subdomain-only and do not match the apex domain. + """ + + +class SourceOidcJfrog(TypedDict, total=False): + host: str + """host must be a hostname or IP address with optional port: + + ``` + this.matches("^([A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?[.])*[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(:([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$") + ``` + """ + + provider_name: Annotated[str, PropertyInfo(alias="providerName")] + + +class Source(TypedDict, total=False): + """source is the source of the secret, possibly verbatim value""" + + oidc_jfrog: Annotated[SourceOidcJfrog, PropertyInfo(alias="oidcJfrog")] + + verbatim: bool diff --git a/src/gitpod/types/security_policy.py b/src/gitpod/types/security_policy.py new file mode 100644 index 00000000..1bbe0b7f --- /dev/null +++ b/src/gitpod/types/security_policy.py @@ -0,0 +1,260 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from pydantic import Field as FieldInfo + +from .._models import BaseModel + +__all__ = ["SecurityPolicy", "Metadata", "Spec", "SpecExecutables", "SpecExecutablesRule"] + + +class Metadata(BaseModel): + name: Optional[str] = None + + +class SpecExecutablesRule(BaseModel): + effect: Optional[Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"]] = None + """effect must be EFFECT_AUDIT or EFFECT_BLOCK. + + EFFECT_ALLOW is not supported on an executable rule. + """ + + path: Optional[str] = None + """ + path is either an absolute executable path, such as /usr/bin/curl, or a bare + executable name, such as npx. Bare names are expanded by runtime discovery. + Surrounding whitespace is ignored. Empty or whitespace-only selectors and + relative paths with directory separators are invalid. Enforcement uses + executable content hashes, so different paths with identical content share one + runtime decision and block wins conflicts. + """ + + +class SpecExecutables(BaseModel): + """executables is the public Veto Exec GA policy surface.""" + + default_effect: Optional[Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"]] = FieldInfo( + alias="defaultEffect", default=None + ) + """ + default_effect controls executables that do not match a rule. For Veto Exec, + omit this field or set it to EFFECT_ALLOW. EFFECT_UNSPECIFIED is normalized to + EFFECT_ALLOW. + """ + + rules: Optional[List[SpecExecutablesRule]] = None + """rules contains executable-specific audit or block decisions.""" + + +class Spec(BaseModel): + """Mandate/deploy security agents, e.g. + + CrowdStrike. + Mandate credential security/proxy use. + These can be modeled later as explicit fields if needed. + """ + + executables: Optional[SpecExecutables] = None + """executables is the public Veto Exec GA policy surface.""" + + +class SecurityPolicy(BaseModel): + metadata: Metadata + + spec: Spec + """Mandate/deploy security agents, e.g. + + CrowdStrike. Mandate credential security/proxy use. These can be modeled later + as explicit fields if needed. + """ + + id: Optional[str] = None + + created_at: Optional[datetime] = FieldInfo(alias="createdAt", default=None) + """ + A Timestamp represents a point in time independent of any time zone or local + calendar, encoded as a count of seconds and fractions of seconds at nanosecond + resolution. The count is relative to an epoch at UTC midnight on January 1, + 1970, in the proleptic Gregorian calendar which extends the Gregorian calendar + backwards to year one. + + All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + second table is needed for interpretation, using a + [24-hour linear smear](https://developers.google.com/time/smear). + + The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + restricting to that range, we ensure that we can convert to and from + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. + + # Examples + + Example 1: Compute Timestamp from POSIX `time()`. + + Timestamp timestamp; + timestamp.set_seconds(time(NULL)); + timestamp.set_nanos(0); + + Example 2: Compute Timestamp from POSIX `gettimeofday()`. + + struct timeval tv; + gettimeofday(&tv, NULL); + + Timestamp timestamp; + timestamp.set_seconds(tv.tv_sec); + timestamp.set_nanos(tv.tv_usec * 1000); + + Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. + + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + + // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z + // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. + Timestamp timestamp; + timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); + timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); + + Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. + + long millis = System.currentTimeMillis(); + + Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) + .setNanos((int) ((millis % 1000) * 1000000)).build(); + + Example 5: Compute Timestamp from Java `Instant.now()`. + + Instant now = Instant.now(); + + Timestamp timestamp = + Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + .setNanos(now.getNano()).build(); + + Example 6: Compute Timestamp from current time in Python. + + timestamp = Timestamp() + timestamp.GetCurrentTime() + + # JSON Mapping + + In JSON format, the Timestamp type is encoded as a string in the + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the format is + "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always + expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are + zero-padded to two digits each. The fractional seconds, which can go up to 9 + digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix + indicates the timezone ("UTC"); the timezone is required. A proto3 JSON + serializer should always use UTC (as indicated by "Z") when printing the + Timestamp type and a proto3 JSON parser should be able to accept both UTC and + other timezones (as indicated by an offset). + + For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on + January 15, 2017. + + In JavaScript, one can convert a Date object to this format using the standard + [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + method. In Python, a standard `datetime.datetime` object can be converted to + this format using + [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with the + time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the + Joda Time's + [`ISODateTimeFormat.dateTime()`]() + to obtain a formatter capable of generating timestamps in this format. + """ + + organization_id: Optional[str] = FieldInfo(alias="organizationId", default=None) + + updated_at: Optional[datetime] = FieldInfo(alias="updatedAt", default=None) + """ + A Timestamp represents a point in time independent of any time zone or local + calendar, encoded as a count of seconds and fractions of seconds at nanosecond + resolution. The count is relative to an epoch at UTC midnight on January 1, + 1970, in the proleptic Gregorian calendar which extends the Gregorian calendar + backwards to year one. + + All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + second table is needed for interpretation, using a + [24-hour linear smear](https://developers.google.com/time/smear). + + The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + restricting to that range, we ensure that we can convert to and from + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. + + # Examples + + Example 1: Compute Timestamp from POSIX `time()`. + + Timestamp timestamp; + timestamp.set_seconds(time(NULL)); + timestamp.set_nanos(0); + + Example 2: Compute Timestamp from POSIX `gettimeofday()`. + + struct timeval tv; + gettimeofday(&tv, NULL); + + Timestamp timestamp; + timestamp.set_seconds(tv.tv_sec); + timestamp.set_nanos(tv.tv_usec * 1000); + + Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. + + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + + // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z + // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. + Timestamp timestamp; + timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); + timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); + + Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. + + long millis = System.currentTimeMillis(); + + Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) + .setNanos((int) ((millis % 1000) * 1000000)).build(); + + Example 5: Compute Timestamp from Java `Instant.now()`. + + Instant now = Instant.now(); + + Timestamp timestamp = + Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + .setNanos(now.getNano()).build(); + + Example 6: Compute Timestamp from current time in Python. + + timestamp = Timestamp() + timestamp.GetCurrentTime() + + # JSON Mapping + + In JSON format, the Timestamp type is encoded as a string in the + [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the format is + "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" where {year} is always + expressed using four digits while {month}, {day}, {hour}, {min}, and {sec} are + zero-padded to two digits each. The fractional seconds, which can go up to 9 + digits (i.e. up to 1 nanosecond resolution), are optional. The "Z" suffix + indicates the timezone ("UTC"); the timezone is required. A proto3 JSON + serializer should always use UTC (as indicated by "Z") when printing the + Timestamp type and a proto3 JSON parser should be able to accept both UTC and + other timezones (as indicated by an offset). + + For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 01:30 UTC on + January 15, 2017. + + In JavaScript, one can convert a Date object to this format using the standard + [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + method. In Python, a standard `datetime.datetime` object can be converted to + this format using + [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with the + time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use the + Joda Time's + [`ISODateTimeFormat.dateTime()`]() + to obtain a formatter capable of generating timestamps in this format. + """ diff --git a/src/gitpod/types/security_policy_create_params.py b/src/gitpod/types/security_policy_create_params.py new file mode 100644 index 00000000..b633c65e --- /dev/null +++ b/src/gitpod/types/security_policy_create_params.py @@ -0,0 +1,74 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Required, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["SecurityPolicyCreateParams", "Metadata", "Spec", "SpecExecutables", "SpecExecutablesRule"] + + +class SecurityPolicyCreateParams(TypedDict, total=False): + metadata: Required[Metadata] + + spec: Required[Spec] + """Mandate/deploy security agents, e.g. + + CrowdStrike. Mandate credential security/proxy use. These can be modeled later + as explicit fields if needed. + """ + + organization_id: Annotated[str, PropertyInfo(alias="organizationId")] + + +class Metadata(TypedDict, total=False): + name: str + + +class SpecExecutablesRule(TypedDict, total=False): + effect: Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"] + """effect must be EFFECT_AUDIT or EFFECT_BLOCK. + + EFFECT_ALLOW is not supported on an executable rule. + """ + + path: str + """ + path is either an absolute executable path, such as /usr/bin/curl, or a bare + executable name, such as npx. Bare names are expanded by runtime discovery. + Surrounding whitespace is ignored. Empty or whitespace-only selectors and + relative paths with directory separators are invalid. Enforcement uses + executable content hashes, so different paths with identical content share one + runtime decision and block wins conflicts. + """ + + +class SpecExecutables(TypedDict, total=False): + """executables is the public Veto Exec GA policy surface.""" + + default_effect: Annotated[ + Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"], + PropertyInfo(alias="defaultEffect"), + ] + """ + default_effect controls executables that do not match a rule. For Veto Exec, + omit this field or set it to EFFECT_ALLOW. EFFECT_UNSPECIFIED is normalized to + EFFECT_ALLOW. + """ + + rules: Iterable[SpecExecutablesRule] + """rules contains executable-specific audit or block decisions.""" + + +class Spec(TypedDict, total=False): + """Mandate/deploy security agents, e.g. + + CrowdStrike. + Mandate credential security/proxy use. + These can be modeled later as explicit fields if needed. + """ + + executables: SpecExecutables + """executables is the public Veto Exec GA policy surface.""" diff --git a/src/gitpod/types/security_policy_create_response.py b/src/gitpod/types/security_policy_create_response.py new file mode 100644 index 00000000..c729e883 --- /dev/null +++ b/src/gitpod/types/security_policy_create_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .security_policy import SecurityPolicy + +__all__ = ["SecurityPolicyCreateResponse"] + + +class SecurityPolicyCreateResponse(BaseModel): + security_policy: SecurityPolicy = FieldInfo(alias="securityPolicy") diff --git a/src/gitpod/types/security_policy_delete_params.py b/src/gitpod/types/security_policy_delete_params.py new file mode 100644 index 00000000..ab3f14f9 --- /dev/null +++ b/src/gitpod/types/security_policy_delete_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["SecurityPolicyDeleteParams"] + + +class SecurityPolicyDeleteParams(TypedDict, total=False): + security_policy_id: Annotated[str, PropertyInfo(alias="securityPolicyId")] diff --git a/src/gitpod/types/security_policy_list_params.py b/src/gitpod/types/security_policy_list_params.py new file mode 100644 index 00000000..7920e4ea --- /dev/null +++ b/src/gitpod/types/security_policy_list_params.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._types import SequenceNotStr +from .._utils import PropertyInfo + +__all__ = ["SecurityPolicyListParams", "Filter", "Pagination"] + + +class SecurityPolicyListParams(TypedDict, total=False): + token: str + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + + filter: Filter + + pagination: Pagination + + +class Filter(TypedDict, total=False): + organization_id: Annotated[str, PropertyInfo(alias="organizationId")] + + search: str + + security_policy_ids: Annotated[SequenceNotStr[str], PropertyInfo(alias="securityPolicyIds")] + + +class Pagination(TypedDict, total=False): + token: str + """ + Token for the next set of results that was returned as next_token of a + PaginationResponse + """ + + page_size: Annotated[int, PropertyInfo(alias="pageSize")] + """Page size is the maximum number of results to retrieve per page. Defaults to 25. + + Maximum 100. + """ diff --git a/src/gitpod/types/security_policy_retrieve_params.py b/src/gitpod/types/security_policy_retrieve_params.py new file mode 100644 index 00000000..06180272 --- /dev/null +++ b/src/gitpod/types/security_policy_retrieve_params.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["SecurityPolicyRetrieveParams"] + + +class SecurityPolicyRetrieveParams(TypedDict, total=False): + security_policy_id: Annotated[str, PropertyInfo(alias="securityPolicyId")] diff --git a/src/gitpod/types/security_policy_retrieve_response.py b/src/gitpod/types/security_policy_retrieve_response.py new file mode 100644 index 00000000..c04dd713 --- /dev/null +++ b/src/gitpod/types/security_policy_retrieve_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .security_policy import SecurityPolicy + +__all__ = ["SecurityPolicyRetrieveResponse"] + + +class SecurityPolicyRetrieveResponse(BaseModel): + security_policy: SecurityPolicy = FieldInfo(alias="securityPolicy") diff --git a/src/gitpod/types/security_policy_update_params.py b/src/gitpod/types/security_policy_update_params.py new file mode 100644 index 00000000..5bb70e72 --- /dev/null +++ b/src/gitpod/types/security_policy_update_params.py @@ -0,0 +1,74 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Iterable +from typing_extensions import Literal, Annotated, TypedDict + +from .._utils import PropertyInfo + +__all__ = ["SecurityPolicyUpdateParams", "Metadata", "Spec", "SpecExecutables", "SpecExecutablesRule"] + + +class SecurityPolicyUpdateParams(TypedDict, total=False): + metadata: Metadata + + security_policy_id: Annotated[str, PropertyInfo(alias="securityPolicyId")] + + spec: Spec + """Mandate/deploy security agents, e.g. + + CrowdStrike. Mandate credential security/proxy use. These can be modeled later + as explicit fields if needed. + """ + + +class Metadata(TypedDict, total=False): + name: str + + +class SpecExecutablesRule(TypedDict, total=False): + effect: Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"] + """effect must be EFFECT_AUDIT or EFFECT_BLOCK. + + EFFECT_ALLOW is not supported on an executable rule. + """ + + path: str + """ + path is either an absolute executable path, such as /usr/bin/curl, or a bare + executable name, such as npx. Bare names are expanded by runtime discovery. + Surrounding whitespace is ignored. Empty or whitespace-only selectors and + relative paths with directory separators are invalid. Enforcement uses + executable content hashes, so different paths with identical content share one + runtime decision and block wins conflicts. + """ + + +class SpecExecutables(TypedDict, total=False): + """executables is the public Veto Exec GA policy surface.""" + + default_effect: Annotated[ + Literal["EFFECT_UNSPECIFIED", "EFFECT_ALLOW", "EFFECT_BLOCK", "EFFECT_AUDIT"], + PropertyInfo(alias="defaultEffect"), + ] + """ + default_effect controls executables that do not match a rule. For Veto Exec, + omit this field or set it to EFFECT_ALLOW. EFFECT_UNSPECIFIED is normalized to + EFFECT_ALLOW. + """ + + rules: Iterable[SpecExecutablesRule] + """rules contains executable-specific audit or block decisions.""" + + +class Spec(TypedDict, total=False): + """Mandate/deploy security agents, e.g. + + CrowdStrike. + Mandate credential security/proxy use. + These can be modeled later as explicit fields if needed. + """ + + executables: SpecExecutables + """executables is the public Veto Exec GA policy surface.""" diff --git a/src/gitpod/types/security_policy_update_response.py b/src/gitpod/types/security_policy_update_response.py new file mode 100644 index 00000000..aa0be7ae --- /dev/null +++ b/src/gitpod/types/security_policy_update_response.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .security_policy import SecurityPolicy + +__all__ = ["SecurityPolicyUpdateResponse"] + + +class SecurityPolicyUpdateResponse(BaseModel): + security_policy: SecurityPolicy = FieldInfo(alias="securityPolicy") diff --git a/src/gitpod/types/shared/__init__.py b/src/gitpod/types/shared/__init__.py index 0d4db91c..ad22c091 100644 --- a/src/gitpod/types/shared/__init__.py +++ b/src/gitpod/types/shared/__init__.py @@ -8,6 +8,7 @@ from .subject import Subject as Subject from .principal import Principal as Principal from .task_spec import TaskSpec as TaskSpec +from .date_range import DateRange as DateRange from .error_code import ErrorCode as ErrorCode from .secret_ref import SecretRef as SecretRef from .sort_order import SortOrder as SortOrder @@ -16,14 +17,19 @@ from .resource_role import ResourceRole as ResourceRole from .resource_type import ResourceType as ResourceType from .task_metadata import TaskMetadata as TaskMetadata +from .codex_settings import CodexSettings as CodexSettings from .task_execution import TaskExecution as TaskExecution from .environment_class import EnvironmentClass as EnvironmentClass from .organization_role import OrganizationRole as OrganizationRole from .organization_tier import OrganizationTier as OrganizationTier from .automation_trigger import AutomationTrigger as AutomationTrigger +from .codex_openai_model import CodexOpenAIModel as CodexOpenAIModel +from .codex_service_tier import CodexServiceTier as CodexServiceTier from .task_execution_spec import TaskExecutionSpec as TaskExecutionSpec from .task_execution_phase import TaskExecutionPhase as TaskExecutionPhase from .task_execution_status import TaskExecutionStatus as TaskExecutionStatus +from .codex_reasoning_effort import CodexReasoningEffort as CodexReasoningEffort +from .kernel_controls_action import KernelControlsAction as KernelControlsAction from .count_response_relation import CountResponseRelation as CountResponseRelation from .task_execution_metadata import TaskExecutionMetadata as TaskExecutionMetadata from .environment_variable_item import EnvironmentVariableItem as EnvironmentVariableItem diff --git a/src/gitpod/types/shared/automation_trigger.py b/src/gitpod/types/shared/automation_trigger.py index 8ffd732b..3d1fafb8 100644 --- a/src/gitpod/types/shared/automation_trigger.py +++ b/src/gitpod/types/shared/automation_trigger.py @@ -20,7 +20,7 @@ class AutomationTrigger(BaseModel): The `prebuild` field starts the automation during a prebuild of an environment. This phase does not have user secrets available. The `before_snapshot` field triggers the automation after all prebuild tasks complete but before the snapshot is taken. This is used for tasks that need to run last during prebuilds, such as IDE warmup. - Note: The prebuild and before_snapshot triggers can only be used with tasks, not services. + Note: The before_snapshot trigger can only be used with tasks, not services. """ before_snapshot: Optional[bool] = FieldInfo(alias="beforeSnapshot", default=None) diff --git a/src/gitpod/types/shared/codex_openai_model.py b/src/gitpod/types/shared/codex_openai_model.py new file mode 100644 index 00000000..c956442a --- /dev/null +++ b/src/gitpod/types/shared/codex_openai_model.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexOpenAIModel"] + +CodexOpenAIModel: TypeAlias = Literal[ + "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "CODEX_OPEN_AI_MODEL_GPT_5_5", + "CODEX_OPEN_AI_MODEL_GPT_5_4", + "CODEX_OPEN_AI_MODEL_GPT_5_4_MINI", + "CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX", + "CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX_SPARK", + "CODEX_OPEN_AI_MODEL_GPT_5_2", + "CODEX_OPEN_AI_MODEL_GPT_5_6_SOL", + "CODEX_OPEN_AI_MODEL_GPT_5_6_TERRA", + "CODEX_OPEN_AI_MODEL_GPT_5_6_LUNA", +] diff --git a/src/gitpod/types/shared/codex_reasoning_effort.py b/src/gitpod/types/shared/codex_reasoning_effort.py new file mode 100644 index 00000000..c686cd5b --- /dev/null +++ b/src/gitpod/types/shared/codex_reasoning_effort.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexReasoningEffort"] + +CodexReasoningEffort: TypeAlias = Literal[ + "CODEX_REASONING_EFFORT_UNSPECIFIED", + "CODEX_REASONING_EFFORT_LOW", + "CODEX_REASONING_EFFORT_MEDIUM", + "CODEX_REASONING_EFFORT_HIGH", + "CODEX_REASONING_EFFORT_EXTRA_HIGH", +] diff --git a/src/gitpod/types/shared/codex_service_tier.py b/src/gitpod/types/shared/codex_service_tier.py new file mode 100644 index 00000000..aec3358e --- /dev/null +++ b/src/gitpod/types/shared/codex_service_tier.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexServiceTier"] + +CodexServiceTier: TypeAlias = Literal["CODEX_SERVICE_TIER_UNSPECIFIED", "CODEX_SERVICE_TIER_FAST"] diff --git a/src/gitpod/types/shared/codex_settings.py b/src/gitpod/types/shared/codex_settings.py new file mode 100644 index 00000000..e9c961c9 --- /dev/null +++ b/src/gitpod/types/shared/codex_settings.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel +from .codex_openai_model import CodexOpenAIModel +from .codex_service_tier import CodexServiceTier +from .codex_reasoning_effort import CodexReasoningEffort + +__all__ = ["CodexSettings"] + + +class CodexSettings(BaseModel): + """CodexSettings contains settings consumed only by the Codex app agent.""" + + model: Optional[CodexOpenAIModel] = None + """ + CodexOpenAIModel is the static allowlist of concrete OpenAI models that the + Codex app runtime can select through Ona's Codex picker. + """ + + reasoning_effort: Optional[CodexReasoningEffort] = FieldInfo(alias="reasoningEffort", default=None) + """ + CodexReasoningEffort is the static allowlist of reasoning efforts supported by + the Codex app runtime. + """ + + service_tier: Optional[CodexServiceTier] = FieldInfo(alias="serviceTier", default=None) + """ + CodexServiceTier is the static allowlist of service tiers supported by the Codex + app runtime. + """ diff --git a/src/gitpod/types/shared/date_range.py b/src/gitpod/types/shared/date_range.py new file mode 100644 index 00000000..c6c5033a --- /dev/null +++ b/src/gitpod/types/shared/date_range.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from datetime import datetime + +from pydantic import Field as FieldInfo + +from ..._models import BaseModel + +__all__ = ["DateRange"] + + +class DateRange(BaseModel): + """DateRange specifies a time period for queries.""" + + end_time: datetime = FieldInfo(alias="endTime") + """End time of the date range (exclusive).""" + + start_time: datetime = FieldInfo(alias="startTime") + """Start time of the date range (inclusive).""" diff --git a/src/gitpod/types/organizations/kernel_controls_action.py b/src/gitpod/types/shared/kernel_controls_action.py similarity index 100% rename from src/gitpod/types/organizations/kernel_controls_action.py rename to src/gitpod/types/shared/kernel_controls_action.py diff --git a/src/gitpod/types/shared/resource_role.py b/src/gitpod/types/shared/resource_role.py index 45759abb..1920fc59 100644 --- a/src/gitpod/types/shared/resource_role.py +++ b/src/gitpod/types/shared/resource_role.py @@ -12,7 +12,11 @@ "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", "RESOURCE_ROLE_ORG_GROUPS_ADMIN", + "RESOURCE_ROLE_ORG_ENVIRONMENTS_READER", "RESOURCE_ROLE_ORG_AUDIT_LOG_READER", + "RESOURCE_ROLE_ORG_BILLING_VIEWER", + "RESOURCE_ROLE_ORG_INSIGHTS_VIEWER", + "RESOURCE_ROLE_ORG_SECURITY_ADMIN", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", "RESOURCE_ROLE_USER_IDENTITY", @@ -67,4 +71,6 @@ "RESOURCE_ROLE_SESSION_USER", "RESOURCE_ROLE_TEAM_ADMIN", "RESOURCE_ROLE_TEAM_VIEWER", + "RESOURCE_ROLE_SECURITY_POLICY_ADMIN", + "RESOURCE_ROLE_SECURITY_POLICY_VIEWER", ] diff --git a/src/gitpod/types/shared/resource_type.py b/src/gitpod/types/shared/resource_type.py index 0debaeda..5c593cac 100644 --- a/src/gitpod/types/shared/resource_type.py +++ b/src/gitpod/types/shared/resource_type.py @@ -55,4 +55,7 @@ "RESOURCE_TYPE_ROLE_ASSIGNMENT", "RESOURCE_TYPE_WARM_POOL", "RESOURCE_TYPE_NOTIFICATION", + "RESOURCE_TYPE_SECURITY_POLICY", + "RESOURCE_TYPE_BASE_SNAPSHOT", + "RESOURCE_TYPE_BASE_SNAPSHOT_CONFIG", ] diff --git a/src/gitpod/types/shared/runs_on.py b/src/gitpod/types/shared/runs_on.py index 5f26ef47..33cf1bd5 100644 --- a/src/gitpod/types/shared/runs_on.py +++ b/src/gitpod/types/shared/runs_on.py @@ -18,9 +18,3 @@ class RunsOn(BaseModel): machine: Optional[object] = None """Machine runs the service/task directly on the VM/machine level.""" - - terminal: Optional[object] = None - """ - Terminal runs the service inside a managed PTY terminal in the devcontainer. - Users can attach to the terminal interactively via the terminal API. - """ diff --git a/src/gitpod/types/shared/task_spec.py b/src/gitpod/types/shared/task_spec.py index 9c30234e..cc314415 100644 --- a/src/gitpod/types/shared/task_spec.py +++ b/src/gitpod/types/shared/task_spec.py @@ -18,5 +18,14 @@ class TaskSpec(BaseModel): env: Optional[List[EnvironmentVariableItem]] = None """env specifies environment variables for the task.""" + prebuild_requires_success: Optional[bool] = FieldInfo(alias="prebuildRequiresSuccess", default=None) + """ + prebuild_requires_success controls whether a non-successful outcome of this task + should fail the prebuild. When true and the task is triggered by a prebuild or + before_snapshot trigger, any terminal phase other than SUCCEEDED (i.e. FAILED or + STOPPED) will cause the prebuild to fail instead of just recording a warning. + Defaults to false (existing behavior: task failures produce warnings only). + """ + runs_on: Optional[RunsOn] = FieldInfo(alias="runsOn", default=None) """runs_on specifies the environment the task should run on.""" diff --git a/src/gitpod/types/shared_params/__init__.py b/src/gitpod/types/shared_params/__init__.py index 48b06ca8..20e9b672 100644 --- a/src/gitpod/types/shared_params/__init__.py +++ b/src/gitpod/types/shared_params/__init__.py @@ -6,6 +6,7 @@ from .subject import Subject as Subject from .principal import Principal as Principal from .task_spec import TaskSpec as TaskSpec +from .date_range import DateRange as DateRange from .secret_ref import SecretRef as SecretRef from .sort_order import SortOrder as SortOrder from .field_value import FieldValue as FieldValue @@ -13,10 +14,15 @@ from .resource_role import ResourceRole as ResourceRole from .resource_type import ResourceType as ResourceType from .task_metadata import TaskMetadata as TaskMetadata +from .codex_settings import CodexSettings as CodexSettings from .environment_class import EnvironmentClass as EnvironmentClass from .organization_role import OrganizationRole as OrganizationRole from .automation_trigger import AutomationTrigger as AutomationTrigger +from .codex_openai_model import CodexOpenAIModel as CodexOpenAIModel +from .codex_service_tier import CodexServiceTier as CodexServiceTier from .task_execution_phase import TaskExecutionPhase as TaskExecutionPhase +from .codex_reasoning_effort import CodexReasoningEffort as CodexReasoningEffort +from .kernel_controls_action import KernelControlsAction as KernelControlsAction from .environment_variable_item import EnvironmentVariableItem as EnvironmentVariableItem from .project_environment_class import ProjectEnvironmentClass as ProjectEnvironmentClass from .environment_variable_source import EnvironmentVariableSource as EnvironmentVariableSource diff --git a/src/gitpod/types/shared_params/automation_trigger.py b/src/gitpod/types/shared_params/automation_trigger.py index 27dc462b..1020f005 100644 --- a/src/gitpod/types/shared_params/automation_trigger.py +++ b/src/gitpod/types/shared_params/automation_trigger.py @@ -20,7 +20,7 @@ class AutomationTrigger(TypedDict, total=False): The `prebuild` field starts the automation during a prebuild of an environment. This phase does not have user secrets available. The `before_snapshot` field triggers the automation after all prebuild tasks complete but before the snapshot is taken. This is used for tasks that need to run last during prebuilds, such as IDE warmup. - Note: The prebuild and before_snapshot triggers can only be used with tasks, not services. + Note: The before_snapshot trigger can only be used with tasks, not services. """ before_snapshot: Annotated[bool, PropertyInfo(alias="beforeSnapshot")] diff --git a/src/gitpod/types/shared_params/codex_openai_model.py b/src/gitpod/types/shared_params/codex_openai_model.py new file mode 100644 index 00000000..8ee17cd5 --- /dev/null +++ b/src/gitpod/types/shared_params/codex_openai_model.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexOpenAIModel"] + +CodexOpenAIModel: TypeAlias = Literal[ + "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "CODEX_OPEN_AI_MODEL_GPT_5_5", + "CODEX_OPEN_AI_MODEL_GPT_5_4", + "CODEX_OPEN_AI_MODEL_GPT_5_4_MINI", + "CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX", + "CODEX_OPEN_AI_MODEL_GPT_5_3_CODEX_SPARK", + "CODEX_OPEN_AI_MODEL_GPT_5_2", + "CODEX_OPEN_AI_MODEL_GPT_5_6_SOL", + "CODEX_OPEN_AI_MODEL_GPT_5_6_TERRA", + "CODEX_OPEN_AI_MODEL_GPT_5_6_LUNA", +] diff --git a/src/gitpod/types/shared_params/codex_reasoning_effort.py b/src/gitpod/types/shared_params/codex_reasoning_effort.py new file mode 100644 index 00000000..4f64c1d5 --- /dev/null +++ b/src/gitpod/types/shared_params/codex_reasoning_effort.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexReasoningEffort"] + +CodexReasoningEffort: TypeAlias = Literal[ + "CODEX_REASONING_EFFORT_UNSPECIFIED", + "CODEX_REASONING_EFFORT_LOW", + "CODEX_REASONING_EFFORT_MEDIUM", + "CODEX_REASONING_EFFORT_HIGH", + "CODEX_REASONING_EFFORT_EXTRA_HIGH", +] diff --git a/src/gitpod/types/shared_params/codex_service_tier.py b/src/gitpod/types/shared_params/codex_service_tier.py new file mode 100644 index 00000000..d9b19a46 --- /dev/null +++ b/src/gitpod/types/shared_params/codex_service_tier.py @@ -0,0 +1,9 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["CodexServiceTier"] + +CodexServiceTier: TypeAlias = Literal["CODEX_SERVICE_TIER_UNSPECIFIED", "CODEX_SERVICE_TIER_FAST"] diff --git a/src/gitpod/types/shared_params/codex_settings.py b/src/gitpod/types/shared_params/codex_settings.py new file mode 100644 index 00000000..6d20c8a3 --- /dev/null +++ b/src/gitpod/types/shared_params/codex_settings.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Annotated, TypedDict + +from ..._utils import PropertyInfo +from ..shared.codex_openai_model import CodexOpenAIModel +from ..shared.codex_service_tier import CodexServiceTier +from ..shared.codex_reasoning_effort import CodexReasoningEffort + +__all__ = ["CodexSettings"] + + +class CodexSettings(TypedDict, total=False): + """CodexSettings contains settings consumed only by the Codex app agent.""" + + model: CodexOpenAIModel + """ + CodexOpenAIModel is the static allowlist of concrete OpenAI models that the + Codex app runtime can select through Ona's Codex picker. + """ + + reasoning_effort: Annotated[CodexReasoningEffort, PropertyInfo(alias="reasoningEffort")] + """ + CodexReasoningEffort is the static allowlist of reasoning efforts supported by + the Codex app runtime. + """ + + service_tier: Annotated[CodexServiceTier, PropertyInfo(alias="serviceTier")] + """ + CodexServiceTier is the static allowlist of service tiers supported by the Codex + app runtime. + """ diff --git a/src/gitpod/types/shared_params/date_range.py b/src/gitpod/types/shared_params/date_range.py new file mode 100644 index 00000000..ae103a70 --- /dev/null +++ b/src/gitpod/types/shared_params/date_range.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Union +from datetime import datetime +from typing_extensions import Required, Annotated, TypedDict + +from ..._utils import PropertyInfo + +__all__ = ["DateRange"] + + +class DateRange(TypedDict, total=False): + """DateRange specifies a time period for queries.""" + + end_time: Required[Annotated[Union[str, datetime], PropertyInfo(alias="endTime", format="iso8601")]] + """End time of the date range (exclusive).""" + + start_time: Required[Annotated[Union[str, datetime], PropertyInfo(alias="startTime", format="iso8601")]] + """Start time of the date range (inclusive).""" diff --git a/src/gitpod/types/shared_params/kernel_controls_action.py b/src/gitpod/types/shared_params/kernel_controls_action.py new file mode 100644 index 00000000..3f1009a6 --- /dev/null +++ b/src/gitpod/types/shared_params/kernel_controls_action.py @@ -0,0 +1,11 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, TypeAlias + +__all__ = ["KernelControlsAction"] + +KernelControlsAction: TypeAlias = Literal[ + "KERNEL_CONTROLS_ACTION_UNSPECIFIED", "KERNEL_CONTROLS_ACTION_BLOCK", "KERNEL_CONTROLS_ACTION_AUDIT" +] diff --git a/src/gitpod/types/shared_params/resource_role.py b/src/gitpod/types/shared_params/resource_role.py index 94f5abcc..f3209840 100644 --- a/src/gitpod/types/shared_params/resource_role.py +++ b/src/gitpod/types/shared_params/resource_role.py @@ -14,7 +14,11 @@ "RESOURCE_ROLE_ORG_PROJECTS_ADMIN", "RESOURCE_ROLE_ORG_AUTOMATIONS_ADMIN", "RESOURCE_ROLE_ORG_GROUPS_ADMIN", + "RESOURCE_ROLE_ORG_ENVIRONMENTS_READER", "RESOURCE_ROLE_ORG_AUDIT_LOG_READER", + "RESOURCE_ROLE_ORG_BILLING_VIEWER", + "RESOURCE_ROLE_ORG_INSIGHTS_VIEWER", + "RESOURCE_ROLE_ORG_SECURITY_ADMIN", "RESOURCE_ROLE_GROUP_ADMIN", "RESOURCE_ROLE_GROUP_VIEWER", "RESOURCE_ROLE_USER_IDENTITY", @@ -69,4 +73,6 @@ "RESOURCE_ROLE_SESSION_USER", "RESOURCE_ROLE_TEAM_ADMIN", "RESOURCE_ROLE_TEAM_VIEWER", + "RESOURCE_ROLE_SECURITY_POLICY_ADMIN", + "RESOURCE_ROLE_SECURITY_POLICY_VIEWER", ] diff --git a/src/gitpod/types/shared_params/resource_type.py b/src/gitpod/types/shared_params/resource_type.py index 27b68eae..c59783f0 100644 --- a/src/gitpod/types/shared_params/resource_type.py +++ b/src/gitpod/types/shared_params/resource_type.py @@ -57,4 +57,7 @@ "RESOURCE_TYPE_ROLE_ASSIGNMENT", "RESOURCE_TYPE_WARM_POOL", "RESOURCE_TYPE_NOTIFICATION", + "RESOURCE_TYPE_SECURITY_POLICY", + "RESOURCE_TYPE_BASE_SNAPSHOT", + "RESOURCE_TYPE_BASE_SNAPSHOT_CONFIG", ] diff --git a/src/gitpod/types/shared_params/runs_on.py b/src/gitpod/types/shared_params/runs_on.py index 0182710a..8fc0fd3c 100644 --- a/src/gitpod/types/shared_params/runs_on.py +++ b/src/gitpod/types/shared_params/runs_on.py @@ -20,9 +20,3 @@ class RunsOn(TypedDict, total=False): machine: object """Machine runs the service/task directly on the VM/machine level.""" - - terminal: object - """ - Terminal runs the service inside a managed PTY terminal in the devcontainer. - Users can attach to the terminal interactively via the terminal API. - """ diff --git a/src/gitpod/types/shared_params/task_spec.py b/src/gitpod/types/shared_params/task_spec.py index 691ba57b..8ef1ee03 100644 --- a/src/gitpod/types/shared_params/task_spec.py +++ b/src/gitpod/types/shared_params/task_spec.py @@ -19,5 +19,14 @@ class TaskSpec(TypedDict, total=False): env: Iterable[EnvironmentVariableItem] """env specifies environment variables for the task.""" + prebuild_requires_success: Annotated[bool, PropertyInfo(alias="prebuildRequiresSuccess")] + """ + prebuild_requires_success controls whether a non-successful outcome of this task + should fail the prebuild. When true and the task is triggered by a prebuild or + before_snapshot trigger, any terminal phase other than SUCCEEDED (i.e. FAILED or + STOPPED) will cause the prebuild to fail instead of just recording a warning. + Defaults to false (existing behavior: task failures produce warnings only). + """ + runs_on: Annotated[RunsOn, PropertyInfo(alias="runsOn")] """runs_on specifies the environment the task should run on.""" diff --git a/src/gitpod/types/stack_frame_param.py b/src/gitpod/types/stack_frame_param.py deleted file mode 100644 index 6ce75870..00000000 --- a/src/gitpod/types/stack_frame_param.py +++ /dev/null @@ -1,43 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -from typing import Dict -from typing_extensions import Annotated, TypedDict - -from .._types import SequenceNotStr -from .._utils import PropertyInfo - -__all__ = ["StackFrameParam"] - - -class StackFrameParam(TypedDict, total=False): - """Stack trace frame information (Sentry-compatible)""" - - colno: int - """Column number in the line""" - - context_line: Annotated[str, PropertyInfo(alias="contextLine")] - - filename: str - """File name or path""" - - function: str - """Function name""" - - in_app: Annotated[bool, PropertyInfo(alias="inApp")] - """Whether this frame is in application code (vs library/framework code)""" - - lineno: int - """Line number in the file""" - - module: str - """Module or package name""" - - post_context: Annotated[SequenceNotStr[str], PropertyInfo(alias="postContext")] - - pre_context: Annotated[SequenceNotStr[str], PropertyInfo(alias="preContext")] - """Source code context around the error line""" - - vars: Dict[str, str] - """Additional frame-specific variables/locals""" diff --git a/src/gitpod/types/supported_model.py b/src/gitpod/types/supported_model.py new file mode 100644 index 00000000..434547aa --- /dev/null +++ b/src/gitpod/types/supported_model.py @@ -0,0 +1,33 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["SupportedModel"] + +SupportedModel: TypeAlias = Literal[ + "SUPPORTED_MODEL_UNSPECIFIED", + "SUPPORTED_MODEL_SONNET_3_5", + "SUPPORTED_MODEL_SONNET_3_7", + "SUPPORTED_MODEL_SONNET_3_7_EXTENDED", + "SUPPORTED_MODEL_SONNET_4", + "SUPPORTED_MODEL_SONNET_4_EXTENDED", + "SUPPORTED_MODEL_SONNET_4_5", + "SUPPORTED_MODEL_SONNET_4_5_EXTENDED", + "SUPPORTED_MODEL_SONNET_4_6", + "SUPPORTED_MODEL_SONNET_4_6_EXTENDED", + "SUPPORTED_MODEL_SONNET_5", + "SUPPORTED_MODEL_OPUS_4", + "SUPPORTED_MODEL_OPUS_4_EXTENDED", + "SUPPORTED_MODEL_OPUS_4_5", + "SUPPORTED_MODEL_OPUS_4_5_EXTENDED", + "SUPPORTED_MODEL_OPUS_4_6", + "SUPPORTED_MODEL_OPUS_4_6_EXTENDED", + "SUPPORTED_MODEL_OPUS_4_7", + "SUPPORTED_MODEL_OPUS_4_8", + "SUPPORTED_MODEL_HAIKU_4_5", + "SUPPORTED_MODEL_OPENAI_4O", + "SUPPORTED_MODEL_OPENAI_4O_MINI", + "SUPPORTED_MODEL_OPENAI_O1", + "SUPPORTED_MODEL_OPENAI_O1_MINI", + "SUPPORTED_MODEL_OPENAI_AUTO", +] diff --git a/src/gitpod/types/team_credit_usage.py b/src/gitpod/types/team_credit_usage.py new file mode 100644 index 00000000..ee28a9a7 --- /dev/null +++ b/src/gitpod/types/team_credit_usage.py @@ -0,0 +1,23 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType + +__all__ = ["TeamCreditUsage"] + + +class TeamCreditUsage(BaseModel): + """ + TeamCreditUsage contains a single team's credit usage for a day, broken down by type. + """ + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + team_id: Optional[str] = FieldInfo(alias="teamId", default=None) + """Empty when representing the "Others" aggregation bucket.""" + + usage: Optional[List[CreditsByType]] = None diff --git a/src/gitpod/types/team_cumulative_credit_usage.py b/src/gitpod/types/team_cumulative_credit_usage.py new file mode 100644 index 00000000..9f0b5ec2 --- /dev/null +++ b/src/gitpod/types/team_cumulative_credit_usage.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .cumulative_credit_usage import CumulativeCreditUsage + +__all__ = ["TeamCumulativeCreditUsage"] + + +class TeamCumulativeCreditUsage(BaseModel): + """ + TeamCumulativeCreditUsage contains a team's cumulative credit usage and allocation. + """ + + credit_budget: Optional[str] = FieldInfo(alias="creditBudget", default=None) + """ + The team's credit allocation (budget) in whole credits, if set. Not set means no + allocation has been configured for this team. + """ + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + team_id: Optional[str] = FieldInfo(alias="teamId", default=None) + + usage: Optional[CumulativeCreditUsage] = None + """Cumulative credit usage for this team.""" diff --git a/src/gitpod/types/team_enterprise_ai_usage.py b/src/gitpod/types/team_enterprise_ai_usage.py new file mode 100644 index 00000000..e7b4932b --- /dev/null +++ b/src/gitpod/types/team_enterprise_ai_usage.py @@ -0,0 +1,27 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage +from .enterprise_ai_usage_budget import EnterpriseAIUsageBudget +from .enterprise_ai_usage_by_token_type import EnterpriseAIUsageByTokenType + +__all__ = ["TeamEnterpriseAIUsage"] + + +class TeamEnterpriseAIUsage(BaseModel): + budget: Optional[EnterpriseAIUsageBudget] = None + """budget is unset when no monthly budget applies to this team.""" + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + team_id: Optional[str] = FieldInfo(alias="teamId", default=None) + + usage: Optional[EnterpriseAIUsage] = None + + usage_by_token_type: Optional[List[EnterpriseAIUsageByTokenType]] = FieldInfo( + alias="usageByTokenType", default=None + ) diff --git a/src/gitpod/types/time_series_point.py b/src/gitpod/types/time_series_point.py new file mode 100644 index 00000000..a4cbc83c --- /dev/null +++ b/src/gitpod/types/time_series_point.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from datetime import datetime + +from .._models import BaseModel + +__all__ = ["TimeSeriesPoint"] + + +class TimeSeriesPoint(BaseModel): + time: Optional[datetime] = None + """Timestamp for this data point.""" + + value: Optional[int] = None + """The numerical value for this data point.""" diff --git a/src/gitpod/types/tool_breakdown.py b/src/gitpod/types/tool_breakdown.py new file mode 100644 index 00000000..9c1f7ef2 --- /dev/null +++ b/src/gitpod/types/tool_breakdown.py @@ -0,0 +1,29 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .co_author_tool import CoAuthorTool + +__all__ = ["ToolBreakdown"] + + +class ToolBreakdown(BaseModel): + """ToolBreakdown contains stats for a single AI tool (or human).""" + + commits: Optional[str] = None + """Number of commits attributed to this tool.""" + + distinct_authors: Optional[str] = FieldInfo(alias="distinctAuthors", default=None) + """Distinct authors who used this tool.""" + + lines_added: Optional[str] = FieldInfo(alias="linesAdded", default=None) + """Lines added by this tool.""" + + lines_removed: Optional[str] = FieldInfo(alias="linesRemoved", default=None) + """Lines removed by this tool.""" + + tool: Optional[CoAuthorTool] = None + """The tool these stats are for.""" diff --git a/src/gitpod/types/usage_get_adoption_usage_summary_params.py b/src/gitpod/types/usage_get_adoption_usage_summary_params.py new file mode 100644 index 00000000..f0698b6b --- /dev/null +++ b/src/gitpod/types/usage_get_adoption_usage_summary_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetAdoptionUsageSummaryParams"] + + +class UsageGetAdoptionUsageSummaryParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query metrics within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to filter metrics by.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """Optional team ID to scope results to members of a specific team.""" + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to filter metrics for a specific user (personal insights view). + """ diff --git a/src/gitpod/types/usage_get_adoption_usage_summary_response.py b/src/gitpod/types/usage_get_adoption_usage_summary_response.py new file mode 100644 index 00000000..ccde3c86 --- /dev/null +++ b/src/gitpod/types/usage_get_adoption_usage_summary_response.py @@ -0,0 +1,57 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .time_series_point import TimeSeriesPoint + +__all__ = ["UsageGetAdoptionUsageSummaryResponse"] + + +class UsageGetAdoptionUsageSummaryResponse(BaseModel): + active_users_count: Optional[str] = FieldInfo(alias="activeUsersCount", default=None) + """Count of active users in the date range.""" + + active_users_trend: Optional[float] = FieldInfo(alias="activeUsersTrend", default=None) + """ + Fractional change in active_users_count vs previous period. Computed as + (current - previous) / previous. + """ + + env_runtime_per_user_seconds: Optional[float] = FieldInfo(alias="envRuntimePerUserSeconds", default=None) + """Average environment runtime in seconds per active user.""" + + env_runtime_per_user_trend: Optional[float] = FieldInfo(alias="envRuntimePerUserTrend", default=None) + """ + Fractional change in env_runtime_per_user_seconds vs previous period. Computed + as (current - previous) / previous. + """ + + power_users_count: Optional[str] = FieldInfo(alias="powerUsersCount", default=None) + """Count of power users in the date range.""" + + power_users_threshold_seconds: Optional[str] = FieldInfo(alias="powerUsersThresholdSeconds", default=None) + """ + Threshold in seconds used to determine power users. Displayed to users so they + understand the definition. + """ + + power_users_trend: Optional[float] = FieldInfo(alias="powerUsersTrend", default=None) + """ + Fractional change in power_users_count vs previous period. Computed as + (current - previous) / previous. + """ + + sessions_count: Optional[str] = FieldInfo(alias="sessionsCount", default=None) + """Count of environment sessions (total starts) in the date range.""" + + sessions_trend: Optional[float] = FieldInfo(alias="sessionsTrend", default=None) + """ + Fractional change in sessions_count vs previous period. Computed as (current - + previous) / previous. + """ + + sparkline: Optional[List[TimeSeriesPoint]] = None + """Sparkline data for the card's trend line (typically ~4 weekly points).""" diff --git a/src/gitpod/types/usage_get_agent_trace_summary_params.py b/src/gitpod/types/usage_get_agent_trace_summary_params.py new file mode 100644 index 00000000..c106353f --- /dev/null +++ b/src/gitpod/types/usage_get_agent_trace_summary_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetAgentTraceSummaryParams"] + + +class UsageGetAgentTraceSummaryParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_agent_trace_summary_response.py b/src/gitpod/types/usage_get_agent_trace_summary_response.py new file mode 100644 index 00000000..d161a048 --- /dev/null +++ b/src/gitpod/types/usage_get_agent_trace_summary_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel +from .time_series_point import TimeSeriesPoint +from .agent_trace_summary import AgentTraceSummary + +__all__ = ["UsageGetAgentTraceSummaryResponse"] + + +class UsageGetAgentTraceSummaryResponse(BaseModel): + sparkline: Optional[List[TimeSeriesPoint]] = None + """Sparkline data for card rendering.""" + + summary: Optional[AgentTraceSummary] = None + """Summary totals and trends for the requested date range.""" diff --git a/src/gitpod/types/usage_get_agent_trace_time_series_params.py b/src/gitpod/types/usage_get_agent_trace_time_series_params.py new file mode 100644 index 00000000..e5cd4c66 --- /dev/null +++ b/src/gitpod/types/usage_get_agent_trace_time_series_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .resolution import Resolution +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetAgentTraceTimeSeriesParams"] + + +class UsageGetAgentTraceTimeSeriesParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + resolution: Resolution + """Time resolution for the series data.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_agent_trace_time_series_response.py b/src/gitpod/types/usage_get_agent_trace_time_series_response.py new file mode 100644 index 00000000..4e016d85 --- /dev/null +++ b/src/gitpod/types/usage_get_agent_trace_time_series_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .agent_trace_time_bucket import AgentTraceTimeBucket + +__all__ = ["UsageGetAgentTraceTimeSeriesResponse"] + + +class UsageGetAgentTraceTimeSeriesResponse(BaseModel): + time_series: Optional[List[AgentTraceTimeBucket]] = FieldInfo(alias="timeSeries", default=None) + """Time series of agent trace stats, bucketed by the requested resolution.""" diff --git a/src/gitpod/types/usage_get_co_author_summary_params.py b/src/gitpod/types/usage_get_co_author_summary_params.py new file mode 100644 index 00000000..96ae9f5b --- /dev/null +++ b/src/gitpod/types/usage_get_co_author_summary_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetCoAuthorSummaryParams"] + + +class UsageGetCoAuthorSummaryParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_co_author_summary_response.py b/src/gitpod/types/usage_get_co_author_summary_response.py new file mode 100644 index 00000000..988ed92d --- /dev/null +++ b/src/gitpod/types/usage_get_co_author_summary_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel +from .co_author_summary import CoAuthorSummary +from .time_series_point import TimeSeriesPoint + +__all__ = ["UsageGetCoAuthorSummaryResponse"] + + +class UsageGetCoAuthorSummaryResponse(BaseModel): + sparkline: Optional[List[TimeSeriesPoint]] = None + """Sparkline data for card rendering.""" + + summary: Optional[CoAuthorSummary] = None + """Summary totals and trends for the requested date range.""" diff --git a/src/gitpod/types/usage_get_co_author_time_series_params.py b/src/gitpod/types/usage_get_co_author_time_series_params.py new file mode 100644 index 00000000..6fb8db52 --- /dev/null +++ b/src/gitpod/types/usage_get_co_author_time_series_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .resolution import Resolution +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetCoAuthorTimeSeriesParams"] + + +class UsageGetCoAuthorTimeSeriesParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + resolution: Resolution + """Time resolution for the series data.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_co_author_time_series_response.py b/src/gitpod/types/usage_get_co_author_time_series_response.py new file mode 100644 index 00000000..71aef495 --- /dev/null +++ b/src/gitpod/types/usage_get_co_author_time_series_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .co_author_time_bucket import CoAuthorTimeBucket + +__all__ = ["UsageGetCoAuthorTimeSeriesResponse"] + + +class UsageGetCoAuthorTimeSeriesResponse(BaseModel): + time_series: Optional[List[CoAuthorTimeBucket]] = FieldInfo(alias="timeSeries", default=None) + """Time series of contribution stats, bucketed by the requested resolution.""" diff --git a/src/gitpod/types/usage_get_pr_summary_params.py b/src/gitpod/types/usage_get_pr_summary_params.py new file mode 100644 index 00000000..93274a16 --- /dev/null +++ b/src/gitpod/types/usage_get_pr_summary_params.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetPrSummaryParams"] + + +class UsageGetPrSummaryParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_pr_summary_response.py b/src/gitpod/types/usage_get_pr_summary_response.py new file mode 100644 index 00000000..59a742a1 --- /dev/null +++ b/src/gitpod/types/usage_get_pr_summary_response.py @@ -0,0 +1,17 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from .._models import BaseModel +from .pr_summary import PrSummary +from .time_series_point import TimeSeriesPoint + +__all__ = ["UsageGetPrSummaryResponse"] + + +class UsageGetPrSummaryResponse(BaseModel): + sparkline: Optional[List[TimeSeriesPoint]] = None + """Sparkline data for card rendering.""" + + summary: Optional[PrSummary] = None + """Summary totals and trends for the requested date range.""" diff --git a/src/gitpod/types/usage_get_pr_time_series_params.py b/src/gitpod/types/usage_get_pr_time_series_params.py new file mode 100644 index 00000000..4c36f6d2 --- /dev/null +++ b/src/gitpod/types/usage_get_pr_time_series_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Required, Annotated, TypedDict + +from .._utils import PropertyInfo +from .resolution import Resolution +from .shared_params.date_range import DateRange + +__all__ = ["UsageGetPrTimeSeriesParams"] + + +class UsageGetPrTimeSeriesParams(TypedDict, total=False): + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] + """Date range to query within.""" + + project_id: Annotated[str, PropertyInfo(alias="projectId")] + """Optional project ID to scope results.""" + + resolution: Resolution + """Time resolution for the series data.""" + + team_id: Annotated[str, PropertyInfo(alias="teamId")] + """ + Optional team ID to scope results to a specific team. Mutually exclusive with + user_id. + """ + + user_id: Annotated[str, PropertyInfo(alias="userId")] + """ + Optional user ID to scope results to a specific user. Mutually exclusive with + team_id. + """ diff --git a/src/gitpod/types/usage_get_pr_time_series_response.py b/src/gitpod/types/usage_get_pr_time_series_response.py new file mode 100644 index 00000000..da95055c --- /dev/null +++ b/src/gitpod/types/usage_get_pr_time_series_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .pr_time_bucket import PrTimeBucket + +__all__ = ["UsageGetPrTimeSeriesResponse"] + + +class UsageGetPrTimeSeriesResponse(BaseModel): + time_series: Optional[List[PrTimeBucket]] = FieldInfo(alias="timeSeries", default=None) + """Time series of PR speed metrics, bucketed by the requested resolution.""" diff --git a/src/gitpod/types/usage_list_environment_runtime_records_params.py b/src/gitpod/types/usage_list_environment_runtime_records_params.py index e3459eae..74e22cb1 100644 --- a/src/gitpod/types/usage_list_environment_runtime_records_params.py +++ b/src/gitpod/types/usage_list_environment_runtime_records_params.py @@ -2,13 +2,12 @@ from __future__ import annotations -from typing import Union -from datetime import datetime from typing_extensions import Required, Annotated, TypedDict from .._utils import PropertyInfo +from .shared_params.date_range import DateRange -__all__ = ["UsageListEnvironmentRuntimeRecordsParams", "Filter", "FilterDateRange", "Pagination"] +__all__ = ["UsageListEnvironmentRuntimeRecordsParams", "Filter", "Pagination"] class UsageListEnvironmentRuntimeRecordsParams(TypedDict, total=False): @@ -23,20 +22,10 @@ class UsageListEnvironmentRuntimeRecordsParams(TypedDict, total=False): """Pagination options.""" -class FilterDateRange(TypedDict, total=False): - """Date range to query runtime records within.""" - - end_time: Required[Annotated[Union[str, datetime], PropertyInfo(alias="endTime", format="iso8601")]] - """End time of the date range (exclusive).""" - - start_time: Required[Annotated[Union[str, datetime], PropertyInfo(alias="startTime", format="iso8601")]] - """Start time of the date range (inclusive).""" - - class Filter(TypedDict, total=False): """Filter options.""" - date_range: Required[Annotated[FilterDateRange, PropertyInfo(alias="dateRange")]] + date_range: Required[Annotated[DateRange, PropertyInfo(alias="dateRange")]] """Date range to query runtime records within.""" project_id: Annotated[str, PropertyInfo(alias="projectId")] diff --git a/src/gitpod/types/usage_type.py b/src/gitpod/types/usage_type.py new file mode 100644 index 00000000..9f6d566b --- /dev/null +++ b/src/gitpod/types/usage_type.py @@ -0,0 +1,7 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal, TypeAlias + +__all__ = ["UsageType"] + +UsageType: TypeAlias = Literal["USAGE_TYPE_UNSPECIFIED", "USAGE_TYPE_ENVIRONMENT", "USAGE_TYPE_AGENTIC"] diff --git a/src/gitpod/types/user_cost_budget_usage.py b/src/gitpod/types/user_cost_budget_usage.py new file mode 100644 index 00000000..b3e29df3 --- /dev/null +++ b/src/gitpod/types/user_cost_budget_usage.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .billing_currency import BillingCurrency +from .enterprise_ai_usage import EnterpriseAIUsage +from .enterprise_ai_user_budget_policy_source import EnterpriseAIUserBudgetPolicySource + +__all__ = ["UserCostBudgetUsage"] + + +class UserCostBudgetUsage(BaseModel): + budget_source: Optional[EnterpriseAIUserBudgetPolicySource] = FieldInfo(alias="budgetSource", default=None) + + currency: Optional[BillingCurrency] = None + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + is_service_account: Optional[bool] = FieldInfo(alias="isServiceAccount", default=None) + + monthly_cost_limit_microunits: Optional[str] = FieldInfo(alias="monthlyCostLimitMicrounits", default=None) + + month_to_date_usage: Optional[EnterpriseAIUsage] = FieldInfo(alias="monthToDateUsage", default=None) + """Usage within the requested date range. + + Reflects true month-to-date usage when the range starts on the first day of the + month. + """ + + no_cap: Optional[bool] = FieldInfo(alias="noCap", default=None) + + over_budget: Optional[bool] = FieldInfo(alias="overBudget", default=None) + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + + utilization_percent: Optional[float] = FieldInfo(alias="utilizationPercent", default=None) diff --git a/src/gitpod/types/user_credit_budget_usage.py b/src/gitpod/types/user_credit_budget_usage.py new file mode 100644 index 00000000..6dcccc5d --- /dev/null +++ b/src/gitpod/types/user_credit_budget_usage.py @@ -0,0 +1,40 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .cumulative_credit_usage import CumulativeCreditUsage +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel +from .enterprise_ai_user_budget_policy_source import EnterpriseAIUserBudgetPolicySource + +__all__ = ["UserCreditBudgetUsage"] + + +class UserCreditBudgetUsage(BaseModel): + budget_source: Optional[EnterpriseAIUserBudgetPolicySource] = FieldInfo(alias="budgetSource", default=None) + + credit_budget: Optional[str] = FieldInfo(alias="creditBudget", default=None) + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + is_service_account: Optional[bool] = FieldInfo(alias="isServiceAccount", default=None) + """ + True when user_id refers to a service account rather than a human user. The + dashboard uses this to mark non-human accounts in admin tables. + """ + + month_to_date_usage: Optional[CumulativeCreditUsage] = FieldInfo(alias="monthToDateUsage", default=None) + """CumulativeCreditUsage contains cumulative credit consumption totals.""" + + no_cap: Optional[bool] = FieldInfo(alias="noCap", default=None) + + over_budget: Optional[bool] = FieldInfo(alias="overBudget", default=None) + + usage_by_model: Optional[List[EnterpriseAIUsageByModel]] = FieldInfo(alias="usageByModel", default=None) + """Month-to-date intelligence usage broken down by model.""" + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + + utilization_percent: Optional[float] = FieldInfo(alias="utilizationPercent", default=None) diff --git a/src/gitpod/types/user_credit_usage.py b/src/gitpod/types/user_credit_usage.py new file mode 100644 index 00000000..4aaa4930 --- /dev/null +++ b/src/gitpod/types/user_credit_usage.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .credits_by_type import CreditsByType +from .enterprise_ai_usage_by_model import EnterpriseAIUsageByModel + +__all__ = ["UserCreditUsage"] + + +class UserCreditUsage(BaseModel): + """UserCreditUsage contains a single user's credit usage, broken down by type.""" + + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + usage: Optional[List[CreditsByType]] = None + + usage_by_model: Optional[List[EnterpriseAIUsageByModel]] = FieldInfo(alias="usageByModel", default=None) + """Intelligence usage broken down by model.""" + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + """Empty when representing the "Others" aggregation bucket.""" diff --git a/src/gitpod/types/user_enterprise_ai_usage.py b/src/gitpod/types/user_enterprise_ai_usage.py new file mode 100644 index 00000000..e574352c --- /dev/null +++ b/src/gitpod/types/user_enterprise_ai_usage.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional + +from pydantic import Field as FieldInfo + +from .._models import BaseModel +from .enterprise_ai_usage import EnterpriseAIUsage + +__all__ = ["UserEnterpriseAIUsage"] + + +class UserEnterpriseAIUsage(BaseModel): + display_name: Optional[str] = FieldInfo(alias="displayName", default=None) + + usage: Optional[EnterpriseAIUsage] = None + + user_id: Optional[str] = FieldInfo(alias="userId", default=None) + """Empty when representing the "Others" aggregation bucket.""" diff --git a/src/gitpod/types/veto.py b/src/gitpod/types/veto.py index 029d97c3..8a5a676f 100644 --- a/src/gitpod/types/veto.py +++ b/src/gitpod/types/veto.py @@ -3,7 +3,7 @@ from typing import List, Optional from .._models import BaseModel -from .organizations.kernel_controls_action import KernelControlsAction +from .shared.kernel_controls_action import KernelControlsAction __all__ = ["Veto", "Exec"] diff --git a/src/gitpod/types/veto_param.py b/src/gitpod/types/veto_param.py index 0234807c..fe38f339 100644 --- a/src/gitpod/types/veto_param.py +++ b/src/gitpod/types/veto_param.py @@ -5,7 +5,7 @@ from typing_extensions import TypedDict from .._types import SequenceNotStr -from .organizations.kernel_controls_action import KernelControlsAction +from .shared.kernel_controls_action import KernelControlsAction __all__ = ["VetoParam", "Exec"] diff --git a/src/gitpod/types/wake_event_param.py b/src/gitpod/types/wake_event_param.py index 0a53c300..48aaa397 100644 --- a/src/gitpod/types/wake_event_param.py +++ b/src/gitpod/types/wake_event_param.py @@ -9,7 +9,25 @@ from .._types import SequenceNotStr from .._utils import PropertyInfo -__all__ = ["WakeEventParam", "Environment", "LoopRetrigger", "LoopRetriggerUnmetCondition", "Timer"] +__all__ = [ + "WakeEventParam", + "DevcontainerRebuild", + "Environment", + "LoopRetrigger", + "LoopRetriggerUnmetCondition", + "Timer", +] + + +class DevcontainerRebuild(TypedDict, total=False): + environment_id: Annotated[str, PropertyInfo(alias="environmentId")] + + failure_message: Annotated[SequenceNotStr[str], PropertyInfo(alias="failureMessage")] + + phase: str + """The devcontainer phase reached by the target session.""" + + session_id: Annotated[str, PropertyInfo(alias="sessionId")] class Environment(TypedDict, total=False): @@ -52,6 +70,8 @@ class WakeEventParam(TypedDict, total=False): Delivered via SendToAgentExecution as a new oneof variant. """ + devcontainer_rebuild: Annotated[DevcontainerRebuild, PropertyInfo(alias="devcontainerRebuild")] + environment: Environment interest_id: Annotated[str, PropertyInfo(alias="interestId")] diff --git a/src/gitpod/types/workflow_trigger.py b/src/gitpod/types/workflow_trigger.py index 4b044761..8d7b81ec 100644 --- a/src/gitpod/types/workflow_trigger.py +++ b/src/gitpod/types/workflow_trigger.py @@ -27,10 +27,18 @@ class PullRequest(BaseModel): "PULL_REQUEST_EVENT_MERGED", "PULL_REQUEST_EVENT_CLOSED", "PULL_REQUEST_EVENT_READY_FOR_REVIEW", + "PULL_REQUEST_EVENT_REVIEW_REQUESTED", ] ] ] = None + integration_id: Optional[str] = FieldInfo(alias="integrationId", default=None) + """ + integration_id is the optional ID of an integration that acts as the source of + webhook events. When set, the trigger will be activated when the webhook + receives events. + """ + webhook_id: Optional[str] = FieldInfo(alias="webhookId", default=None) """ webhook_id is the optional ID of a webhook that this trigger is bound to. When @@ -84,6 +92,8 @@ class WorkflowTrigger(BaseModel): - Manual: Can use any context type - Time: Typically uses Projects or Repositories context - PullRequest: Can use any context, FromTrigger uses PR repository context + - Incident: Typically uses Projects or Repositories context (no inherent repo + context) """ manual: Optional[object] = None diff --git a/src/gitpod/types/workflow_trigger_context.py b/src/gitpod/types/workflow_trigger_context.py index 6d82400e..769acdb0 100644 --- a/src/gitpod/types/workflow_trigger_context.py +++ b/src/gitpod/types/workflow_trigger_context.py @@ -103,6 +103,7 @@ class WorkflowTriggerContext(BaseModel): - Manual: Can use any context type - Time: Typically uses Projects or Repositories context - PullRequest: Can use any context, FromTrigger uses PR repository context + - Incident: Typically uses Projects or Repositories context (no inherent repo context) """ agent: Optional[Agent] = None diff --git a/src/gitpod/types/workflow_trigger_context_param.py b/src/gitpod/types/workflow_trigger_context_param.py index 4ebb2e49..1522f619 100644 --- a/src/gitpod/types/workflow_trigger_context_param.py +++ b/src/gitpod/types/workflow_trigger_context_param.py @@ -104,6 +104,7 @@ class WorkflowTriggerContextParam(TypedDict, total=False): - Manual: Can use any context type - Time: Typically uses Projects or Repositories context - PullRequest: Can use any context, FromTrigger uses PR repository context + - Incident: Typically uses Projects or Repositories context (no inherent repo context) """ agent: Agent diff --git a/src/gitpod/types/workflow_trigger_param.py b/src/gitpod/types/workflow_trigger_param.py index ed28c9f8..0753a773 100644 --- a/src/gitpod/types/workflow_trigger_param.py +++ b/src/gitpod/types/workflow_trigger_param.py @@ -26,9 +26,17 @@ class PullRequest(TypedDict, total=False): "PULL_REQUEST_EVENT_MERGED", "PULL_REQUEST_EVENT_CLOSED", "PULL_REQUEST_EVENT_READY_FOR_REVIEW", + "PULL_REQUEST_EVENT_REVIEW_REQUESTED", ] ] + integration_id: Annotated[Optional[str], PropertyInfo(alias="integrationId")] + """ + integration_id is the optional ID of an integration that acts as the source of + webhook events. When set, the trigger will be activated when the webhook + receives events. + """ + webhook_id: Annotated[Optional[str], PropertyInfo(alias="webhookId")] """ webhook_id is the optional ID of a webhook that this trigger is bound to. When @@ -82,6 +90,8 @@ class WorkflowTriggerParam(TypedDict, total=False): - Manual: Can use any context type - Time: Typically uses Projects or Repositories context - PullRequest: Can use any context, FromTrigger uses PR repository context + - Incident: Typically uses Projects or Repositories context (no inherent repo + context) """ manual: object diff --git a/tests/api_resources/environments/automations/test_services.py b/tests/api_resources/environments/automations/test_services.py index 3a80cc01..daa24e8d 100644 --- a/tests/api_resources/environments/automations/test_services.py +++ b/tests/api_resources/environments/automations/test_services.py @@ -69,13 +69,13 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, "session": "session", "spec_version": "specVersion", @@ -182,13 +182,13 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, status={ @@ -431,13 +431,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, "session": "session", "spec_version": "specVersion", @@ -544,13 +544,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "readiness_timeout": "+9125115.360s", "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, status={ diff --git a/tests/api_resources/environments/automations/test_tasks.py b/tests/api_resources/environments/automations/test_tasks.py index 29599ec1..a2acfa39 100644 --- a/tests/api_resources/environments/automations/test_tasks.py +++ b/tests/api_resources/environments/automations/test_tasks.py @@ -65,13 +65,13 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -172,13 +172,13 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -371,13 +371,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) @@ -478,13 +478,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "value_from": {"secret_ref": {"id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"}}, } ], + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, }, ) diff --git a/tests/api_resources/environments/test_automations.py b/tests/api_resources/environments/test_automations.py index bed1aa5a..f9a62f02 100644 --- a/tests/api_resources/environments/test_automations.py +++ b/tests/api_resources/environments/test_automations.py @@ -37,6 +37,7 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: }, "description": "Development web server", "name": "Web Server", + "readiness_timeout": "+9125115.360s", "role": "", "runs_on": { "docker": { @@ -44,7 +45,6 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postDevcontainerStart"], } @@ -55,13 +55,13 @@ def test_method_upsert_with_all_params(self, client: Gitpod) -> None: "depends_on": ["string"], "description": "Builds the project artifacts", "name": "Build Project", + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postEnvironmentStart"], } @@ -119,6 +119,7 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> }, "description": "Development web server", "name": "Web Server", + "readiness_timeout": "+9125115.360s", "role": "", "runs_on": { "docker": { @@ -126,7 +127,6 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postDevcontainerStart"], } @@ -137,13 +137,13 @@ async def test_method_upsert_with_all_params(self, async_client: AsyncGitpod) -> "depends_on": ["string"], "description": "Builds the project artifacts", "name": "Build Project", + "prebuild_requires_success": True, "runs_on": { "docker": { "environment": ["string"], "image": "x", }, "machine": {}, - "terminal": {}, }, "triggered_by": ["postEnvironmentStart"], } diff --git a/tests/api_resources/organizations/test_policies.py b/tests/api_resources/organizations/test_policies.py index 56814db9..93ae13b8 100644 --- a/tests/api_resources/organizations/test_policies.py +++ b/tests/api_resources/organizations/test_policies.py @@ -67,6 +67,11 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: policy = client.organizations.policies.update( organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", agent_policy={ + "allowed_agent_ids": ["string"], + "allowed_codex_models": ["CODEX_OPEN_AI_MODEL_UNSPECIFIED"], + "allowed_codex_reasoning_efforts": ["CODEX_REASONING_EFFORT_UNSPECIFIED"], + "allowed_codex_service_tiers": ["CODEX_SERVICE_TIER_UNSPECIFIED"], + "codex_model_policy": {"model_states": {"foo": "CODEX_MODEL_POLICY_STATE_UNSPECIFIED"}}, "command_deny_list": ["string"], "conversation_sharing_policy": "CONVERSATION_SHARING_POLICY_UNSPECIFIED", "max_subagents_per_environment": 10, @@ -79,11 +84,13 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: default_editor_id="defaultEditorId", default_environment_image="defaultEnvironmentImage", delete_archived_environments_after="+9125115.360s", + disable_from_scratch=True, editor_version_restrictions={"foo": {"allowed_versions": ["string"]}}, maximum_environment_lifetime="+9125115.360s", maximum_environments_per_user="20", maximum_environment_timeout="3600s", maximum_running_environments_per_user="5", + max_port_admission_level="ADMISSION_LEVEL_UNSPECIFIED", members_create_projects=True, members_require_projects=True, port_sharing_disabled=True, @@ -98,11 +105,13 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "tags": "tags", } }, + security_policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", veto_exec_policy={ "action": "KERNEL_CONTROLS_ACTION_UNSPECIFIED", "enabled": True, "executables": ["string"], }, + web_browser_disabled=True, ) assert_matches_type(object, policy, path=["response"]) @@ -186,6 +195,11 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> policy = await async_client.organizations.policies.update( organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", agent_policy={ + "allowed_agent_ids": ["string"], + "allowed_codex_models": ["CODEX_OPEN_AI_MODEL_UNSPECIFIED"], + "allowed_codex_reasoning_efforts": ["CODEX_REASONING_EFFORT_UNSPECIFIED"], + "allowed_codex_service_tiers": ["CODEX_SERVICE_TIER_UNSPECIFIED"], + "codex_model_policy": {"model_states": {"foo": "CODEX_MODEL_POLICY_STATE_UNSPECIFIED"}}, "command_deny_list": ["string"], "conversation_sharing_policy": "CONVERSATION_SHARING_POLICY_UNSPECIFIED", "max_subagents_per_environment": 10, @@ -198,11 +212,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> default_editor_id="defaultEditorId", default_environment_image="defaultEnvironmentImage", delete_archived_environments_after="+9125115.360s", + disable_from_scratch=True, editor_version_restrictions={"foo": {"allowed_versions": ["string"]}}, maximum_environment_lifetime="+9125115.360s", maximum_environments_per_user="20", maximum_environment_timeout="3600s", maximum_running_environments_per_user="5", + max_port_admission_level="ADMISSION_LEVEL_UNSPECIFIED", members_create_projects=True, members_require_projects=True, port_sharing_disabled=True, @@ -217,11 +233,13 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "tags": "tags", } }, + security_policy_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", veto_exec_policy={ "action": "KERNEL_CONTROLS_ACTION_UNSPECIFIED", "enabled": True, "executables": ["string"], }, + web_browser_disabled=True, ) assert_matches_type(object, policy, path=["response"]) diff --git a/tests/api_resources/organizations/test_scim_configurations.py b/tests/api_resources/organizations/test_scim_configurations.py index 2bd96136..03411ef3 100644 --- a/tests/api_resources/organizations/test_scim_configurations.py +++ b/tests/api_resources/organizations/test_scim_configurations.py @@ -39,6 +39,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: scim_configuration = client.organizations.scim_configurations.create( organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + allow_unverified_email_account_linking=True, name="name", token_expires_in="+9125115.360s", ) @@ -119,6 +120,7 @@ def test_method_update(self, client: Gitpod) -> None: def test_method_update_with_all_params(self, client: Gitpod) -> None: scim_configuration = client.organizations.scim_configurations.update( scim_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + allow_unverified_email_account_linking=True, enabled=False, name="name", sso_configuration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -290,6 +292,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> scim_configuration = await async_client.organizations.scim_configurations.create( organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", sso_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + allow_unverified_email_account_linking=True, name="name", token_expires_in="+9125115.360s", ) @@ -370,6 +373,7 @@ async def test_method_update(self, async_client: AsyncGitpod) -> None: async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> None: scim_configuration = await async_client.organizations.scim_configurations.update( scim_configuration_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + allow_unverified_email_account_linking=True, enabled=False, name="name", sso_configuration_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py index 0a7b1ed7..7b2e70a2 100644 --- a/tests/api_resources/test_agents.py +++ b/tests/api_resources/test_agents.py @@ -191,6 +191,7 @@ def test_method_list_executions_with_all_params(self, client: Gitpod) -> None: token="token", page_size=0, filter={ + "agent_execution_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "agent_ids": ["b8a64cfa-43e2-4b9d-9fb3-07edc63f5971"], "annotations": {"foo": "string"}, "creator_ids": ["string"], @@ -366,6 +367,11 @@ def test_method_send_to_execution_with_all_params(self, client: Gitpod) -> None: "payload": "payload", "type": "TYPE_UNSPECIFIED", }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, user_input={ "id": "id", "created_at": parse_datetime("2019-12-27T18:11:19.117Z"), @@ -385,6 +391,12 @@ def test_method_send_to_execution_with_all_params(self, client: Gitpod) -> None: "text": {"content": "Generate a report based on the latest logs."}, }, wake_event={ + "devcontainer_rebuild": { + "environment_id": "environmentId", + "failure_message": ["string"], + "phase": "phase", + "session_id": "sessionId", + }, "environment": { "environment_id": "environmentId", "failure_message": ["string"], @@ -467,6 +479,11 @@ def test_method_start_execution_with_all_params(self, client: Gitpod) -> None: "url": "url", }, }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, mode="AGENT_MODE_UNSPECIFIED", name="name", runner_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -749,6 +766,7 @@ async def test_method_list_executions_with_all_params(self, async_client: AsyncG token="token", page_size=0, filter={ + "agent_execution_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], "agent_ids": ["b8a64cfa-43e2-4b9d-9fb3-07edc63f5971"], "annotations": {"foo": "string"}, "creator_ids": ["string"], @@ -924,6 +942,11 @@ async def test_method_send_to_execution_with_all_params(self, async_client: Asyn "payload": "payload", "type": "TYPE_UNSPECIFIED", }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, user_input={ "id": "id", "created_at": parse_datetime("2019-12-27T18:11:19.117Z"), @@ -943,6 +966,12 @@ async def test_method_send_to_execution_with_all_params(self, async_client: Asyn "text": {"content": "Generate a report based on the latest logs."}, }, wake_event={ + "devcontainer_rebuild": { + "environment_id": "environmentId", + "failure_message": ["string"], + "phase": "phase", + "session_id": "sessionId", + }, "environment": { "environment_id": "environmentId", "failure_message": ["string"], @@ -1025,6 +1054,11 @@ async def test_method_start_execution_with_all_params(self, async_client: AsyncG "url": "url", }, }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, mode="AGENT_MODE_UNSPECIFIED", name="name", runner_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", diff --git a/tests/api_resources/test_automations.py b/tests/api_resources/test_automations.py index f1412921..257d2436 100644 --- a/tests/api_resources/test_automations.py +++ b/tests/api_resources/test_automations.py @@ -70,6 +70,11 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: } ], }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, description="description", executor={ "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -113,6 +118,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -212,6 +218,11 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: } ], }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, description="description", disabled=True, executor={ @@ -256,6 +267,7 @@ def test_method_update_with_all_params(self, client: Gitpod) -> None: "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -750,6 +762,11 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> } ], }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, description="description", executor={ "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", @@ -793,6 +810,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, @@ -892,6 +910,11 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> } ], }, + codex_settings={ + "model": "CODEX_OPEN_AI_MODEL_UNSPECIFIED", + "reasoning_effort": "CODEX_REASONING_EFFORT_UNSPECIFIED", + "service_tier": "CODEX_SERVICE_TIER_UNSPECIFIED", + }, description="description", disabled=True, executor={ @@ -936,6 +959,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> "manual": {}, "pull_request": { "events": ["PULL_REQUEST_EVENT_UNSPECIFIED"], + "integration_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "webhook_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, "time": {"cron_expression": "cronExpression"}, diff --git a/tests/api_resources/test_billing.py b/tests/api_resources/test_billing.py new file mode 100644 index 00000000..ec7e2758 --- /dev/null +++ b/tests/api_resources/test_billing.py @@ -0,0 +1,1005 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from gitpod import Gitpod, AsyncGitpod +from tests.utils import assert_matches_type +from gitpod.types import ( + UserCostBudgetUsage, + TeamEnterpriseAIUsage, + UserCreditBudgetUsage, + BillingGetCreditUsageExportResponse, + BillingGetCreditUsageReportResponse, + BillingGetCumulativeCreditUsageResponse, + BillingGetEnterpriseAIUsageSummaryResponse, + BillingGetEnterpriseAIUsageTimeSeriesResponse, +) +from gitpod._utils import parse_datetime +from gitpod.pagination import SyncTeamUsagePage, SyncUserUsagePage, AsyncTeamUsagePage, AsyncUserUsagePage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestBilling: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_credit_usage_export(self, client: Gitpod) -> None: + billing = client.billing.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_credit_usage_export_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + group_by="CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY", + ) + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_credit_usage_export(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_credit_usage_export(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_credit_usage_report(self, client: Gitpod) -> None: + billing = client.billing.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_credit_usage_report_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + timezone="timezone", + ) + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_credit_usage_report(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_credit_usage_report(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_cumulative_credit_usage(self, client: Gitpod) -> None: + billing = client.billing.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_cumulative_credit_usage_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + as_of=parse_datetime("2026-03-31T23:59:59Z"), + ) + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_cumulative_credit_usage(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_cumulative_credit_usage(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_enterprise_ai_usage_summary(self, client: Gitpod) -> None: + billing = client.billing.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_enterprise_ai_usage_summary_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + timezone="timezone", + ) + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_enterprise_ai_usage_summary(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_enterprise_ai_usage_summary(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_enterprise_ai_usage_time_series(self, client: Gitpod) -> None: + billing = client.billing.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_enterprise_ai_usage_time_series_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + timezone="timezone", + ) + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_enterprise_ai_usage_time_series(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_enterprise_ai_usage_time_series(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_ai_team_usage(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(SyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_ai_team_usage_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + filter={"team_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"]}, + pagination={ + "token": "token", + "page_size": 100, + }, + timezone="timezone", + ) + assert_matches_type(SyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_enterprise_ai_team_usage(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(SyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_enterprise_ai_team_usage(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(SyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_ai_user_usage(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(SyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_ai_user_usage_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + pagination={ + "token": "token", + "page_size": 100, + }, + sort={ + "field": "SORT_FIELD_UNSPECIFIED", + "order": "SORT_ORDER_UNSPECIFIED", + }, + timezone="timezone", + ) + assert_matches_type(SyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_enterprise_ai_user_usage(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(SyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_enterprise_ai_user_usage(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(SyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_user_credit_usage(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(SyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_enterprise_user_credit_usage_with_all_params(self, client: Gitpod) -> None: + billing = client.billing.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + as_of=parse_datetime("2019-12-27T18:11:19.117Z"), + pagination={ + "token": "token", + "page_size": 50, + }, + sort={ + "field": "SORT_FIELD_UNSPECIFIED", + "order": "SORT_ORDER_UNSPECIFIED", + }, + ) + assert_matches_type(SyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list_enterprise_user_credit_usage(self, client: Gitpod) -> None: + response = client.billing.with_raw_response.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = response.parse() + assert_matches_type(SyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list_enterprise_user_credit_usage(self, client: Gitpod) -> None: + with client.billing.with_streaming_response.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = response.parse() + assert_matches_type(SyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncBilling: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_credit_usage_export(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_credit_usage_export_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + group_by="CREDIT_USAGE_EXPORT_GROUP_BY_DAILY_SUMMARY", + ) + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_credit_usage_export(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_credit_usage_export(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.get_credit_usage_export( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(BillingGetCreditUsageExportResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_credit_usage_report(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_credit_usage_report_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + timezone="timezone", + ) + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_credit_usage_report(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_credit_usage_report(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.get_credit_usage_report( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(BillingGetCreditUsageReportResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_cumulative_credit_usage(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_cumulative_credit_usage_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + as_of=parse_datetime("2026-03-31T23:59:59Z"), + ) + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_cumulative_credit_usage(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_cumulative_credit_usage(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.get_cumulative_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(BillingGetCumulativeCreditUsageResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_enterprise_ai_usage_summary(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_enterprise_ai_usage_summary_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + timezone="timezone", + ) + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_enterprise_ai_usage_summary(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_enterprise_ai_usage_summary(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.get_enterprise_ai_usage_summary( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageSummaryResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_enterprise_ai_usage_time_series(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_enterprise_ai_usage_time_series_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + timezone="timezone", + ) + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_enterprise_ai_usage_time_series(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_enterprise_ai_usage_time_series(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.get_enterprise_ai_usage_time_series( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(BillingGetEnterpriseAIUsageTimeSeriesResponse, billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_ai_team_usage(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AsyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_ai_team_usage_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + filter={"team_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"]}, + pagination={ + "token": "token", + "page_size": 100, + }, + timezone="timezone", + ) + assert_matches_type(AsyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_enterprise_ai_team_usage(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(AsyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_enterprise_ai_team_usage(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.list_enterprise_ai_team_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(AsyncTeamUsagePage[TeamEnterpriseAIUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_ai_user_usage(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AsyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_ai_user_usage_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + filter={ + "subject": { + "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", + "principal": "PRINCIPAL_UNSPECIFIED", + } + }, + pagination={ + "token": "token", + "page_size": 100, + }, + sort={ + "field": "SORT_FIELD_UNSPECIFIED", + "order": "SORT_ORDER_UNSPECIFIED", + }, + timezone="timezone", + ) + assert_matches_type(AsyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_enterprise_ai_user_usage(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(AsyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_enterprise_ai_user_usage(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.list_enterprise_ai_user_usage( + date_range={ + "end_time": parse_datetime("2024-01-31T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(AsyncUserUsagePage[UserCostBudgetUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_user_credit_usage(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(AsyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_enterprise_user_credit_usage_with_all_params(self, async_client: AsyncGitpod) -> None: + billing = await async_client.billing.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + token="token", + page_size=0, + as_of=parse_datetime("2019-12-27T18:11:19.117Z"), + pagination={ + "token": "token", + "page_size": 50, + }, + sort={ + "field": "SORT_FIELD_UNSPECIFIED", + "order": "SORT_ORDER_UNSPECIFIED", + }, + ) + assert_matches_type(AsyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list_enterprise_user_credit_usage(self, async_client: AsyncGitpod) -> None: + response = await async_client.billing.with_raw_response.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + billing = await response.parse() + assert_matches_type(AsyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list_enterprise_user_credit_usage(self, async_client: AsyncGitpod) -> None: + async with async_client.billing.with_streaming_response.list_enterprise_user_credit_usage( + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + billing = await response.parse() + assert_matches_type(AsyncUserUsagePage[UserCreditBudgetUsage], billing, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_environments.py b/tests/api_resources/test_environments.py index 0b44c1c4..969a5688 100644 --- a/tests/api_resources/test_environments.py +++ b/tests/api_resources/test_environments.py @@ -108,7 +108,6 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "api_only": True, "container_registry_basic_auth_host": "containerRegistryBasicAuthHost", "credential_proxy": { - "format": "FORMAT_UNSPECIFIED", "header": "header", "target_hosts": ["string"], }, @@ -487,7 +486,6 @@ def test_method_create_from_project_with_all_params(self, client: Gitpod) -> Non "api_only": True, "container_registry_basic_auth_host": "containerRegistryBasicAuthHost", "credential_proxy": { - "format": "FORMAT_UNSPECIFIED", "header": "header", "target_hosts": ["string"], }, @@ -808,7 +806,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "api_only": True, "container_registry_basic_auth_host": "containerRegistryBasicAuthHost", "credential_proxy": { - "format": "FORMAT_UNSPECIFIED", "header": "header", "target_hosts": ["string"], }, @@ -1187,7 +1184,6 @@ async def test_method_create_from_project_with_all_params(self, async_client: As "api_only": True, "container_registry_basic_auth_host": "containerRegistryBasicAuthHost", "credential_proxy": { - "format": "FORMAT_UNSPECIFIED", "header": "header", "target_hosts": ["string"], }, diff --git a/tests/api_resources/test_errors.py b/tests/api_resources/test_errors.py deleted file mode 100644 index 5e342a29..00000000 --- a/tests/api_resources/test_errors.py +++ /dev/null @@ -1,224 +0,0 @@ -# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -from __future__ import annotations - -import os -from typing import Any, cast - -import pytest - -from gitpod import Gitpod, AsyncGitpod -from tests.utils import assert_matches_type -from gitpod._utils import parse_datetime - -base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") - - -class TestErrors: - parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_report_errors(self, client: Gitpod) -> None: - error = client.errors.report_errors() - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_method_report_errors_with_all_params(self, client: Gitpod) -> None: - error = client.errors.report_errors( - events=[ - { - "breadcrumbs": [ - { - "category": "category", - "data": {"foo": "string"}, - "level": "ERROR_LEVEL_UNSPECIFIED", - "message": "message", - "timestamp": parse_datetime("2019-12-27T18:11:19.117Z"), - "type": "type", - } - ], - "environment": "environment", - "event_id": "210b9798eb53baa4e69d31c1071cf03d", - "exceptions": [ - { - "mechanism": { - "data": {"foo": "string"}, - "description": "description", - "handled": True, - "synthetic": True, - "type": "x", - }, - "module": "module", - "stacktrace": [ - { - "colno": 0, - "context_line": "contextLine", - "filename": "filename", - "function": "function", - "in_app": True, - "lineno": 0, - "module": "module", - "post_context": ["string"], - "pre_context": ["string"], - "vars": {"foo": "string"}, - } - ], - "thread_id": "threadId", - "type": "x", - "value": "value", - } - ], - "extra": {"foo": "string"}, - "fingerprint": ["x"], - "identity_id": "ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c", - "level": "ERROR_LEVEL_UNSPECIFIED", - "logger": "logger", - "modules": {"foo": "string"}, - "platform": "x", - "release": "release", - "request": { - "data": "data", - "headers": {"foo": "string"}, - "method": "method", - "query_string": {"foo": "string"}, - "url": "url", - }, - "sdk": {"foo": "string"}, - "server_name": "serverName", - "tags": {"foo": "string"}, - "timestamp": parse_datetime("2019-12-27T18:11:19.117Z"), - "transaction": "transaction", - } - ], - ) - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_raw_response_report_errors(self, client: Gitpod) -> None: - response = client.errors.with_raw_response.report_errors() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - error = response.parse() - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - def test_streaming_response_report_errors(self, client: Gitpod) -> None: - with client.errors.with_streaming_response.report_errors() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - error = response.parse() - assert_matches_type(object, error, path=["response"]) - - assert cast(Any, response.is_closed) is True - - -class TestAsyncErrors: - parametrize = pytest.mark.parametrize( - "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] - ) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_report_errors(self, async_client: AsyncGitpod) -> None: - error = await async_client.errors.report_errors() - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_method_report_errors_with_all_params(self, async_client: AsyncGitpod) -> None: - error = await async_client.errors.report_errors( - events=[ - { - "breadcrumbs": [ - { - "category": "category", - "data": {"foo": "string"}, - "level": "ERROR_LEVEL_UNSPECIFIED", - "message": "message", - "timestamp": parse_datetime("2019-12-27T18:11:19.117Z"), - "type": "type", - } - ], - "environment": "environment", - "event_id": "210b9798eb53baa4e69d31c1071cf03d", - "exceptions": [ - { - "mechanism": { - "data": {"foo": "string"}, - "description": "description", - "handled": True, - "synthetic": True, - "type": "x", - }, - "module": "module", - "stacktrace": [ - { - "colno": 0, - "context_line": "contextLine", - "filename": "filename", - "function": "function", - "in_app": True, - "lineno": 0, - "module": "module", - "post_context": ["string"], - "pre_context": ["string"], - "vars": {"foo": "string"}, - } - ], - "thread_id": "threadId", - "type": "x", - "value": "value", - } - ], - "extra": {"foo": "string"}, - "fingerprint": ["x"], - "identity_id": "ecc2efdd-ddfa-31a9-c6f1-b833d337aa7c", - "level": "ERROR_LEVEL_UNSPECIFIED", - "logger": "logger", - "modules": {"foo": "string"}, - "platform": "x", - "release": "release", - "request": { - "data": "data", - "headers": {"foo": "string"}, - "method": "method", - "query_string": {"foo": "string"}, - "url": "url", - }, - "sdk": {"foo": "string"}, - "server_name": "serverName", - "tags": {"foo": "string"}, - "timestamp": parse_datetime("2019-12-27T18:11:19.117Z"), - "transaction": "transaction", - } - ], - ) - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_raw_response_report_errors(self, async_client: AsyncGitpod) -> None: - response = await async_client.errors.with_raw_response.report_errors() - - assert response.is_closed is True - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - error = await response.parse() - assert_matches_type(object, error, path=["response"]) - - @pytest.mark.skip(reason="Mock server tests are disabled") - @parametrize - async def test_streaming_response_report_errors(self, async_client: AsyncGitpod) -> None: - async with async_client.errors.with_streaming_response.report_errors() as response: - assert not response.is_closed - assert response.http_request.headers.get("X-Stainless-Lang") == "python" - - error = await response.parse() - assert_matches_type(object, error, path=["response"]) - - assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_events.py b/tests/api_resources/test_events.py index dc84a57e..0bff6108 100644 --- a/tests/api_resources/test_events.py +++ b/tests/api_resources/test_events.py @@ -9,7 +9,11 @@ from gitpod import Gitpod, AsyncGitpod from tests.utils import assert_matches_type -from gitpod.types import EventListResponse, EventWatchResponse +from gitpod.types import ( + EventListResponse, + EventWatchResponse, + EventRetrieveResponse, +) from gitpod._utils import parse_datetime from gitpod.pagination import SyncEntriesPage, AsyncEntriesPage @@ -19,6 +23,40 @@ class TestEvents: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Gitpod) -> None: + event = client.events.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Gitpod) -> None: + response = client.events.with_raw_response.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Gitpod) -> None: + with client.events.with_streaming_response.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_list(self, client: Gitpod) -> None: @@ -125,6 +163,40 @@ class TestAsyncEvents: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncGitpod) -> None: + event = await async_client.events.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncGitpod) -> None: + response = await async_client.events.with_raw_response.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + event = await response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncGitpod) -> None: + async with async_client.events.with_streaming_response.retrieve( + audit_log_entry_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + event = await response.parse() + assert_matches_type(EventRetrieveResponse, event, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_list(self, async_client: AsyncGitpod) -> None: diff --git a/tests/api_resources/test_runners.py b/tests/api_resources/test_runners.py index 3a7c4506..15517f08 100644 --- a/tests/api_resources/test_runners.py +++ b/tests/api_resources/test_runners.py @@ -21,7 +21,7 @@ RunnerCheckRepositoryAccessResponse, RunnerCheckAuthenticationForHostResponse, ) -from gitpod.pagination import SyncRunnersPage, AsyncRunnersPage +from gitpod.pagination import SyncRunnersPage, AsyncRunnersPage, SyncOrganizationsPage, AsyncOrganizationsPage base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") @@ -40,8 +40,8 @@ def test_method_create(self, client: Gitpod) -> None: def test_method_create_with_all_params(self, client: Gitpod) -> None: runner = client.runners.create( kind="RUNNER_KIND_UNSPECIFIED", - name="Production Runner", - provider="RUNNER_PROVIDER_AWS_EC2", + name="GCP Runner", + provider="RUNNER_PROVIDER_GCP", runner_manager_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", spec={ "configuration": { @@ -55,7 +55,7 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "url": "url", "username": "username", }, - "region": "us-west", + "region": "us-central1", "release_channel": "RUNNER_RELEASE_CHANNEL_STABLE", "update_window": { "end_hour": 0, @@ -416,7 +416,7 @@ def test_streaming_response_create_runner_token(self, client: Gitpod) -> None: @parametrize def test_method_list_scm_organizations(self, client: Gitpod) -> None: runner = client.runners.list_scm_organizations() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -424,10 +424,15 @@ def test_method_list_scm_organizations_with_all_params(self, client: Gitpod) -> runner = client.runners.list_scm_organizations( token="token", page_size=0, + pagination={ + "token": "token", + "page_size": 100, + }, + query="query", runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", scm_host="github.com", ) - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -437,7 +442,7 @@ def test_raw_response_list_scm_organizations(self, client: Gitpod) -> None: assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -447,7 +452,7 @@ def test_streaming_response_list_scm_organizations(self, client: Gitpod) -> None assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(SyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) assert cast(Any, response.is_closed) is True @@ -549,8 +554,8 @@ async def test_method_create(self, async_client: AsyncGitpod) -> None: async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> None: runner = await async_client.runners.create( kind="RUNNER_KIND_UNSPECIFIED", - name="Production Runner", - provider="RUNNER_PROVIDER_AWS_EC2", + name="GCP Runner", + provider="RUNNER_PROVIDER_GCP", runner_manager_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", spec={ "configuration": { @@ -564,7 +569,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "url": "url", "username": "username", }, - "region": "us-west", + "region": "us-central1", "release_channel": "RUNNER_RELEASE_CHANNEL_STABLE", "update_window": { "end_hour": 0, @@ -925,7 +930,7 @@ async def test_streaming_response_create_runner_token(self, async_client: AsyncG @parametrize async def test_method_list_scm_organizations(self, async_client: AsyncGitpod) -> None: runner = await async_client.runners.list_scm_organizations() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -933,10 +938,15 @@ async def test_method_list_scm_organizations_with_all_params(self, async_client: runner = await async_client.runners.list_scm_organizations( token="token", page_size=0, + pagination={ + "token": "token", + "page_size": 100, + }, + query="query", runner_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", scm_host="github.com", ) - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -946,7 +956,7 @@ async def test_raw_response_list_scm_organizations(self, async_client: AsyncGitp assert response.is_closed is True assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = await response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize @@ -956,7 +966,7 @@ async def test_streaming_response_list_scm_organizations(self, async_client: Asy assert response.http_request.headers.get("X-Stainless-Lang") == "python" runner = await response.parse() - assert_matches_type(RunnerListScmOrganizationsResponse, runner, path=["response"]) + assert_matches_type(AsyncOrganizationsPage[RunnerListScmOrganizationsResponse], runner, path=["response"]) assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_secrets.py b/tests/api_resources/test_secrets.py index cbed1cda..66cae944 100644 --- a/tests/api_resources/test_secrets.py +++ b/tests/api_resources/test_secrets.py @@ -34,6 +34,10 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: secret = client.secrets.create( api_only=True, container_registry_basic_auth_host="containerRegistryBasicAuthHost", + credential_proxy={ + "header": "header", + "target_hosts": ["string"], + }, environment_variable=True, file_path="filePath", name="DATABASE_URL", @@ -44,6 +48,13 @@ def test_method_create_with_all_params(self, client: Gitpod) -> None: "service_account_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "user_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, + source={ + "oidc_jfrog": { + "host": "x", + "provider_name": "x", + }, + "verbatim": True, + }, value="postgresql://user:pass@localhost:5432/db", ) assert_matches_type(SecretCreateResponse, secret, path=["response"]) @@ -247,6 +258,10 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> secret = await async_client.secrets.create( api_only=True, container_registry_basic_auth_host="containerRegistryBasicAuthHost", + credential_proxy={ + "header": "header", + "target_hosts": ["string"], + }, environment_variable=True, file_path="filePath", name="DATABASE_URL", @@ -257,6 +272,13 @@ async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> "service_account_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "user_id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", }, + source={ + "oidc_jfrog": { + "host": "x", + "provider_name": "x", + }, + "verbatim": True, + }, value="postgresql://user:pass@localhost:5432/db", ) assert_matches_type(SecretCreateResponse, secret, path=["response"]) diff --git a/tests/api_resources/test_security_policies.py b/tests/api_resources/test_security_policies.py new file mode 100644 index 00000000..99294e0b --- /dev/null +++ b/tests/api_resources/test_security_policies.py @@ -0,0 +1,492 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +import os +from typing import Any, cast + +import pytest + +from gitpod import Gitpod, AsyncGitpod +from tests.utils import assert_matches_type +from gitpod.types import ( + SecurityPolicy, + SecurityPolicyCreateResponse, + SecurityPolicyUpdateResponse, + SecurityPolicyRetrieveResponse, +) +from gitpod.pagination import SyncSecurityPoliciesPage, AsyncSecurityPoliciesPage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") + + +class TestSecurityPolicies: + parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create(self, client: Gitpod) -> None: + security_policy = client.security_policies.create( + metadata={}, + spec={}, + ) + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_create_with_all_params(self, client: Gitpod) -> None: + security_policy = client.security_policies.create( + metadata={"name": "Veto Exec audit-first"}, + spec={ + "executables": { + "default_effect": "EFFECT_ALLOW", + "rules": [ + { + "effect": "EFFECT_AUDIT", + "path": "npx", + }, + { + "effect": "EFFECT_BLOCK", + "path": "/usr/bin/curl", + }, + ], + } + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_create(self, client: Gitpod) -> None: + response = client.security_policies.with_raw_response.create( + metadata={}, + spec={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = response.parse() + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_create(self, client: Gitpod) -> None: + with client.security_policies.with_streaming_response.create( + metadata={}, + spec={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = response.parse() + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve(self, client: Gitpod) -> None: + security_policy = client.security_policies.retrieve() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_retrieve_with_all_params(self, client: Gitpod) -> None: + security_policy = client.security_policies.retrieve( + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_retrieve(self, client: Gitpod) -> None: + response = client.security_policies.with_raw_response.retrieve() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = response.parse() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_retrieve(self, client: Gitpod) -> None: + with client.security_policies.with_streaming_response.retrieve() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = response.parse() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update(self, client: Gitpod) -> None: + security_policy = client.security_policies.update() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params(self, client: Gitpod) -> None: + security_policy = client.security_policies.update( + metadata={"name": "x"}, + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + spec={ + "executables": { + "default_effect": "EFFECT_ALLOW", + "rules": [ + { + "effect": "EFFECT_BLOCK", + "path": "npx", + }, + { + "effect": "EFFECT_BLOCK", + "path": "/usr/bin/curl", + }, + ], + } + }, + ) + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update(self, client: Gitpod) -> None: + response = client.security_policies.with_raw_response.update() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = response.parse() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update(self, client: Gitpod) -> None: + with client.security_policies.with_streaming_response.update() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = response.parse() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list(self, client: Gitpod) -> None: + security_policy = client.security_policies.list() + assert_matches_type(SyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_list_with_all_params(self, client: Gitpod) -> None: + security_policy = client.security_policies.list( + token="token", + page_size=0, + filter={ + "organization_id": "b0e12f6c-4c67-429d-a4a6-d9838b5da047", + "search": "search", + "security_policy_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + }, + pagination={ + "token": "token", + "page_size": 20, + }, + ) + assert_matches_type(SyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_list(self, client: Gitpod) -> None: + response = client.security_policies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = response.parse() + assert_matches_type(SyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_list(self, client: Gitpod) -> None: + with client.security_policies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = response.parse() + assert_matches_type(SyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete(self, client: Gitpod) -> None: + security_policy = client.security_policies.delete() + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_delete_with_all_params(self, client: Gitpod) -> None: + security_policy = client.security_policies.delete( + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_delete(self, client: Gitpod) -> None: + response = client.security_policies.with_raw_response.delete() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = response.parse() + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_delete(self, client: Gitpod) -> None: + with client.security_policies.with_streaming_response.delete() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = response.parse() + assert_matches_type(object, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + +class TestAsyncSecurityPolicies: + parametrize = pytest.mark.parametrize( + "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.create( + metadata={}, + spec={}, + ) + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_create_with_all_params(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.create( + metadata={"name": "Veto Exec audit-first"}, + spec={ + "executables": { + "default_effect": "EFFECT_ALLOW", + "rules": [ + { + "effect": "EFFECT_AUDIT", + "path": "npx", + }, + { + "effect": "EFFECT_BLOCK", + "path": "/usr/bin/curl", + }, + ], + } + }, + organization_id="b0e12f6c-4c67-429d-a4a6-d9838b5da047", + ) + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_create(self, async_client: AsyncGitpod) -> None: + response = await async_client.security_policies.with_raw_response.create( + metadata={}, + spec={}, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = await response.parse() + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_create(self, async_client: AsyncGitpod) -> None: + async with async_client.security_policies.with_streaming_response.create( + metadata={}, + spec={}, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = await response.parse() + assert_matches_type(SecurityPolicyCreateResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.retrieve() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_retrieve_with_all_params(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.retrieve( + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_retrieve(self, async_client: AsyncGitpod) -> None: + response = await async_client.security_policies.with_raw_response.retrieve() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = await response.parse() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_retrieve(self, async_client: AsyncGitpod) -> None: + async with async_client.security_policies.with_streaming_response.retrieve() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = await response.parse() + assert_matches_type(SecurityPolicyRetrieveResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.update() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.update( + metadata={"name": "x"}, + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + spec={ + "executables": { + "default_effect": "EFFECT_ALLOW", + "rules": [ + { + "effect": "EFFECT_BLOCK", + "path": "npx", + }, + { + "effect": "EFFECT_BLOCK", + "path": "/usr/bin/curl", + }, + ], + } + }, + ) + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update(self, async_client: AsyncGitpod) -> None: + response = await async_client.security_policies.with_raw_response.update() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = await response.parse() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update(self, async_client: AsyncGitpod) -> None: + async with async_client.security_policies.with_streaming_response.update() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = await response.parse() + assert_matches_type(SecurityPolicyUpdateResponse, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.list() + assert_matches_type(AsyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_list_with_all_params(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.list( + token="token", + page_size=0, + filter={ + "organization_id": "b0e12f6c-4c67-429d-a4a6-d9838b5da047", + "search": "search", + "security_policy_ids": ["182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"], + }, + pagination={ + "token": "token", + "page_size": 20, + }, + ) + assert_matches_type(AsyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_list(self, async_client: AsyncGitpod) -> None: + response = await async_client.security_policies.with_raw_response.list() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = await response.parse() + assert_matches_type(AsyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_list(self, async_client: AsyncGitpod) -> None: + async with async_client.security_policies.with_streaming_response.list() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = await response.parse() + assert_matches_type(AsyncSecurityPoliciesPage[SecurityPolicy], security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.delete() + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_delete_with_all_params(self, async_client: AsyncGitpod) -> None: + security_policy = await async_client.security_policies.delete( + security_policy_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + ) + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_delete(self, async_client: AsyncGitpod) -> None: + response = await async_client.security_policies.with_raw_response.delete() + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + security_policy = await response.parse() + assert_matches_type(object, security_policy, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_delete(self, async_client: AsyncGitpod) -> None: + async with async_client.security_policies.with_streaming_response.delete() as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + security_policy = await response.parse() + assert_matches_type(object, security_policy, path=["response"]) + + assert cast(Any, response.is_closed) is True diff --git a/tests/api_resources/test_usage.py b/tests/api_resources/test_usage.py index 754a862e..ba6063bc 100644 --- a/tests/api_resources/test_usage.py +++ b/tests/api_resources/test_usage.py @@ -9,7 +9,16 @@ from gitpod import Gitpod, AsyncGitpod from tests.utils import assert_matches_type -from gitpod.types import EnvironmentUsageRecord +from gitpod.types import ( + EnvironmentUsageRecord, + UsageGetPrSummaryResponse, + UsageGetPrTimeSeriesResponse, + UsageGetCoAuthorSummaryResponse, + UsageGetAgentTraceSummaryResponse, + UsageGetCoAuthorTimeSeriesResponse, + UsageGetAdoptionUsageSummaryResponse, + UsageGetAgentTraceTimeSeriesResponse, +) from gitpod._utils import parse_datetime from gitpod.pagination import SyncRecordsPage, AsyncRecordsPage @@ -19,6 +28,408 @@ class TestUsage: parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"]) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_adoption_usage_summary(self, client: Gitpod) -> None: + usage = client.usage.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_adoption_usage_summary_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_adoption_usage_summary(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_adoption_usage_summary(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_agent_trace_summary(self, client: Gitpod) -> None: + usage = client.usage.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_agent_trace_summary_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_agent_trace_summary(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_agent_trace_summary(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_agent_trace_time_series(self, client: Gitpod) -> None: + usage = client.usage.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_agent_trace_time_series_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_agent_trace_time_series(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_agent_trace_time_series(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_co_author_summary(self, client: Gitpod) -> None: + usage = client.usage.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_co_author_summary_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_co_author_summary(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_co_author_summary(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_co_author_time_series(self, client: Gitpod) -> None: + usage = client.usage.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_co_author_time_series_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_co_author_time_series(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_co_author_time_series(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_pr_summary(self, client: Gitpod) -> None: + usage = client.usage.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_pr_summary_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_pr_summary(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_pr_summary(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_pr_time_series(self, client: Gitpod) -> None: + usage = client.usage.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_get_pr_time_series_with_all_params(self, client: Gitpod) -> None: + usage = client.usage.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_get_pr_time_series(self, client: Gitpod) -> None: + response = client.usage.with_raw_response.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = response.parse() + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_get_pr_time_series(self, client: Gitpod) -> None: + with client.usage.with_streaming_response.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = response.parse() + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_list_environment_runtime_records(self, client: Gitpod) -> None: @@ -73,6 +484,408 @@ class TestAsyncUsage: "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"] ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_adoption_usage_summary(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_adoption_usage_summary_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_adoption_usage_summary(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_adoption_usage_summary(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_adoption_usage_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetAdoptionUsageSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_agent_trace_summary(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_agent_trace_summary_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_agent_trace_summary(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_agent_trace_summary(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_agent_trace_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetAgentTraceSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_agent_trace_time_series(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_agent_trace_time_series_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_agent_trace_time_series(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_agent_trace_time_series(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_agent_trace_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetAgentTraceTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_co_author_summary(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_co_author_summary_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_co_author_summary(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_co_author_summary(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_co_author_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetCoAuthorSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_co_author_time_series(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_co_author_time_series_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_co_author_time_series(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_co_author_time_series(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_co_author_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetCoAuthorTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_pr_summary(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_pr_summary_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_pr_summary(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_pr_summary(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_pr_summary( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetPrSummaryResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_pr_time_series(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_get_pr_time_series_with_all_params(self, async_client: AsyncGitpod) -> None: + usage = await async_client.usage.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + project_id="d2c94c27-3b76-4a42-b88c-95a85e392c68", + resolution="RESOLUTION_WEEKLY", + team_id="teamId", + user_id="userId", + ) + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_get_pr_time_series(self, async_client: AsyncGitpod) -> None: + response = await async_client.usage.with_raw_response.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + usage = await response.parse() + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_get_pr_time_series(self, async_client: AsyncGitpod) -> None: + async with async_client.usage.with_streaming_response.get_pr_time_series( + date_range={ + "end_time": parse_datetime("2024-02-01T00:00:00Z"), + "start_time": parse_datetime("2024-01-01T00:00:00Z"), + }, + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + usage = await response.parse() + assert_matches_type(UsageGetPrTimeSeriesResponse, usage, path=["response"]) + + assert cast(Any, response.is_closed) is True + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_list_environment_runtime_records(self, async_client: AsyncGitpod) -> None: diff --git a/tests/test_client.py b/tests/test_client.py index 92b0eea3..c105b4d9 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -438,6 +438,30 @@ def test_default_query_option(self) -> None: client.close() + def test_hardcoded_query_params_in_url(self, client: Gitpod) -> None: + request = client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Gitpod) -> None: request = client._build_request( FinalRequestOptions( @@ -1363,6 +1387,30 @@ async def test_default_query_option(self) -> None: await client.close() + async def test_hardcoded_query_params_in_url(self, async_client: AsyncGitpod) -> None: + request = async_client._build_request(FinalRequestOptions(method="get", url="/foo?beta=true")) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/foo?beta=true", + params={"limit": "10", "page": "abc"}, + ) + ) + url = httpx.URL(request.url) + assert dict(url.params) == {"beta": "true", "limit": "10", "page": "abc"} + + request = async_client._build_request( + FinalRequestOptions( + method="get", + url="/files/a%2Fb?beta=true", + params={"limit": "10"}, + ) + ) + assert request.url.raw_path == b"/files/a%2Fb?beta=true&limit=10" + def test_request_extra_json(self, client: Gitpod) -> None: request = client._build_request( FinalRequestOptions( diff --git a/tests/test_deepcopy.py b/tests/test_deepcopy.py deleted file mode 100644 index c498f531..00000000 --- a/tests/test_deepcopy.py +++ /dev/null @@ -1,58 +0,0 @@ -from gitpod._utils import deepcopy_minimal - - -def assert_different_identities(obj1: object, obj2: object) -> None: - assert obj1 == obj2 - assert id(obj1) != id(obj2) - - -def test_simple_dict() -> None: - obj1 = {"foo": "bar"} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_dict() -> None: - obj1 = {"foo": {"bar": True}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - - -def test_complex_nested_dict() -> None: - obj1 = {"foo": {"bar": [{"hello": "world"}]}} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1["foo"], obj2["foo"]) - assert_different_identities(obj1["foo"]["bar"], obj2["foo"]["bar"]) - assert_different_identities(obj1["foo"]["bar"][0], obj2["foo"]["bar"][0]) - - -def test_simple_list() -> None: - obj1 = ["a", "b", "c"] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - - -def test_nested_list() -> None: - obj1 = ["a", [1, 2, 3]] - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert_different_identities(obj1[1], obj2[1]) - - -class MyObject: ... - - -def test_ignores_other_types() -> None: - # custom classes - my_obj = MyObject() - obj1 = {"foo": my_obj} - obj2 = deepcopy_minimal(obj1) - assert_different_identities(obj1, obj2) - assert obj1["foo"] is my_obj - - # tuples - obj3 = ("a", "b") - obj4 = deepcopy_minimal(obj3) - assert obj3 is obj4 diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index 0ca5a8dc..4a107218 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -4,7 +4,7 @@ import pytest -from gitpod._types import FileTypes +from gitpod._types import FileTypes, ArrayFormat from gitpod._utils import extract_files @@ -35,6 +35,12 @@ def test_multiple_files() -> None: assert query == {"documents": [{}, {}]} +def test_top_level_file_array() -> None: + query = {"files": [b"file one", b"file two"], "title": "hello"} + assert extract_files(query, paths=[["files", ""]]) == [("files[]", b"file one"), ("files[]", b"file two")] + assert query == {"title": "hello"} + + @pytest.mark.parametrize( "query,paths,expected", [ @@ -62,3 +68,24 @@ def test_ignores_incorrect_paths( expected: list[tuple[str, FileTypes]], ) -> None: assert extract_files(query, paths=paths) == expected + + +@pytest.mark.parametrize( + "array_format,expected_top_level,expected_nested", + [ + ("brackets", [("files[]", b"a"), ("files[]", b"b")], [("items[][file]", b"a"), ("items[][file]", b"b")]), + ("repeat", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("comma", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("indices", [("files[0]", b"a"), ("files[1]", b"b")], [("items[0][file]", b"a"), ("items[1][file]", b"b")]), + ], +) +def test_array_format_controls_file_field_names( + array_format: ArrayFormat, + expected_top_level: list[tuple[str, FileTypes]], + expected_nested: list[tuple[str, FileTypes]], +) -> None: + top_level = {"files": [b"a", b"b"]} + assert extract_files(top_level, paths=[["files", ""]], array_format=array_format) == expected_top_level + + nested = {"items": [{"file": b"a"}, {"file": b"b"}]} + assert extract_files(nested, paths=[["items", "", "file"]], array_format=array_format) == expected_nested diff --git a/tests/test_files.py b/tests/test_files.py index efde0d4e..d8f636ba 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -4,7 +4,8 @@ import pytest from dirty_equals import IsDict, IsList, IsBytes, IsTuple -from gitpod._files import to_httpx_files, async_to_httpx_files +from gitpod._files import to_httpx_files, deepcopy_with_paths, async_to_httpx_files +from gitpod._utils import extract_files readme_path = Path(__file__).parent.parent.joinpath("README.md") @@ -49,3 +50,99 @@ def test_string_not_allowed() -> None: "file": "foo", # type: ignore } ) + + +def assert_different_identities(obj1: object, obj2: object) -> None: + assert obj1 == obj2 + assert obj1 is not obj2 + + +class TestDeepcopyWithPaths: + def test_copies_top_level_dict(self) -> None: + original = {"file": b"data", "other": "value"} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + + def test_file_value_is_same_reference(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes} + result = deepcopy_with_paths(original, [["file"]]) + assert_different_identities(result, original) + assert result["file"] is file_bytes + + def test_list_popped_wholesale(self) -> None: + files = [b"f1", b"f2"] + original = {"files": files, "title": "t"} + result = deepcopy_with_paths(original, [["files", ""]]) + assert_different_identities(result, original) + result_files = result["files"] + assert isinstance(result_files, list) + assert_different_identities(result_files, files) + + def test_nested_array_path_copies_list_and_elements(self) -> None: + elem1 = {"file": b"f1", "extra": 1} + elem2 = {"file": b"f2", "extra": 2} + original = {"items": [elem1, elem2]} + result = deepcopy_with_paths(original, [["items", "", "file"]]) + assert_different_identities(result, original) + result_items = result["items"] + assert isinstance(result_items, list) + assert_different_identities(result_items, original["items"]) + assert_different_identities(result_items[0], elem1) + assert_different_identities(result_items[1], elem2) + + def test_empty_paths_returns_same_object(self) -> None: + original = {"foo": "bar"} + result = deepcopy_with_paths(original, []) + assert result is original + + def test_multiple_paths(self) -> None: + f1 = b"file1" + f2 = b"file2" + original = {"a": f1, "b": f2, "c": "unchanged"} + result = deepcopy_with_paths(original, [["a"], ["b"]]) + assert_different_identities(result, original) + assert result["a"] is f1 + assert result["b"] is f2 + assert result["c"] is original["c"] + + def test_extract_files_does_not_mutate_original_top_level(self) -> None: + file_bytes = b"contents" + original = {"file": file_bytes, "other": "value"} + + copied = deepcopy_with_paths(original, [["file"]]) + extracted = extract_files(copied, paths=[["file"]]) + + assert extracted == [("file", file_bytes)] + assert original == {"file": file_bytes, "other": "value"} + assert copied == {"other": "value"} + + def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None: + file1 = b"f1" + file2 = b"f2" + original = { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + + copied = deepcopy_with_paths(original, [["items", "", "file"]]) + extracted = extract_files(copied, paths=[["items", "", "file"]]) + + assert [entry for _, entry in extracted] == [file1, file2] + assert original == { + "items": [ + {"file": file1, "extra": 1}, + {"file": file2, "extra": 2}, + ], + "title": "example", + } + assert copied == { + "items": [ + {"extra": 1}, + {"extra": 2}, + ], + "title": "example", + } diff --git a/tests/test_models.py b/tests/test_models.py index 47fa9efd..ce2b6d8d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,7 +1,8 @@ import json -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast +from typing import TYPE_CHECKING, Any, Dict, List, Union, Iterable, Optional, cast from datetime import datetime, timezone -from typing_extensions import Literal, Annotated, TypeAliasType +from collections import deque +from typing_extensions import Literal, Annotated, TypedDict, TypeAliasType import pytest import pydantic @@ -9,7 +10,7 @@ from gitpod._utils import PropertyInfo from gitpod._compat import PYDANTIC_V1, parse_obj, model_dump, model_json -from gitpod._models import DISCRIMINATOR_CACHE, BaseModel, construct_type +from gitpod._models import DISCRIMINATOR_CACHE, BaseModel, EagerIterable, construct_type class BasicModel(BaseModel): @@ -961,3 +962,56 @@ def __getattr__(self, attr: str) -> Item: ... assert model.a.prop == 1 assert isinstance(model.a, Item) assert model.other == "foo" + + +# NOTE: Workaround for Pydantic Iterable behavior. +# Iterable fields are replaced with a ValidatorIterator and may be consumed +# during serialization, which can cause subsequent dumps to return empty data. +# See: https://github.com/pydantic/pydantic/issues/9541 +@pytest.mark.parametrize( + "data, expected_validated", + [ + ([1, 2, 3], [1, 2, 3]), + ((1, 2, 3), (1, 2, 3)), + (set([1, 2, 3]), set([1, 2, 3])), + (iter([1, 2, 3]), [1, 2, 3]), + ([], []), + ((x for x in [1, 2, 3]), [1, 2, 3]), + (map(lambda x: x, [1, 2, 3]), [1, 2, 3]), + (frozenset([1, 2, 3]), frozenset([1, 2, 3])), + (deque([1, 2, 3]), deque([1, 2, 3])), + ], + ids=["list", "tuple", "set", "iterator", "empty", "generator", "map", "frozenset", "deque"], +) +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction(data: Iterable[int], expected_validated: Iterable[int]) -> None: + class TypeWithIterable(TypedDict): + items: EagerIterable[int] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": data}}) + assert m.data["items"] == expected_validated + + # Verify repeated dumps don't lose data (the original bug) + assert m.model_dump()["data"]["items"] == list(expected_validated) + assert m.model_dump()["data"]["items"] == list(expected_validated) + + +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction_str_falls_back_to_list() -> None: + # str is iterable (over chars), but str(list_of_chars) produces the list's repr + # rather than reconstructing a string from items. We special-case str to fall + # back to list instead of attempting reconstruction. + class TypeWithIterable(TypedDict): + items: EagerIterable[str] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": "hello"}}) + + # falls back to list of chars rather than calling str(["h", "e", "l", "l", "o"]) + assert m.data["items"] == ["h", "e", "l", "l", "o"] + assert m.model_dump()["data"]["items"] == ["h", "e", "l", "l", "o"]