mainsequence 8.1.7__tar.gz → 8.1.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mainsequence-8.1.7/mainsequence.egg-info → mainsequence-8.1.8}/PKG-INFO +1 -1
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/models_helpers.py +29 -7
- {mainsequence-8.1.7 → mainsequence-8.1.8/mainsequence.egg-info}/PKG-INFO +1 -1
- {mainsequence-8.1.7 → mainsequence-8.1.8}/pyproject.toml +1 -1
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_filter_normalization.py +154 -3
- {mainsequence-8.1.7 → mainsequence-8.1.8}/LICENSE +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/MANIFEST.in +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/README.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/a2a_sdk_execution/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_publishing/meta_table_migrations/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_publishing/time_index_table_updates/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/maintenance/code_repository_maintenance/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/sdk_code_repository_execution/SKILL.md +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/__main__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/bootstrap.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/api.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/cli.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/code_repository_status.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/config.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/migrations.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/cli/ui.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/base.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/client.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/compute_validation.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/duckdb.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/local_paths.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/sqlite.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/metatables/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/metatables/core.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/models_user.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/observability.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/code_repository_context.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/code_repository_skills.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/defaults.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/logconf.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/compiled_sql/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/compiled_sql/v1.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/alembic.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/env.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/provider.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/registry.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/scaffold.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/templates/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/templates/env.py.mako +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/templates/script.py.mako +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/schema_names.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/sqlalchemy_contracts.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_refs.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/__init__.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/configuration.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/dependencies.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/managers.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/namespacing.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/runner.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/updaters.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/repository_identity_security.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/scaffold_skills.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/setup.cfg +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/fixtures/time_index_table_update_hash_v2_golden.json +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_auth_precedence.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_canonical_api_route_contract.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_cli.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_cli_migrations.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_client.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_batch_jobs_from_file.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_branch_contract.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_documentation_contract.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_runtime_context.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_skills.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_dependency_extras.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_duckdb_interface_dimensions.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_environment_resource_context.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_environment_response_contracts.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_instrumentation.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_local_ops.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_logconf.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_meta_table_migrations.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_meta_tables_sqlalchemy_contracts.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_notification_uid_contract.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_observability_client.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_scaffold_skills.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_schema_names.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_secret_client_model.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_sqlite_interface_dimensions.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_ssh_utils.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_access_dimension_audit.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_dimension_queries.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_configuration.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_configuration_client.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_flow.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_hard_cut.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_update_statistics.py +0 -0
- {mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_update_uid_guards.py +0 -0
|
@@ -1403,23 +1403,43 @@ class DeploymentRunBillingComponents(BasePydanticModel):
|
|
|
1403
1403
|
image_registry_service: Decimal | None = Field(max_digits=18, decimal_places=6)
|
|
1404
1404
|
|
|
1405
1405
|
|
|
1406
|
+
DeploymentRunPricingState = Literal[
|
|
1407
|
+
"priced",
|
|
1408
|
+
"partial",
|
|
1409
|
+
"pending",
|
|
1410
|
+
"unavailable",
|
|
1411
|
+
"failed",
|
|
1412
|
+
]
|
|
1413
|
+
|
|
1414
|
+
|
|
1406
1415
|
class DeploymentRunBilling(BasePydanticModel):
|
|
1407
1416
|
scope: Literal["image_lifecycle"]
|
|
1408
1417
|
total_cost: Decimal | None = Field(max_digits=18, decimal_places=6)
|
|
1409
1418
|
currency: str = Field(min_length=1)
|
|
1410
|
-
pricing_state:
|
|
1411
|
-
"priced",
|
|
1412
|
-
"partial",
|
|
1413
|
-
"pending",
|
|
1414
|
-
"unavailable",
|
|
1415
|
-
"failed",
|
|
1416
|
-
]
|
|
1419
|
+
pricing_state: DeploymentRunPricingState
|
|
1417
1420
|
components: DeploymentRunBillingComponents
|
|
1418
1421
|
priced_rows: int = Field(ge=0)
|
|
1419
1422
|
unpriced_rows: int = Field(ge=0)
|
|
1420
1423
|
reused_image_count: int = Field(ge=0)
|
|
1421
1424
|
|
|
1422
1425
|
|
|
1426
|
+
class DeploymentRunRuntimeBilling(BasePydanticModel):
|
|
1427
|
+
scope: Literal["knative_runtime"]
|
|
1428
|
+
total_cost: Decimal | None = Field(max_digits=18, decimal_places=6)
|
|
1429
|
+
base_cost: Decimal | None = Field(max_digits=18, decimal_places=6)
|
|
1430
|
+
currency: str = Field(min_length=1)
|
|
1431
|
+
pricing_state: DeploymentRunPricingState
|
|
1432
|
+
priced_rows: int = Field(ge=0)
|
|
1433
|
+
unpriced_rows: int = Field(ge=0)
|
|
1434
|
+
is_complete: bool
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
class DeploymentRunCostSummary(BasePydanticModel):
|
|
1438
|
+
total_cost: Decimal | None = Field(max_digits=18, decimal_places=6)
|
|
1439
|
+
currency: str = Field(min_length=1)
|
|
1440
|
+
is_complete: bool
|
|
1441
|
+
|
|
1442
|
+
|
|
1423
1443
|
class DeploymentRunLogEntry(BaseModel):
|
|
1424
1444
|
sequence: int
|
|
1425
1445
|
timestamp: datetime.datetime | None = None
|
|
@@ -1497,6 +1517,8 @@ class DeploymentRun(CurrentCodeRepositoryBranchCollectionMixin, BaseObjectOrm, B
|
|
|
1497
1517
|
logs: DeploymentRunLogReference
|
|
1498
1518
|
error: DeploymentRunError | None = None
|
|
1499
1519
|
billing: DeploymentRunBilling
|
|
1520
|
+
runtime_billing: DeploymentRunRuntimeBilling
|
|
1521
|
+
cost_summary: DeploymentRunCostSummary
|
|
1500
1522
|
|
|
1501
1523
|
def get_logs(
|
|
1502
1524
|
self,
|
|
@@ -3217,6 +3217,61 @@ def _deployment_run_billing_payload(
|
|
|
3217
3217
|
}
|
|
3218
3218
|
|
|
3219
3219
|
|
|
3220
|
+
def _deployment_run_runtime_billing_payload(
|
|
3221
|
+
*,
|
|
3222
|
+
pricing_state: str = "priced",
|
|
3223
|
+
total_cost: str | None = "0.000000",
|
|
3224
|
+
base_cost: str | None = "0.000000",
|
|
3225
|
+
is_complete: bool = True,
|
|
3226
|
+
) -> dict:
|
|
3227
|
+
return {
|
|
3228
|
+
"scope": "knative_runtime",
|
|
3229
|
+
"total_cost": total_cost,
|
|
3230
|
+
"base_cost": base_cost,
|
|
3231
|
+
"currency": "USD",
|
|
3232
|
+
"pricing_state": pricing_state,
|
|
3233
|
+
"priced_rows": 3 if pricing_state == "priced" else 0,
|
|
3234
|
+
"unpriced_rows": 0 if pricing_state == "priced" else 3,
|
|
3235
|
+
"is_complete": is_complete,
|
|
3236
|
+
}
|
|
3237
|
+
|
|
3238
|
+
|
|
3239
|
+
def _deployment_run_cost_summary_payload(
|
|
3240
|
+
*,
|
|
3241
|
+
total_cost: str | None = "0.000000",
|
|
3242
|
+
is_complete: bool = True,
|
|
3243
|
+
) -> dict:
|
|
3244
|
+
return {
|
|
3245
|
+
"total_cost": total_cost,
|
|
3246
|
+
"currency": "USD",
|
|
3247
|
+
"is_complete": is_complete,
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
|
|
3251
|
+
def _deployment_run_cost_projections(
|
|
3252
|
+
*,
|
|
3253
|
+
pricing_state: str = "priced",
|
|
3254
|
+
total_cost: str | None = "0.000000",
|
|
3255
|
+
is_complete: bool = True,
|
|
3256
|
+
) -> dict:
|
|
3257
|
+
return {
|
|
3258
|
+
"billing": _deployment_run_billing_payload(
|
|
3259
|
+
pricing_state=pricing_state,
|
|
3260
|
+
total_cost=total_cost,
|
|
3261
|
+
),
|
|
3262
|
+
"runtime_billing": _deployment_run_runtime_billing_payload(
|
|
3263
|
+
pricing_state=pricing_state,
|
|
3264
|
+
total_cost=total_cost,
|
|
3265
|
+
base_cost=total_cost,
|
|
3266
|
+
is_complete=is_complete,
|
|
3267
|
+
),
|
|
3268
|
+
"cost_summary": _deployment_run_cost_summary_payload(
|
|
3269
|
+
total_cost=total_cost,
|
|
3270
|
+
is_complete=is_complete,
|
|
3271
|
+
),
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3274
|
+
|
|
3220
3275
|
@pytest.mark.parametrize(
|
|
3221
3276
|
"pricing_state",
|
|
3222
3277
|
["priced", "partial", "pending", "unavailable", "failed"],
|
|
@@ -3273,6 +3328,91 @@ def test_deployment_run_billing_contract_is_complete_and_closed():
|
|
|
3273
3328
|
)
|
|
3274
3329
|
|
|
3275
3330
|
|
|
3331
|
+
@pytest.mark.parametrize(
|
|
3332
|
+
"pricing_state",
|
|
3333
|
+
["priced", "partial", "pending", "unavailable", "failed"],
|
|
3334
|
+
)
|
|
3335
|
+
def test_deployment_run_runtime_billing_parses_every_backend_pricing_state(
|
|
3336
|
+
pricing_state,
|
|
3337
|
+
):
|
|
3338
|
+
total_cost = "1.250000" if pricing_state in {"priced", "partial"} else None
|
|
3339
|
+
base_cost = "0.750000" if total_cost is not None else None
|
|
3340
|
+
|
|
3341
|
+
billing = models_helpers_mod.DeploymentRunRuntimeBilling.model_validate(
|
|
3342
|
+
_deployment_run_runtime_billing_payload(
|
|
3343
|
+
pricing_state=pricing_state,
|
|
3344
|
+
total_cost=total_cost,
|
|
3345
|
+
base_cost=base_cost,
|
|
3346
|
+
is_complete=pricing_state == "priced",
|
|
3347
|
+
)
|
|
3348
|
+
)
|
|
3349
|
+
|
|
3350
|
+
assert billing.pricing_state == pricing_state
|
|
3351
|
+
assert billing.total_cost == (Decimal(total_cost) if total_cost is not None else None)
|
|
3352
|
+
assert billing.base_cost == (Decimal(base_cost) if base_cost is not None else None)
|
|
3353
|
+
assert billing.is_complete is (pricing_state == "priced")
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
@pytest.mark.parametrize("total_cost", ["2.000000", None])
|
|
3357
|
+
def test_deployment_run_cost_summary_parses_nullable_decimal(total_cost):
|
|
3358
|
+
summary = models_helpers_mod.DeploymentRunCostSummary.model_validate(
|
|
3359
|
+
_deployment_run_cost_summary_payload(
|
|
3360
|
+
total_cost=total_cost,
|
|
3361
|
+
is_complete=total_cost is not None,
|
|
3362
|
+
)
|
|
3363
|
+
)
|
|
3364
|
+
|
|
3365
|
+
assert summary.total_cost == (Decimal(total_cost) if total_cost is not None else None)
|
|
3366
|
+
assert summary.is_complete is (total_cost is not None)
|
|
3367
|
+
|
|
3368
|
+
|
|
3369
|
+
@pytest.mark.parametrize(
|
|
3370
|
+
("model", "payload", "required_fields"),
|
|
3371
|
+
[
|
|
3372
|
+
(
|
|
3373
|
+
models_helpers_mod.DeploymentRunRuntimeBilling,
|
|
3374
|
+
_deployment_run_runtime_billing_payload(),
|
|
3375
|
+
(
|
|
3376
|
+
"scope",
|
|
3377
|
+
"total_cost",
|
|
3378
|
+
"base_cost",
|
|
3379
|
+
"currency",
|
|
3380
|
+
"pricing_state",
|
|
3381
|
+
"priced_rows",
|
|
3382
|
+
"unpriced_rows",
|
|
3383
|
+
"is_complete",
|
|
3384
|
+
),
|
|
3385
|
+
),
|
|
3386
|
+
(
|
|
3387
|
+
models_helpers_mod.DeploymentRunCostSummary,
|
|
3388
|
+
_deployment_run_cost_summary_payload(),
|
|
3389
|
+
("total_cost", "currency", "is_complete"),
|
|
3390
|
+
),
|
|
3391
|
+
],
|
|
3392
|
+
)
|
|
3393
|
+
def test_deployment_run_additive_billing_contracts_are_complete_and_closed(
|
|
3394
|
+
model,
|
|
3395
|
+
payload,
|
|
3396
|
+
required_fields,
|
|
3397
|
+
):
|
|
3398
|
+
for field_name in required_fields:
|
|
3399
|
+
incomplete = dict(payload)
|
|
3400
|
+
incomplete.pop(field_name)
|
|
3401
|
+
with pytest.raises(ValidationError, match=field_name):
|
|
3402
|
+
model.model_validate(incomplete)
|
|
3403
|
+
|
|
3404
|
+
with pytest.raises(ValidationError, match="extra_forbidden"):
|
|
3405
|
+
model.model_validate(payload | {"future_billing_field": "value"})
|
|
3406
|
+
|
|
3407
|
+
|
|
3408
|
+
@pytest.mark.parametrize("field_name", ["priced_rows", "unpriced_rows"])
|
|
3409
|
+
def test_deployment_run_runtime_billing_rejects_negative_counters(field_name):
|
|
3410
|
+
with pytest.raises(ValidationError, match="greater_than_equal"):
|
|
3411
|
+
models_helpers_mod.DeploymentRunRuntimeBilling.model_validate(
|
|
3412
|
+
_deployment_run_runtime_billing_payload() | {field_name: -1}
|
|
3413
|
+
)
|
|
3414
|
+
|
|
3415
|
+
|
|
3276
3416
|
def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch):
|
|
3277
3417
|
captured = {}
|
|
3278
3418
|
release_uid = "2f4c4c3d-5669-4da5-9d86-b84633c1e6ed"
|
|
@@ -3317,7 +3457,7 @@ def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch
|
|
|
3317
3457
|
"retention_expires_at": None,
|
|
3318
3458
|
},
|
|
3319
3459
|
"error": None,
|
|
3320
|
-
|
|
3460
|
+
**_deployment_run_cost_projections(),
|
|
3321
3461
|
}
|
|
3322
3462
|
|
|
3323
3463
|
def _fake_make_request(*, s, loaders, r_type, url, payload, time_out=None):
|
|
@@ -3343,6 +3483,8 @@ def test_resource_release_deploy_current_version_posts_detail_action(monkeypatch
|
|
|
3343
3483
|
assert run.logs.state == "available"
|
|
3344
3484
|
assert run.error is None
|
|
3345
3485
|
assert run.billing.total_cost == Decimal("0.000000")
|
|
3486
|
+
assert run.runtime_billing.scope == "knative_runtime"
|
|
3487
|
+
assert run.cost_summary.is_complete is True
|
|
3346
3488
|
assert captured == {
|
|
3347
3489
|
"r_type": "POST",
|
|
3348
3490
|
"url": (
|
|
@@ -3386,7 +3528,7 @@ def test_deployment_run_collection_and_detail_use_unified_resource_release_contr
|
|
|
3386
3528
|
"retention_expires_at": None,
|
|
3387
3529
|
},
|
|
3388
3530
|
"error": None,
|
|
3389
|
-
|
|
3531
|
+
**_deployment_run_cost_projections(),
|
|
3390
3532
|
}
|
|
3391
3533
|
|
|
3392
3534
|
collection_payload = {
|
|
@@ -3444,6 +3586,10 @@ def test_deployment_run_collection_and_detail_use_unified_resource_release_contr
|
|
|
3444
3586
|
assert detail.error is None
|
|
3445
3587
|
assert runs[0].billing.pricing_state == "priced"
|
|
3446
3588
|
assert detail.billing.components.image_registry_storage == Decimal("0.000000")
|
|
3589
|
+
assert runs[0].runtime_billing.is_complete is True
|
|
3590
|
+
assert detail.runtime_billing.base_cost == Decimal("0.000000")
|
|
3591
|
+
assert runs[0].cost_summary.total_cost == Decimal("0.000000")
|
|
3592
|
+
assert detail.cost_summary.currency == "USD"
|
|
3447
3593
|
assert captured[0]["payload"] == {
|
|
3448
3594
|
"params": {
|
|
3449
3595
|
"code_repository_branch_uid": CODE_REPOSITORY_BRANCH_UID,
|
|
@@ -3483,9 +3629,10 @@ def test_unified_deployment_run_models_and_filters(monkeypatch):
|
|
|
3483
3629
|
"retention_expires_at": None,
|
|
3484
3630
|
},
|
|
3485
3631
|
"error": None,
|
|
3486
|
-
|
|
3632
|
+
**_deployment_run_cost_projections(
|
|
3487
3633
|
pricing_state="pending",
|
|
3488
3634
|
total_cost=None,
|
|
3635
|
+
is_complete=False,
|
|
3489
3636
|
),
|
|
3490
3637
|
}
|
|
3491
3638
|
)
|
|
@@ -3506,6 +3653,10 @@ def test_unified_deployment_run_models_and_filters(monkeypatch):
|
|
|
3506
3653
|
assert run.builder_runtime == "nodejs22"
|
|
3507
3654
|
assert run.billing.pricing_state == "pending"
|
|
3508
3655
|
assert run.billing.total_cost is None
|
|
3656
|
+
assert run.runtime_billing.pricing_state == "pending"
|
|
3657
|
+
assert run.runtime_billing.base_cost is None
|
|
3658
|
+
assert run.cost_summary.total_cost is None
|
|
3659
|
+
assert run.cost_summary.is_complete is False
|
|
3509
3660
|
assert normalized == {
|
|
3510
3661
|
"code_repository_branch_uid": code_repository_branch_uid,
|
|
3511
3662
|
"target_type__in": ["resource_release", "static_site"],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_access/exploration/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/__init__.py
RENAMED
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/local_paths.py
RENAMED
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/templates/__init__.py
RENAMED
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/migrations/templates/env.py.mako
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/mainsequence/meta_tables/time_index_table_updates/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/fixtures/time_index_table_update_hash_v2_golden.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_batch_jobs_from_file.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_code_repository_documentation_contract.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_access_dimension_audit.py
RENAMED
|
File without changes
|
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_configuration.py
RENAMED
|
File without changes
|
{mainsequence-8.1.7 → mainsequence-8.1.8}/tests/test_time_index_table_update_configuration_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|