diff --git a/.github/workflows/manual_regenerate_models.yaml b/.github/workflows/manual_regenerate_models.yaml index 6f5092d4..84cfde08 100644 --- a/.github/workflows/manual_regenerate_models.yaml +++ b/.github/workflows/manual_regenerate_models.yaml @@ -1,4 +1,4 @@ -# This workflow regenerates Pydantic models (src/apify_client/_models.py) from the OpenAPI spec. +# This workflow regenerates Pydantic models and TypedDicts (src/apify_client/_{models,typeddicts}_generated.py) from the OpenAPI spec. # # It can be triggered in two ways: # 1. Automatically via workflow_dispatch from the apify-docs CI pipeline. @@ -108,7 +108,7 @@ jobs: id: commit uses: EndBug/add-and-commit@v10 with: - add: src/apify_client/_models.py + add: 'src/apify_client/_*_generated.py' author_name: apify-service-account author_email: apify-service-account@users.noreply.github.com message: ${{ env.TITLE }} @@ -130,9 +130,9 @@ jobs: else if [[ -n "$DOCS_PR_NUMBER" ]]; then DOCS_PR_URL="https://github.com/apify/apify-docs/pull/${DOCS_PR_NUMBER}" - BODY="This PR updates the auto-generated Pydantic models based on OpenAPI specification changes in [apify-docs PR #${DOCS_PR_NUMBER}](${DOCS_PR_URL})." + BODY="This PR updates the auto-generated Pydantic models and TypedDicts based on OpenAPI specification changes in [apify-docs PR #${DOCS_PR_NUMBER}](${DOCS_PR_URL})." else - BODY="This PR updates the auto-generated Pydantic models from the [published OpenAPI specification](https://docs.apify.com/api/openapi.json)." + BODY="This PR updates the auto-generated Pydantic models and TypedDicts from the [published OpenAPI specification](https://docs.apify.com/api/openapi.json)." fi PR_URL=$(gh pr create \ diff --git a/.rules.md b/.rules.md index 8700bbe9..19004d65 100644 --- a/.rules.md +++ b/.rules.md @@ -19,7 +19,7 @@ uv run poe type-check # Run ty type checker uv run poe unit-tests # Run unit tests uv run poe check-docstrings # Verify async docstrings match sync uv run poe fix-docstrings # Auto-fix async docstrings -uv run poe generate-models # Regenerate _models.py from live OpenAPI spec +uv run poe generate-models # Regenerate _models_generated.py and _typeddicts_generated.py from live OpenAPI spec uv run poe generate-models-from-file # Regenerate from a local OpenAPI spec file # Run a single test @@ -73,7 +73,7 @@ Docstrings are written on sync clients and **automatically copied** to async cli ### Data Models -`src/apify_client/_models.py` is **auto-generated** — do not edit it manually. +`src/apify_client/_models_generated.py` and `src/apify_client/_typeddicts_generated.py` are **auto-generated** — do not edit them manually. The hand-maintained `src/apify_client/_models.py` and `src/apify_client/_typeddicts.py` hold only shapes that are not exposed by the OpenAPI spec (or that need local logic); import generated types directly from the `_*_generated` modules. - Generated by `datamodel-code-generator` from the OpenAPI spec at `https://docs.apify.com/api/openapi.json` (config in `pyproject.toml` under `[tool.datamodel-codegen]`, aliases in `datamodel_codegen_aliases.json`) - After generation, `scripts/postprocess_generated_models.py` is run to apply additional fixes diff --git a/docs/02_concepts/code/03_nested_async.py b/docs/02_concepts/code/03_nested_async.py index b7843df1..cca76012 100644 --- a/docs/02_concepts/code/03_nested_async.py +++ b/docs/02_concepts/code/03_nested_async.py @@ -1,5 +1,5 @@ from apify_client import ApifyClientAsync -from apify_client._models import ActorJobStatus +from apify_client._models_generated import ActorJobStatus TOKEN = 'MY-APIFY-TOKEN' diff --git a/docs/02_concepts/code/03_nested_sync.py b/docs/02_concepts/code/03_nested_sync.py index 4759f28f..159b3ce0 100644 --- a/docs/02_concepts/code/03_nested_sync.py +++ b/docs/02_concepts/code/03_nested_sync.py @@ -1,5 +1,5 @@ from apify_client import ApifyClient -from apify_client._models import ActorJobStatus +from apify_client._models_generated import ActorJobStatus TOKEN = 'MY-APIFY-TOKEN' diff --git a/docs/04_upgrading/upgrading_to_v3.mdx b/docs/04_upgrading/upgrading_to_v3.mdx index b4d35b64..65edb441 100644 --- a/docs/04_upgrading/upgrading_to_v3.mdx +++ b/docs/04_upgrading/upgrading_to_v3.mdx @@ -55,7 +55,7 @@ run.status Models also use `populate_by_name=True`, which means you can use either the Python field name or the camelCase alias when **constructing** a model: ```python -from apify_client._models import Run +from apify_client._models_generated import Run # Both work when constructing models Run(default_dataset_id='abc') # Python field name @@ -86,7 +86,7 @@ rq_client.add_request({ After (v3) — both forms are accepted: ```python -from apify_client._types import RequestInput +from apify_client._models import RequestInput # Option 1: dict (still works) rq_client.add_request({ diff --git a/pyproject.toml b/pyproject.toml index b41e0cbc..f79dfe85 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,7 +152,7 @@ indent-style = "space" "**/docs/03_guides/code/05_custom_http_client_{async,sync}.py" = [ "ARG002", # Unused method argument ] -"src/apify_client/_models.py" = [ +"src/apify_client/_*_generated.py" = [ "D", # Everything from the pydocstyle "E501", # Line too long "ERA001", # Commented-out code @@ -210,7 +210,7 @@ context = 7 # https://koxudaxi.github.io/datamodel-code-generator/ [tool.datamodel-codegen] input_file_type = "openapi" -output = "src/apify_client/_models.py" +output = "src/apify_client/_models_generated.py" target_python_version = "3.11" output_model_type = "pydantic_v2.BaseModel" use_schema_description = true @@ -272,8 +272,22 @@ shell = "./build_api_reference.sh && corepack enable && yarn && uv run yarn star cwd = "website" [tool.poe.tasks.generate-models] -shell = "uv run datamodel-codegen --url https://docs.apify.com/api/openapi.json && python scripts/postprocess_generated_models.py" +shell = """ +uv run datamodel-codegen --url https://docs.apify.com/api/openapi.json \ + && uv run datamodel-codegen --url https://docs.apify.com/api/openapi.json \ + --output src/apify_client/_typeddicts_generated.py \ + --output-model-type typing.TypedDict \ + --no-use-closed-typed-dict \ + && python scripts/postprocess_generated_models.py +""" [tool.poe.tasks.generate-models-from-file] -shell = "uv run datamodel-codegen --input $input_file && python scripts/postprocess_generated_models.py" +shell = """ +uv run datamodel-codegen --input $input_file \ + && uv run datamodel-codegen --input $input_file \ + --output src/apify_client/_typeddicts_generated.py \ + --output-model-type typing.TypedDict \ + --no-use-closed-typed-dict \ + && python scripts/postprocess_generated_models.py +""" args = [{ name = "input-file", positional = true, required = true }] diff --git a/scripts/postprocess_generated_models.py b/scripts/postprocess_generated_models.py index e32ca443..0efbfae1 100644 --- a/scripts/postprocess_generated_models.py +++ b/scripts/postprocess_generated_models.py @@ -1,24 +1,34 @@ -"""Post-process the generated _models.py to fix known datamodel-codegen issues. - -Currently fixes: -- Discriminator field names: datamodel-codegen sometimes emits the JSON property name (camelCase) - instead of the Python field name (snake_case) in `Field(discriminator='...')` annotations, - particularly when the discriminator is on a schema referenced inside array items. -- Duplicate ErrorType enum: ErrorResponse.yaml inlines the ErrorType enum (due to a Spectral - nested-$ref limitation), causing datamodel-codegen to generate a duplicate `Type(StrEnum)` - class alongside the canonical `ErrorType(StrEnum)`. This script removes the duplicate and - rewires references to use `ErrorType`. -- Missing @docs_group decorator: Adds `@docs_group('Models')` to all model classes for API - reference documentation grouping, along with the required import. +"""Post-process datamodel-codegen output to fix known issues and prune the TypedDict file. + +Applied to `_models_generated.py`: +- Fix discriminator field names that use camelCase instead of snake_case (known issue with + discriminators on schemas referenced from array items). +- Deduplicate the inlined `Type(StrEnum)` that comes from ErrorResponse.yaml; rewire to `ErrorType`. +- Add `@docs_group('Models')` to every model class (plus the required import). + +Applied to `_typeddicts_generated.py`: +- Keep only the TypedDicts actually used as resource-client method inputs (plus their transitive + dependencies). The file is generated in full by datamodel-codegen; the trimming happens here. +- Rename every kept class to add a `Dict` suffix so it doesn't clash with the Pydantic model name + (e.g. `WebhookCreate` -> `WebhookCreateDict`) and rewire references. +- Add `@docs_group('Typed dicts')` to every kept class. """ from __future__ import annotations +import ast import re +import subprocess from pathlib import Path +from typing import TYPE_CHECKING -MODELS_PATH = Path(__file__).resolve().parent.parent / 'src' / 'apify_client' / '_models.py' -DOCS_GROUP_DECORATOR = "@docs_group('Models')" +if TYPE_CHECKING: + from apify_client._docs import GroupName + +REPO_ROOT = Path(__file__).resolve().parent.parent +PACKAGE_DIR = REPO_ROOT / 'src' / 'apify_client' +MODELS_PATH = PACKAGE_DIR / '_models_generated.py' +TYPEDDICTS_PATH = PACKAGE_DIR / '_typeddicts_generated.py' # Map of camelCase discriminator values to their snake_case equivalents. # Add new entries here as needed when the OpenAPI spec introduces new discriminators. @@ -26,6 +36,20 @@ class alongside the canonical `ErrorType(StrEnum)`. This script removes the dupl 'pricingModel': 'pricing_model', } +# TypedDicts accepted as inputs by resource-client methods. These are the roots of the reachability +# walk over `_typeddicts_generated.py`: anything not reachable from here (directly or transitively) +# is dropped so only the TypedDicts that are part of the public input surface — plus their nested +# shapes — survive. Names are the raw datamodel-codegen outputs (no `Dict` suffix yet); the suffix +# is added later by `rename_with_dict_suffix`. Update this set whenever a new `Dict | ` +# union is introduced on a resource-client method signature. +RESOURCE_INPUT_TYPEDDICTS: frozenset[str] = frozenset( + { + 'Request', # RequestQueueClient.update_request + 'TaskInput', # Actor/Task start/call/update default input + 'WebhookCreate', # Actor/Task start/call webhook list element + } +) + def fix_discriminators(content: str) -> str: """Replace camelCase discriminator values with their snake_case equivalents.""" @@ -47,46 +71,236 @@ def deduplicate_error_type_enum(content: str) -> str: content, flags=re.DOTALL, ) - # Replace standalone `Type` references in type annotations with `ErrorType`. - # Only target annotation contexts (`: Type`, `| Type`, `[Type`). + # Replace standalone `Type` references in annotation contexts (`: Type`, `| Type`, `[Type`). content = re.sub(r'(?<=: )Type\b|(?<=\| )Type\b|(?<=\[)Type\b', 'ErrorType', content) # Collapse triple+ blank lines left by the removal. return re.sub(r'\n{3,}', '\n\n\n', content) -def add_docs_group_decorators(content: str) -> str: - """Add `@docs_group('Models')` decorator to all model classes and the required import. +def add_docs_group_decorators(content: str, group_name: GroupName) -> str: + """Add `@docs_group(group_name)` to every class and inject the required import. - This function is idempotent — it skips the import and decorators if they already exist. + Idempotent: skips classes that are already decorated and skips the import if it exists. """ - # Add the import after the existing imports (only if not already present). if 'from apify_client._docs import docs_group' not in content: content = re.sub( - r'(from pydantic import [^\n]+\n)', + r'(from (?:pydantic|typing) import [^\n]+\n)', r'\1\nfrom apify_client._docs import docs_group\n', content, + count=1, ) - # Add @docs_group('Models') before class definitions not already preceded by it. + + decorator = f"@docs_group('{group_name}')" lines = content.split('\n') result: list[str] = [] for line in lines: - if line.startswith('class ') and (not result or result[-1] != DOCS_GROUP_DECORATOR): - result.append(DOCS_GROUP_DECORATOR) + if line.startswith('class ') and (not result or result[-1] != decorator): + result.append(decorator) result.append(line) return '\n'.join(result) -def main() -> None: - content = MODELS_PATH.read_text() - fixed = fix_discriminators(content) +def flatten_empty_typeddicts(content: str) -> str: + """Rewrite empty TypedDict classes into `ClassName: TypeAlias = dict[str, Any]`. + + An empty `TypedDict` is closed at the type-checker level (no keys allowed), which contradicts + the open semantics of Pydantic models with `extra='allow'` and no declared fields (e.g. + `TaskInput`). An open `dict[str, Any]` alias preserves the "any shape" contract. + """ + tree = ast.parse(content) + lines = content.split('\n') + replaced = False + for node in tree.body: + if not isinstance(node, ast.ClassDef): + continue + # A class body counts as "empty" if it has no fields — only optional docstring/pass/ellipsis. + has_fields = any( + isinstance(stmt, (ast.Assign, ast.AnnAssign, ast.FunctionDef, ast.AsyncFunctionDef)) for stmt in node.body + ) + if has_fields: + continue + # Only flatten TypedDict-based classes (e.g. skip Enum subclasses). + base_names = {b.id for b in node.bases if isinstance(b, ast.Name)} + if 'TypedDict' not in base_names: + continue + assert node.end_lineno is not None # noqa: S101 + start_idx = node.lineno - 1 + # Absorb a decorator that sits directly above the class definition (@docs_group). + if start_idx > 0 and lines[start_idx - 1].lstrip().startswith('@'): + start_idx -= 1 + for i in range(start_idx, node.end_lineno): + lines[i] = '' + lines[start_idx] = f'{node.name}: TypeAlias = dict[str, Any]' + replaced = True + + if not replaced: + return content + + output = re.sub(r'\n{3,}', '\n\n\n', '\n'.join(lines)) + # Flattening introduces new `TypeAlias` uses; make sure it's imported from typing. + typing_import = re.search(r'from typing import[^\n]+', output) + if typing_import is not None and 'TypeAlias' not in typing_import.group(0): + output = re.sub( + r'(from typing import )([^\n]+)', + lambda m: f'{m.group(1)}{m.group(2)}, TypeAlias', + output, + count=1, + ) + return output + + +def _is_string_expr(node: ast.stmt) -> bool: + """Return True if `node` is a bare string expression (e.g. a module-level docstring).""" + return isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str) + + +def _extract_top_level_symbols(tree: ast.Module) -> list[tuple[str, ast.stmt, int]]: + """Return (name, node, end_line) for every top-level class or type-alias statement. + + If a top-level string expression immediately follows a symbol, it is absorbed into that + symbol's `end_line` so they get pruned together (datamodel-codegen emits the schema description + for TypeAlias statements as a bare string right after the alias). + """ + symbols: list[tuple[str, ast.stmt, int]] = [] + body = tree.body + i = 0 + while i < len(body): + node = body[i] + name: str | None = None + if isinstance(node, ast.ClassDef): + name = node.name + elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): + name = node.target.id + + if name is not None: + assert node.end_lineno is not None # noqa: S101 + end_line = node.end_lineno + if i + 1 < len(body) and _is_string_expr(body[i + 1]): + trailing = body[i + 1] + assert trailing.end_lineno is not None # noqa: S101 + end_line = trailing.end_lineno + i += 1 # Skip the docstring: it's absorbed into this symbol. + symbols.append((name, node, end_line)) + i += 1 + return symbols + + +def _collect_name_references(node: ast.AST, exclude: set[str]) -> set[str]: + """Collect every `ast.Name` identifier under `node`, minus names in `exclude`.""" + refs: set[str] = set() + for child in ast.walk(node): + if isinstance(child, ast.Name): + refs.add(child.id) + return refs - exclude + + +def _compute_reachable_symbols(deps: dict[str, set[str]], seeds: set[str]) -> set[str]: + """Return every symbol transitively reachable from any seed via `deps`.""" + reachable: set[str] = set() + stack = [s for s in seeds if s in deps] + while stack: + name = stack.pop() + if name in reachable: + continue + reachable.add(name) + stack.extend(ref for ref in deps[name] if ref in deps and ref not in reachable) + return reachable + + +def prune_typeddicts(content: str, seeds: frozenset[str]) -> tuple[str, set[str]]: + """Remove every top-level class/alias not transitively reachable from `seeds`. + + Returns the pruned source and the set of names that were kept. + """ + tree = ast.parse(content) + symbols = _extract_top_level_symbols(tree) + symbol_names = {name for name, _, _ in symbols} + + deps: dict[str, set[str]] = {} + for name, node, _ in symbols: + # Ignore builtins and imported names — we only care about cross-references within the file. + deps[name] = _collect_name_references(node, exclude={name}) & symbol_names + + kept = _compute_reachable_symbols(deps, set(seeds)) + + missing_seeds = seeds - symbol_names + if missing_seeds: + raise RuntimeError(f'TypedDict seeds missing from generated file: {sorted(missing_seeds)}') + + lines = content.split('\n') + drop_line_indices: set[int] = set() + for name, node, end_line in symbols: + if name in kept: + continue + # ast line numbers are 1-indexed; list is 0-indexed. + for line_no in range(node.lineno - 1, end_line): + drop_line_indices.add(line_no) + + pruned = [line for i, line in enumerate(lines) if i not in drop_line_indices] + output = '\n'.join(pruned) + # Collapse runs of blank lines left behind by deletions. + output = re.sub(r'\n{3,}', '\n\n\n', output) + return output, kept + + +def rename_with_dict_suffix(content: str, names: set[str]) -> str: + """Append `Dict` to every whole-word occurrence of each name in `names`. + + Order doesn't matter because `\\b` anchors in the pattern prevent partial-prefix matches. + """ + for name in names: + content = re.sub(rf'\b{re.escape(name)}\b', f'{name}Dict', content) + return content + + +def postprocess_models(path: Path) -> bool: + """Apply `_models_generated.py`-specific fixes. Returns True if the file changed.""" + original = path.read_text() + fixed = fix_discriminators(original) fixed = deduplicate_error_type_enum(fixed) - fixed = add_docs_group_decorators(fixed) + fixed = add_docs_group_decorators(fixed, 'Models') + if fixed == original: + return False + path.write_text(fixed) + return True + + +def postprocess_typeddicts(path: Path) -> bool: + """Apply `_typeddicts_generated.py`-specific fixes. Returns True if the file changed.""" + original = path.read_text() + pruned, kept = prune_typeddicts(original, RESOURCE_INPUT_TYPEDDICTS) + renamed = rename_with_dict_suffix(pruned, kept) + flattened = flatten_empty_typeddicts(renamed) + final = add_docs_group_decorators(flattened, 'Typed dicts') + if final == original: + return False + path.write_text(final) + return True + - if fixed != content: - MODELS_PATH.write_text(fixed) +def run_ruff(paths: list[Path]) -> None: + """Run `ruff check --fix` and `ruff format` on the given files (single subprocess per phase).""" + paths_s = [str(p) for p in paths] + subprocess.run(['uv', 'run', 'ruff', 'check', '--fix', *paths_s], check=True, cwd=REPO_ROOT) # noqa: S603, S607 + subprocess.run(['uv', 'run', 'ruff', 'format', *paths_s], check=True, cwd=REPO_ROOT) # noqa: S603, S607 + + +def main() -> None: + changed: list[Path] = [] + if postprocess_models(MODELS_PATH): + changed.append(MODELS_PATH) print(f'Fixed generated models in {MODELS_PATH}') else: - print('No fixes needed') + print('No fixes needed for _models_generated.py') + + if postprocess_typeddicts(TYPEDDICTS_PATH): + changed.append(TYPEDDICTS_PATH) + print(f'Pruned and renamed TypedDicts in {TYPEDDICTS_PATH}') + else: + print('No fixes needed for _typeddicts_generated.py') + + if changed: + run_ruff(changed) if __name__ == '__main__': diff --git a/src/apify_client/_consts.py b/src/apify_client/_consts.py index 91f8fd3e..f6a18d97 100644 --- a/src/apify_client/_consts.py +++ b/src/apify_client/_consts.py @@ -2,7 +2,7 @@ from datetime import timedelta -from apify_client._models import ActorJobStatus +from apify_client._models_generated import ActorJobStatus DEFAULT_API_URL = 'https://api.apify.com' """Default base URL for the Apify API.""" diff --git a/src/apify_client/_docs.py b/src/apify_client/_docs.py index fa5983fa..5aa61acd 100644 --- a/src/apify_client/_docs.py +++ b/src/apify_client/_docs.py @@ -11,6 +11,7 @@ 'Resource clients', 'Errors', 'Models', + 'Typed dicts', 'Other', ] diff --git a/src/apify_client/_models.py b/src/apify_client/_models.py index 284d6780..be6fba38 100644 --- a/src/apify_client/_models.py +++ b/src/apify_client/_models.py @@ -1,4016 +1,163 @@ -# generated by datamodel-codegen +"""Hand-written Pydantic models for shapes not exposed by the OpenAPI spec or that need local logic. + +Generated models live in `apify_client._models_generated`; import from there directly. +""" from __future__ import annotations -from enum import StrEnum -from typing import Annotated, Any, Literal +import json +from base64 import b64encode +from typing import TYPE_CHECKING, Annotated -from pydantic import AnyUrl, AwareDatetime, BaseModel, ConfigDict, EmailStr, Field, RootModel +from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel, model_validator from apify_client._docs import docs_group +from apify_client._models_generated import ActorJobStatus, WebhookCreate - -@docs_group('Models') -class AccountLimits(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - monthly_usage_cycle: Annotated[UsageCycle, Field(alias='monthlyUsageCycle')] - limits: Limits - current: Current - - -@docs_group('Models') -class Actor(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - name: Annotated[str, Field(examples=['MyActor'])] - username: Annotated[str, Field(examples=['jane35'])] - description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None - restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None - is_public: Annotated[bool, Field(alias='isPublic', examples=[False])] - actor_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='actorPermissionLevel')] = None - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-07-08T11:27:57.401Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-07-08T14:01:05.546Z'])] - stats: ActorStats - versions: list[Version] - pricing_infos: Annotated[ - list[ - Annotated[ - PayPerEventActorPricingInfo - | PricePerDatasetItemActorPricingInfo - | FlatPricePerMonthActorPricingInfo - | FreeActorPricingInfo, - Field(discriminator='pricing_model'), - ] - ] - | None, - Field(alias='pricingInfos'), - ] = None - default_run_options: Annotated[DefaultRunOptions, Field(alias='defaultRunOptions')] - example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None - is_deprecated: Annotated[bool | None, Field(alias='isDeprecated', examples=[False])] = None - deployment_key: Annotated[str | None, Field(alias='deploymentKey', examples=['ssh-rsa AAAA ...'])] = None - title: Annotated[str | None, Field(examples=['My Actor'])] = None - tagged_builds: Annotated[dict[str, TaggedBuildInfo | None] | None, Field(alias='taggedBuilds')] = None - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - readme_summary: Annotated[str | None, Field(alias='readmeSummary')] = None - """ - A brief, LLM-generated readme summary - """ - - -@docs_group('Models') -class ActorChargeEvent(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - event_price_usd: Annotated[float, Field(alias='eventPriceUsd')] - event_title: Annotated[str, Field(alias='eventTitle')] - event_description: Annotated[str, Field(alias='eventDescription')] +if TYPE_CHECKING: + from apify_client._types import WebhooksList @docs_group('Models') -class ActorDefinition(BaseModel): - """The definition of the Actor, the full specification of this field can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/actor-json).""" +class ActorJob(BaseModel): + """Minimal model for an Actor job (run or build) with status. - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_specification: Annotated[Literal[1], Field(alias='actorSpecification')] = 1 - """ - The Actor specification version that this Actor follows. This property must be set to 1. - """ - name: str | None = None - """ - The name of the Actor. - """ - version: Annotated[str | None, Field(pattern='^[0-9]+\\.[0-9]+$')] = None + Used for validation during polling operations. Allows extra fields so the full response data is preserved. """ - The version of the Actor, specified in the format [Number].[Number], e.g., 0.1, 1.0. - """ - build_tag: Annotated[str | None, Field(alias='buildTag')] = None - """ - The tag name to be applied to a successful build of the Actor. Defaults to 'latest' if not specified. - """ - environment_variables: Annotated[dict[str, str] | None, Field(alias='environmentVariables')] = None - """ - A map of environment variables to be used during local development and deployment. - """ - dockerfile: str | None = None - """ - The path to the Dockerfile used for building the Actor on the platform. - """ - docker_context_dir: Annotated[str | None, Field(alias='dockerContextDir')] = None - """ - The path to the directory used as the Docker context when building the Actor. - """ - readme: str | None = None - """ - The path to the README file for the Actor. - """ - input: dict[str, Any] | None = None - """ - The input schema object, the full specification can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/input-schema) - """ - changelog: str | None = None - """ - The path to the CHANGELOG file displayed in the Actor's information tab. - """ - storages: Storages | None = None - default_memory_mbytes: Annotated[str | int | None, Field(alias='defaultMemoryMbytes')] = None - """ - Specifies the default amount of memory in megabytes to be used when the Actor is started. Can be an integer or a [dynamic memory expression](/platform/actors/development/actor-definition/dynamic-actor-memory). - """ - min_memory_mbytes: Annotated[int | None, Field(alias='minMemoryMbytes', ge=256)] = None - """ - Specifies the minimum amount of memory in megabytes required by the Actor. - """ - max_memory_mbytes: Annotated[int | None, Field(alias='maxMemoryMbytes', ge=256)] = None - """ - Specifies the maximum amount of memory in megabytes required by the Actor. - """ - uses_standby_mode: Annotated[bool | None, Field(alias='usesStandbyMode')] = None - """ - Specifies whether Standby mode is enabled for the Actor. - """ - -@docs_group('Models') -class ActorJobStatus(StrEnum): - """Status of an Actor job (run or build).""" - - READY = 'READY' - RUNNING = 'RUNNING' - SUCCEEDED = 'SUCCEEDED' - FAILED = 'FAILED' - TIMING_OUT = 'TIMING-OUT' - TIMED_OUT = 'TIMED-OUT' - ABORTING = 'ABORTING' - ABORTED = 'ABORTED' - - -@docs_group('Models') -class ActorPermissionLevel(StrEnum): - """Determines permissions that the Actor requires to run. For more information, see the [Actor permissions documentation](https://docs.apify.com/platform/actors/development/permissions).""" + model_config = ConfigDict(extra='allow', populate_by_name=True) - LIMITED_PERMISSIONS = 'LIMITED_PERMISSIONS' - FULL_PERMISSIONS = 'FULL_PERMISSIONS' + status: ActorJobStatus + """The current status of the Actor job.""" @docs_group('Models') -class ActorResponse(BaseModel): - """Response containing Actor data.""" +class ActorJobResponse(BaseModel): + """Response wrapper for an Actor job (run or build). - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Actor + Used for minimal validation during polling operations. Allows extra fields so the full response data is preserved. + """ + model_config = ConfigDict(extra='allow', populate_by_name=True) -@docs_group('Models') -class ActorRunFailedError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - error: RunFailedErrorDetail | None = None + data: ActorJob + """The Actor job payload.""" @docs_group('Models') -class ActorRunTimeoutExceededError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - error: RunTimeoutExceededErrorDetail | None = None +class WebhookRepresentation(BaseModel): + """Representation of a webhook for base64-encoded API transmission. + Contains only the fields needed for the webhook payload sent via query parameters. + """ -@docs_group('Models') -class ActorShort(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['br9CKmk457'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-10-29T07:34:24.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-10-30T07:34:24.202Z'])] - name: Annotated[str, Field(examples=['MyAct'])] - username: Annotated[str, Field(examples=['janedoe'])] - title: Annotated[str | None, Field(examples=['Hello World Example'])] = None - stats: ActorStats | None = None + model_config = ConfigDict(populate_by_name=True, extra='ignore') + event_types: Annotated[list[str], Field(alias='eventTypes')] + """The list of Actor events that trigger this webhook.""" -@docs_group('Models') -class ActorStandby(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - is_enabled: Annotated[bool | None, Field(alias='isEnabled')] = None - desired_requests_per_actor_run: Annotated[int | None, Field(alias='desiredRequestsPerActorRun')] = None - max_requests_per_actor_run: Annotated[int | None, Field(alias='maxRequestsPerActorRun')] = None - idle_timeout_secs: Annotated[int | None, Field(alias='idleTimeoutSecs')] = None - build: str | None = None - memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes')] = None - disable_standby_fields_override: Annotated[bool | None, Field(alias='disableStandbyFieldsOverride')] = None - should_pass_actor_input: Annotated[bool | None, Field(alias='shouldPassActorInput')] = None + request_url: Annotated[str, Field(alias='requestUrl')] + """The URL to which the webhook sends its payload.""" + payload_template: Annotated[str | None, Field(alias='payloadTemplate')] = None + """Optional template for the JSON payload sent by the webhook.""" -@docs_group('Models') -class ActorStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total_builds: Annotated[int | None, Field(alias='totalBuilds', examples=[9])] = None - total_runs: Annotated[int | None, Field(alias='totalRuns', examples=[16])] = None - total_users: Annotated[int | None, Field(alias='totalUsers', examples=[6])] = None - total_users7_days: Annotated[int | None, Field(alias='totalUsers7Days', examples=[2])] = None - total_users30_days: Annotated[int | None, Field(alias='totalUsers30Days', examples=[6])] = None - total_users90_days: Annotated[int | None, Field(alias='totalUsers90Days', examples=[6])] = None - total_metamorphs: Annotated[int | None, Field(alias='totalMetamorphs', examples=[2])] = None - last_run_started_at: Annotated[ - AwareDatetime | None, Field(alias='lastRunStartedAt', examples=['2019-07-08T14:01:05.546Z']) - ] = None + headers_template: Annotated[str | None, Field(alias='headersTemplate')] = None + """Optional template for the HTTP headers sent by the webhook.""" @docs_group('Models') -class AddRequestResponse(BaseModel): - """Response containing the result of adding a request to the request queue.""" +class WebhookRepresentationList(RootModel[list[WebhookRepresentation]]): + """List of webhook representations with base64 encoding support.""" - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: RequestRegistration + @classmethod + def from_webhooks(cls, webhooks: WebhooksList) -> WebhookRepresentationList: + """Construct from a list of webhooks. + See `WebhooksList` for the accepted shapes. `WebhookRepresentation` instances are used as-is; all + other shapes are validated into `WebhookRepresentation`, keeping only its fields and ignoring any + extras (e.g. `condition`). + """ + representations = list[WebhookRepresentation]() -@docs_group('Models') -class AddedRequest(BaseModel): - """Information about a request that was successfully added to a request queue.""" + for webhook in webhooks: + if isinstance(webhook, WebhookRepresentation): + representations.append(webhook) + elif isinstance(webhook, WebhookCreate): + webhook_dict = webhook.model_dump(mode='json', exclude_none=True) + webhook_representation = WebhookRepresentation.model_validate(webhook_dict) + representations.append(webhook_representation) + else: + webhook_representation = WebhookRepresentation.model_validate(webhook) + representations.append(webhook_representation) - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - request_id: Annotated[str, Field(alias='requestId', examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - was_already_present: Annotated[bool, Field(alias='wasAlreadyPresent', examples=[False])] - """ - Indicates whether a request with the same unique key already existed in the request queue. If true, no new request was created. - """ - was_already_handled: Annotated[bool, Field(alias='wasAlreadyHandled', examples=[False])] - """ - Indicates whether a request with the same unique key has already been processed by the request queue. - """ + return cls(representations) + def to_base64(self) -> str | None: + """Encode this list of webhook representations to a base64 string. -@docs_group('Models') -class BatchAddResponse(BaseModel): - """Response containing the result of a batch add operation.""" + Returns `None` if the list is empty, so that the query parameter is omitted. + """ + if not self.root: + return None - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: BatchAddResult + data = [r.model_dump(by_alias=True, exclude_none=True) for r in self.root] + json_string = json.dumps(data).encode(encoding='utf-8') + return b64encode(json_string).decode(encoding='ascii') @docs_group('Models') -class BatchAddResult(BaseModel): - """Result of a batch add operation containing successfully processed and failed requests.""" +class RequestInput(BaseModel): + """Input model for adding requests to a request queue. - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - processed_requests: Annotated[list[AddedRequest], Field(alias='processedRequests')] - """ - Requests that were successfully added to the request queue. + Both `url` and `unique_key` are required. The API defaults `method` to `GET` when not provided. """ - unprocessed_requests: Annotated[list[RequestDraft], Field(alias='unprocessedRequests')] - """ - Requests that failed to be added and can be retried. - """ - - -@docs_group('Models') -class BatchDeleteResponse(BaseModel): - """Response containing the result of a batch delete operation.""" model_config = ConfigDict( extra='allow', populate_by_name=True, ) - data: BatchDeleteResult - -@docs_group('Models') -class BatchDeleteResult(BaseModel): - """Result of a batch delete operation containing successfully deleted and failed requests.""" + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """A unique identifier assigned to the request.""" - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - processed_requests: Annotated[ - list[DeletedRequestById | DeletedRequestByUniqueKey], Field(alias='processedRequests') + unique_key: Annotated[ + str, + Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']), ] - """ - Requests that were successfully deleted from the request queue. - """ - unprocessed_requests: Annotated[list[RequestDraft], Field(alias='unprocessedRequests')] - """ - Requests that failed to be deleted and can be retried. - """ - - -@docs_group('Models') -class BrowserInfoResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - method: Annotated[str, Field(examples=['GET'])] - """ - HTTP method of the request. - """ - client_ip: Annotated[str | None, Field(alias='clientIp', examples=['1.2.3.4'])] - """ - IP address of the client. - """ - country_code: Annotated[str | None, Field(alias='countryCode', examples=['US'])] - """ - Two-letter country code resolved from the client IP address. - """ - body_length: Annotated[int, Field(alias='bodyLength', examples=[0])] - """ - Length of the request body in bytes. - """ - headers: dict[str, str | list[str]] | None = None - """ - Request headers. Omitted when `skipHeaders=true`. - - """ - raw_headers: Annotated[list[str] | None, Field(alias='rawHeaders')] = None - """ - Raw request headers as a flat list of alternating name/value strings. - Included only when `rawHeaders=true`. - - """ - - -@docs_group('Models') -class Build(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] - act_id: Annotated[str, Field(alias='actId', examples=['janedoe~my-actor'])] - user_id: Annotated[str, Field(alias='userId', examples=['klmdEpoiojmdEMlk3'])] - started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( - None - ) - status: ActorJobStatus - meta: BuildsMeta - stats: BuildStats | None = None - options: BuildOptions | None = None - usage: BuildUsage | None = None - usage_total_usd: Annotated[float | None, Field(alias='usageTotalUsd', examples=[0.02])] = None - """ - Total cost in USD for this build. Requires authentication token to access. - """ - usage_usd: Annotated[BuildUsage | None, Field(alias='usageUsd')] = None - """ - Platform usage costs breakdown in USD for this build. Requires authentication token to access. - """ - input_schema: Annotated[ - str | None, Field(alias='inputSchema', deprecated=True, examples=['{\\n "title": "Schema for ... }']) - ] = None - readme: Annotated[str | None, Field(deprecated=True, examples=['# Magic Actor\\nThis Actor is magic.'])] = None - build_number: Annotated[str, Field(alias='buildNumber', examples=['0.1.1'])] - actor_definition: Annotated[ActorDefinition | None, Field(alias='actorDefinition')] = None - - -@docs_group('Models') -class BuildOptions(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - use_cache: Annotated[bool | None, Field(alias='useCache', examples=[False])] = None - beta_packages: Annotated[bool | None, Field(alias='betaPackages', examples=[False])] = None - memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[1024])] = None - disk_mbytes: Annotated[int | None, Field(alias='diskMbytes', examples=[2048])] = None - - -@docs_group('Models') -class BuildResponse(BaseModel): - """Response containing Actor build data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Build - - -@docs_group('Models') -class BuildShort(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] - act_id: Annotated[str | None, Field(alias='actId', examples=['janedoe~my-actor'])] = None - status: ActorJobStatus - started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( - None - ) - usage_total_usd: Annotated[float, Field(alias='usageTotalUsd', examples=[0.02])] - meta: BuildsMeta | None = None - - -@docs_group('Models') -class BuildStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - duration_millis: Annotated[int | None, Field(alias='durationMillis', examples=[1000])] = None - run_time_secs: Annotated[float | None, Field(alias='runTimeSecs', examples=[45.718])] = None - compute_units: Annotated[float, Field(alias='computeUnits', examples=[0.0126994444444444])] + """A unique key used for request de-duplication.""" + url: Annotated[AnyUrl, Field(examples=['https://apify.com'])] + """The URL of the request.""" -@docs_group('Models') -class BuildTag(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - build_id: Annotated[str, Field(alias='buildId')] + method: Annotated[str | None, Field(examples=['GET'])] = None + """The HTTP method of the request. Defaults to `GET` on the API side if not provided.""" @docs_group('Models') -class BuildUsage(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[0.08])] = None +class RequestDeleteInput(BaseModel): + """Input model for deleting requests from a request queue. - -@docs_group('Models') -class BuildsMeta(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - origin: RunOrigin - client_ip: Annotated[str | None, Field(alias='clientIp', examples=['172.234.12.34'])] = None - """ - IP address of the client that started the build. - """ - user_agent: Annotated[str | None, Field(alias='userAgent', examples=['Mozilla/5.0 (iPad)'])] = None + Requests are identified by `id` or `unique_key`. At least one must be provided. """ - User agent of the client that started the build. - """ - - -@docs_group('Models') -class Call(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - started_at: Annotated[AwareDatetime | None, Field(alias='startedAt', examples=['2019-12-12T07:34:14.202Z'])] = None - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T07:34:14.202Z'])] = ( - None - ) - error_message: Annotated[str | None, Field(alias='errorMessage', examples=['Cannot send request'])] = None - response_status: Annotated[int | None, Field(alias='responseStatus', examples=[200])] = None - response_body: Annotated[str | None, Field(alias='responseBody', examples=['{"foo": "bar"}'])] = None - - -@docs_group('Models') -class ChargeRunRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - event_name: Annotated[str, Field(alias='eventName', examples=['ANALYZE_PAGE'])] - count: Annotated[int, Field(examples=[1])] - -@docs_group('Models') -class CommonActorPricingInfo(BaseModel): model_config = ConfigDict( extra='allow', populate_by_name=True, ) - apify_margin_percentage: Annotated[float, Field(alias='apifyMarginPercentage')] - """ - In [0, 1], fraction of pricePerUnitUsd that goes to Apify - """ - created_at: Annotated[AwareDatetime, Field(alias='createdAt')] - """ - When this pricing info record has been created - """ - started_at: Annotated[AwareDatetime, Field(alias='startedAt')] - """ - Since when is this pricing info record effective for a given Actor - """ - notified_about_future_change_at: Annotated[AwareDatetime | None, Field(alias='notifiedAboutFutureChangeAt')] = None - notified_about_change_at: Annotated[AwareDatetime | None, Field(alias='notifiedAboutChangeAt')] = None - reason_for_change: Annotated[str | None, Field(alias='reasonForChange')] = None + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """A unique identifier assigned to the request.""" -@docs_group('Models') -class CreateActorRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str | None, Field(examples=['MyActor'])] = None - description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None - title: Annotated[str | None, Field(examples=['My actor'])] = None - is_public: Annotated[bool | None, Field(alias='isPublic', examples=[False])] = None - seo_title: Annotated[str | None, Field(alias='seoTitle', examples=['My actor'])] = None - seo_description: Annotated[str | None, Field(alias='seoDescription', examples=['My actor is the best'])] = None - restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None - versions: list[Version] | None = None - pricing_infos: Annotated[ - list[ - Annotated[ - PayPerEventActorPricingInfo - | PricePerDatasetItemActorPricingInfo - | FlatPricePerMonthActorPricingInfo - | FreeActorPricingInfo, - Field(discriminator='pricing_model'), - ] - ] - | None, - Field(alias='pricingInfos'), + unique_key: Annotated[ + str | None, + Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']), ] = None - categories: list[str] | None = None - default_run_options: Annotated[DefaultRunOptions | None, Field(alias='defaultRunOptions')] = None - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None - is_deprecated: Annotated[bool | None, Field(alias='isDeprecated')] = None + """A unique key used for request de-duplication.""" - -@docs_group('Models') -class CreateOrUpdateVersionRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - version_number: Annotated[str | None, Field(alias='versionNumber', examples=['0.0'])] = None - source_type: Annotated[VersionSourceType | None, Field(alias='sourceType')] = None - env_vars: Annotated[list[EnvVarRequest] | None, Field(alias='envVars')] = None - apply_env_vars_to_build: Annotated[bool | None, Field(alias='applyEnvVarsToBuild', examples=[False])] = None - build_tag: Annotated[str | None, Field(alias='buildTag', examples=['latest'])] = None - source_files: Annotated[ - list[SourceCodeFile | SourceCodeFolder] | None, Field(alias='sourceFiles', title='VersionSourceFiles') - ] = None - git_repo_url: Annotated[str | None, Field(alias='gitRepoUrl')] = None - """ - URL of the Git repository when sourceType is GIT_REPO. - """ - tarball_url: Annotated[str | None, Field(alias='tarballUrl')] = None - """ - URL of the tarball when sourceType is TARBALL. - """ - github_gist_url: Annotated[str | None, Field(alias='gitHubGistUrl')] = None - """ - URL of the GitHub Gist when sourceType is GITHUB_GIST. - """ - - -@docs_group('Models') -class CreateTaskRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] - name: Annotated[str | None, Field(examples=['my-task'])] = None - options: TaskOptions | None = None - input: TaskInput | None = None - title: str | None = None - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - - -@docs_group('Models') -class Current(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - monthly_usage_usd: Annotated[float, Field(alias='monthlyUsageUsd', examples=[43])] - monthly_actor_compute_units: Annotated[float, Field(alias='monthlyActorComputeUnits', examples=[500.784475])] - monthly_external_data_transfer_gbytes: Annotated[ - float, Field(alias='monthlyExternalDataTransferGbytes', examples=[3.00861903931946]) - ] - monthly_proxy_serps: Annotated[int, Field(alias='monthlyProxySerps', examples=[34])] - monthly_residential_proxy_gbytes: Annotated[float, Field(alias='monthlyResidentialProxyGbytes', examples=[0.4])] - actor_memory_gbytes: Annotated[float, Field(alias='actorMemoryGbytes', examples=[8])] - actor_count: Annotated[int, Field(alias='actorCount', examples=[31])] - actor_task_count: Annotated[int, Field(alias='actorTaskCount', examples=[130])] - active_actor_job_count: Annotated[int, Field(alias='activeActorJobCount', examples=[0])] - team_account_seat_count: Annotated[int, Field(alias='teamAccountSeatCount', examples=[5])] - - -@docs_group('Models') -class CurrentPricingInfo(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - pricing_model: Annotated[str, Field(alias='pricingModel', examples=['FREE'])] - - -@docs_group('Models') -class DailyServiceUsages(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - date: Annotated[str, Field(examples=['2022-10-02T00:00:00.000Z'])] - service_usage: Annotated[dict[str, UsageItem], Field(alias='serviceUsage')] - total_usage_credits_usd: Annotated[float, Field(alias='totalUsageCreditsUsd', examples=[0.0474385791970591])] - - -@docs_group('Models') -class Dataset(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] - name: Annotated[str | None, Field(examples=['d7b9MDYsbtX5L7XAj'])] = None - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] - item_count: Annotated[int, Field(alias='itemCount', examples=[7], ge=0)] - clean_item_count: Annotated[int, Field(alias='cleanItemCount', examples=[5], ge=0)] - act_id: Annotated[str | None, Field(alias='actId')] = None - act_run_id: Annotated[str | None, Field(alias='actRunId')] = None - fields: list[str] | None = None - schema_: Annotated[ - dict[str, Any] | None, - Field( - alias='schema', - examples=[ - { - 'actorSpecification': 1, - 'title': 'My dataset', - 'views': { - 'overview': { - 'title': 'Overview', - 'transformation': {'fields': ['linkUrl']}, - 'display': { - 'component': 'table', - 'properties': {'linkUrl': {'label': 'Link URL', 'format': 'link'}}, - }, - } - }, - } - ], - ), - ] = None - """ - Defines the schema of items in your dataset, the full specification can be found in [Apify docs](/platform/actors/development/actor-definition/dataset-schema) - """ - console_url: Annotated[ - AnyUrl, Field(alias='consoleUrl', examples=['https://console.apify.com/storage/datasets/27TmTznX9YPeAYhkC']) - ] - items_public_url: Annotated[ - AnyUrl | None, - Field( - alias='itemsPublicUrl', - examples=['https://api.apify.com/v2/datasets/WkzbQMuFYuamGv3YF/items?signature=abc123'], - ), - ] = None - """ - A public link to access the dataset items directly. - """ - url_signing_secret_key: Annotated[str | None, Field(alias='urlSigningSecretKey')] = None - """ - A secret key for generating signed public URLs. It is only provided to clients with WRITE permission for the dataset. - """ - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - stats: DatasetStats | None = None - - -@docs_group('Models') -class DatasetFieldStatistics(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - min: float | None = None - """ - Minimum value of the field. For numbers, this is calculated directly. For strings, this is the length of the shortest string. For arrays, this is the length of the shortest array. For objects, this is the number of keys in the smallest object. - """ - max: float | None = None - """ - Maximum value of the field. For numbers, this is calculated directly. For strings, this is the length of the longest string. For arrays, this is the length of the longest array. For objects, this is the number of keys in the largest object. - """ - null_count: Annotated[int | None, Field(alias='nullCount')] = None - """ - How many items in the dataset have a null value for this field. - """ - empty_count: Annotated[int | None, Field(alias='emptyCount')] = None - """ - How many items in the dataset are `undefined`, meaning that for example empty string is not considered empty. - """ - - -@docs_group('Models') -class DatasetListItem(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] - name: Annotated[str, Field(examples=['d7b9MDYsbtX5L7XAj'])] - user_id: Annotated[str, Field(alias='userId', examples=['tbXmWu7GCxnyYtSiL'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] - item_count: Annotated[int, Field(alias='itemCount', examples=[7])] - clean_item_count: Annotated[int, Field(alias='cleanItemCount', examples=[5])] - act_id: Annotated[str | None, Field(alias='actId', examples=['zdc3Pyhyz3m8vjDeM'])] = None - act_run_id: Annotated[str | None, Field(alias='actRunId', examples=['HG7ML7M8z78YcAPEB'])] = None - - -@docs_group('Models') -class DatasetResponse(BaseModel): - """Response containing dataset metadata.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Dataset - - -@docs_group('Models') -class DatasetSchemaValidationError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Annotated[str | None, Field(examples=['schema-validation-error'])] = None - """ - The type of the error. - """ - message: Annotated[str | None, Field(examples=['Schema validation failed'])] = None - """ - A human-readable message describing the error. - """ - data: SchemaValidationErrorData | None = None - - -@docs_group('Models') -class DatasetStatistics(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - field_statistics: Annotated[dict[str, Any] | None, Field(alias='fieldStatistics')] = None - """ - When you configure the dataset [fields schema](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema/validation), we measure the statistics such as `min`, `max`, `nullCount` and `emptyCount` for each field. This property provides statistics for each field from dataset fields schema.

See dataset field statistics [documentation](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema/validation#dataset-field-statistics) for more information. - """ - - -@docs_group('Models') -class DatasetStatisticsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: DatasetStatistics - - -@docs_group('Models') -class DatasetStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - read_count: Annotated[int, Field(alias='readCount', examples=[22])] - write_count: Annotated[int, Field(alias='writeCount', examples=[3])] - storage_bytes: Annotated[int, Field(alias='storageBytes', examples=[783])] - - -@docs_group('Models') -class Datasets(BaseModel): - """Aliased dataset IDs for this run.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - default: Annotated[str | None, Field(examples=['wmKPijuyDnPZAPRMk'])] = None - """ - ID of the default dataset for this run. - """ - - -@docs_group('Models') -class DecodeAndVerifyData(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - decoded: Any - """ - The original object that was encoded. - """ - encoded_by_user_id: Annotated[str | None, Field(alias='encodedByUserId', examples=['wRwJZtadYvn4mBZmm'])] - is_verified_user: Annotated[bool, Field(alias='isVerifiedUser', examples=[False])] - - -@docs_group('Models') -class DecodeAndVerifyRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - encoded: Annotated[str, Field(examples=['eyJwYXlsb2FkIjoiLi4uIiwic2lnbmF0dXJlIjoiLi4uIn0='])] - - -@docs_group('Models') -class DecodeAndVerifyResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: DecodeAndVerifyData - - -@docs_group('Models') -class DefaultRunOptions(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - build: Annotated[str | None, Field(examples=['latest'])] = None - timeout_secs: Annotated[int | None, Field(alias='timeoutSecs', examples=[3600])] = None - memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[2048])] = None - restart_on_error: Annotated[bool | None, Field(alias='restartOnError', examples=[False])] = None - max_items: Annotated[int | None, Field(alias='maxItems')] = None - force_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='forcePermissionLevel')] = None - - -@docs_group('Models') -class DeletedRequestById(BaseModel): - """Confirmation of a request that was successfully deleted, identified by its ID.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - unique_key: Annotated[ - str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) - ] = None - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - - -@docs_group('Models') -class DeletedRequestByUniqueKey(BaseModel): - """Confirmation of a request that was successfully deleted, identified by its unique key.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """ - A unique identifier assigned to the request. - """ - - -@docs_group('Models') -class EffectivePlatformFeature(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] - disabled_reason: Annotated[ - str | None, - Field( - alias='disabledReason', - examples=[ - 'The "Selected public Actors for developers" feature is not enabled for your account. Please upgrade your plan or contact support@apify.com' - ], - ), - ] - disabled_reason_type: Annotated[str | None, Field(alias='disabledReasonType', examples=['DISABLED'])] - is_trial: Annotated[bool, Field(alias='isTrial', examples=[False])] - trial_expiration_at: Annotated[ - AwareDatetime | None, Field(alias='trialExpirationAt', examples=['2025-01-01T14:00:00.000Z']) - ] - - -@docs_group('Models') -class EffectivePlatformFeatures(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actors: Annotated[EffectivePlatformFeature, Field(alias='ACTORS')] - storage: Annotated[EffectivePlatformFeature, Field(alias='STORAGE')] - scheduler: Annotated[EffectivePlatformFeature, Field(alias='SCHEDULER')] - proxy: Annotated[EffectivePlatformFeature, Field(alias='PROXY')] - proxy_external_access: Annotated[EffectivePlatformFeature, Field(alias='PROXY_EXTERNAL_ACCESS')] - proxy_residential: Annotated[EffectivePlatformFeature, Field(alias='PROXY_RESIDENTIAL')] - proxy_serps: Annotated[EffectivePlatformFeature, Field(alias='PROXY_SERPS')] - webhooks: Annotated[EffectivePlatformFeature, Field(alias='WEBHOOKS')] - actors_public_all: Annotated[EffectivePlatformFeature, Field(alias='ACTORS_PUBLIC_ALL')] - actors_public_developer: Annotated[EffectivePlatformFeature, Field(alias='ACTORS_PUBLIC_DEVELOPER')] - - -@docs_group('Models') -class EncodeAndSignData(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - encoded: Annotated[str, Field(examples=['eyJwYXlsb2FkIjoiLi4uIiwic2lnbmF0dXJlIjoiLi4uIn0='])] - - -@docs_group('Models') -class EncodeAndSignResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: EncodeAndSignData - - -@docs_group('Models') -class EnvVar(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str, Field(examples=['MY_ENV_VAR'])] - value: Annotated[str | None, Field(examples=['my-value'])] = None - """ - The environment variable value. This field is absent in responses when `isSecret` is `true`, as secret values are never returned by the API. - """ - is_secret: Annotated[bool | None, Field(alias='isSecret', examples=[False])] = None - - -@docs_group('Models') -class EnvVarRequest(EnvVar): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class EnvVarResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: EnvVar - - -@docs_group('Models') -class ErrorDetail(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: ErrorType | None = None - message: str | None = None - """ - Human-readable error message describing what went wrong. - """ - - -@docs_group('Models') -class ErrorResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - error: ErrorDetail - - -@docs_group('Models') -class ErrorType(StrEnum): - """Machine-processable error type identifier.""" - - FIELD_3D_SECURE_AUTH_FAILED = '3d-secure-auth-failed' - ACCESS_RIGHT_ALREADY_EXISTS = 'access-right-already-exists' - ACTION_NOT_FOUND = 'action-not-found' - ACTOR_ALREADY_RENTED = 'actor-already-rented' - ACTOR_CAN_NOT_BE_RENTED = 'actor-can-not-be-rented' - ACTOR_DISABLED = 'actor-disabled' - ACTOR_IS_NOT_RENTED = 'actor-is-not-rented' - ACTOR_MEMORY_LIMIT_EXCEEDED = 'actor-memory-limit-exceeded' - ACTOR_NAME_EXISTS_NEW_OWNER = 'actor-name-exists-new-owner' - ACTOR_NAME_NOT_UNIQUE = 'actor-name-not-unique' - ACTOR_NOT_FOUND = 'actor-not-found' - ACTOR_NOT_GITHUB_ACTOR = 'actor-not-github-actor' - ACTOR_NOT_PUBLIC = 'actor-not-public' - ACTOR_PERMISSION_LEVEL_NOT_SUPPORTED_FOR_AGENTIC_PAYMENTS = ( - 'actor-permission-level-not-supported-for-agentic-payments' - ) - ACTOR_REVIEW_ALREADY_EXISTS = 'actor-review-already-exists' - ACTOR_RUN_FAILED = 'actor-run-failed' - ACTOR_STANDBY_NOT_SUPPORTED_FOR_AGENTIC_PAYMENTS = 'actor-standby-not-supported-for-agentic-payments' - ACTOR_TASK_NAME_NOT_UNIQUE = 'actor-task-name-not-unique' - AGENTIC_PAYMENT_INFO_RETRIEVAL_ERROR = 'agentic-payment-info-retrieval-error' - AGENTIC_PAYMENT_INFORMATION_MISSING = 'agentic-payment-information-missing' - AGENTIC_PAYMENT_INSUFFICIENT_AMOUNT = 'agentic-payment-insufficient-amount' - AGENTIC_PAYMENT_PROVIDER_INTERNAL_ERROR = 'agentic-payment-provider-internal-error' - AGENTIC_PAYMENT_PROVIDER_UNAUTHORIZED = 'agentic-payment-provider-unauthorized' - AIRTABLE_WEBHOOK_DEPRECATED = 'airtable-webhook-deprecated' - ALREADY_SUBSCRIBED_TO_PAID_ACTOR = 'already-subscribed-to-paid-actor' - APIFY_PLAN_REQUIRED_TO_USE_PAID_ACTOR = 'apify-plan-required-to-use-paid-actor' - APIFY_SIGNUP_NOT_ALLOWED = 'apify-signup-not-allowed' - AUTH_METHOD_NOT_SUPPORTED = 'auth-method-not-supported' - AUTHORIZATION_SERVER_NOT_FOUND = 'authorization-server-not-found' - AUTO_ISSUE_DATE_INVALID = 'auto-issue-date-invalid' - BACKGROUND_CHECK_REQUIRED = 'background-check-required' - BILLING_SYSTEM_ERROR = 'billing-system-error' - BLACK_FRIDAY_PLAN_EXPIRED = 'black-friday-plan-expired' - BRAINTREE_ERROR = 'braintree-error' - BRAINTREE_NOT_LINKED = 'braintree-not-linked' - BRAINTREE_OPERATION_TIMED_OUT = 'braintree-operation-timed-out' - BRAINTREE_UNSUPPORTED_CURRENCY = 'braintree-unsupported-currency' - BUILD_NOT_FOUND = 'build-not-found' - BUILD_OUTDATED = 'build-outdated' - CANNOT_ADD_APIFY_EVENTS_TO_PPE_ACTOR = 'cannot-add-apify-events-to-ppe-actor' - CANNOT_ADD_MULTIPLE_PRICING_INFOS = 'cannot-add-multiple-pricing-infos' - CANNOT_ADD_PRICING_INFO_THAT_ALTERS_PAST = 'cannot-add-pricing-info-that-alters-past' - CANNOT_ADD_SECOND_FUTURE_PRICING_INFO = 'cannot-add-second-future-pricing-info' - CANNOT_BUILD_ACTOR_FROM_WEBHOOK = 'cannot-build-actor-from-webhook' - CANNOT_CHANGE_BILLING_INTERVAL = 'cannot-change-billing-interval' - CANNOT_CHANGE_OWNER = 'cannot-change-owner' - CANNOT_CHARGE_APIFY_EVENT = 'cannot-charge-apify-event' - CANNOT_CHARGE_NON_PAY_PER_EVENT_ACTOR = 'cannot-charge-non-pay-per-event-actor' - CANNOT_COMMENT_AS_OTHER_USER = 'cannot-comment-as-other-user' - CANNOT_COPY_ACTOR_TASK = 'cannot-copy-actor-task' - CANNOT_CREATE_PAYOUT = 'cannot-create-payout' - CANNOT_CREATE_PUBLIC_ACTOR = 'cannot-create-public-actor' - CANNOT_CREATE_TAX_TRANSACTION = 'cannot-create-tax-transaction' - CANNOT_DELETE_CRITICAL_ACTOR = 'cannot-delete-critical-actor' - CANNOT_DELETE_INVOICE = 'cannot-delete-invoice' - CANNOT_DELETE_PAID_ACTOR = 'cannot-delete-paid-actor' - CANNOT_DISABLE_ONE_TIME_EVENT_FOR_APIFY_START_EVENT = 'cannot-disable-one-time-event-for-apify-start-event' - CANNOT_DISABLE_ORGANIZATION_WITH_ENABLED_MEMBERS = 'cannot-disable-organization-with-enabled-members' - CANNOT_DISABLE_USER_WITH_SUBSCRIPTION = 'cannot-disable-user-with-subscription' - CANNOT_LINK_OAUTH_TO_UNVERIFIED_EMAIL = 'cannot-link-oauth-to-unverified-email' - CANNOT_METAMORPH_TO_PAY_PER_RESULT_ACTOR = 'cannot-metamorph-to-pay-per-result-actor' - CANNOT_MODIFY_ACTOR_PRICING_TOO_FREQUENTLY = 'cannot-modify-actor-pricing-too-frequently' - CANNOT_MODIFY_ACTOR_PRICING_WITH_IMMEDIATE_EFFECT = 'cannot-modify-actor-pricing-with-immediate-effect' - CANNOT_OVERRIDE_PAID_ACTOR_TRIAL = 'cannot-override-paid-actor-trial' - CANNOT_PERMANENTLY_DELETE_SUBSCRIPTION = 'cannot-permanently-delete-subscription' - CANNOT_PUBLISH_ACTOR = 'cannot-publish-actor' - CANNOT_REDUCE_LAST_FULL_TOKEN = 'cannot-reduce-last-full-token' - CANNOT_REIMBURSE_MORE_THAN_ORIGINAL_CHARGE = 'cannot-reimburse-more-than-original-charge' - CANNOT_REIMBURSE_NON_RENTAL_CHARGE = 'cannot-reimburse-non-rental-charge' - CANNOT_REMOVE_OWN_ACTOR_FROM_RECENTLY_USED = 'cannot-remove-own-actor-from-recently-used' - CANNOT_REMOVE_PAYMENT_METHOD = 'cannot-remove-payment-method' - CANNOT_REMOVE_PRICING_INFO = 'cannot-remove-pricing-info' - CANNOT_REMOVE_RUNNING_RUN = 'cannot-remove-running-run' - CANNOT_REMOVE_USER_WITH_PUBLIC_ACTORS = 'cannot-remove-user-with-public-actors' - CANNOT_REMOVE_USER_WITH_SUBSCRIPTION = 'cannot-remove-user-with-subscription' - CANNOT_REMOVE_USER_WITH_UNPAID_INVOICE = 'cannot-remove-user-with-unpaid-invoice' - CANNOT_RENAME_ENV_VAR = 'cannot-rename-env-var' - CANNOT_RENT_PAID_ACTOR = 'cannot-rent-paid-actor' - CANNOT_REVIEW_OWN_ACTOR = 'cannot-review-own-actor' - CANNOT_SET_ACCESS_RIGHTS_FOR_OWNER = 'cannot-set-access-rights-for-owner' - CANNOT_SET_IS_STATUS_MESSAGE_TERMINAL = 'cannot-set-is-status-message-terminal' - CANNOT_UNPUBLISH_CRITICAL_ACTOR = 'cannot-unpublish-critical-actor' - CANNOT_UNPUBLISH_PAID_ACTOR = 'cannot-unpublish-paid-actor' - CANNOT_UNPUBLISH_PROFILE = 'cannot-unpublish-profile' - CANNOT_UPDATE_INVOICE_FIELD = 'cannot-update-invoice-field' - CONCURRENT_RUNS_LIMIT_EXCEEDED = 'concurrent-runs-limit-exceeded' - CONCURRENT_UPDATE_DETECTED = 'concurrent-update-detected' - CONFERENCE_TOKEN_NOT_FOUND = 'conference-token-not-found' - CONTENT_ENCODING_FORBIDDEN_FOR_HTML = 'content-encoding-forbidden-for-html' - COUPON_ALREADY_REDEEMED = 'coupon-already-redeemed' - COUPON_EXPIRED = 'coupon-expired' - COUPON_FOR_NEW_CUSTOMERS = 'coupon-for-new-customers' - COUPON_FOR_SUBSCRIBED_USERS = 'coupon-for-subscribed-users' - COUPON_LIMITS_ARE_IN_CONFLICT_WITH_CURRENT_LIMITS = 'coupon-limits-are-in-conflict-with-current-limits' - COUPON_MAX_NUMBER_OF_REDEMPTIONS_REACHED = 'coupon-max-number-of-redemptions-reached' - COUPON_NOT_FOUND = 'coupon-not-found' - COUPON_NOT_UNIQUE = 'coupon-not-unique' - COUPONS_DISABLED = 'coupons-disabled' - CREATE_GITHUB_ISSUE_NOT_ALLOWED = 'create-github-issue-not-allowed' - CREATOR_PLAN_NOT_AVAILABLE = 'creator-plan-not-available' - CRON_EXPRESSION_INVALID = 'cron-expression-invalid' - DAILY_AI_TOKEN_LIMIT_EXCEEDED = 'daily-ai-token-limit-exceeded' - DAILY_PUBLICATION_LIMIT_EXCEEDED = 'daily-publication-limit-exceeded' - DATASET_DOES_NOT_HAVE_FIELDS_SCHEMA = 'dataset-does-not-have-fields-schema' - DATASET_DOES_NOT_HAVE_SCHEMA = 'dataset-does-not-have-schema' - DATASET_LOCKED = 'dataset-locked' - DATASET_SCHEMA_INVALID = 'dataset-schema-invalid' - DCR_NOT_SUPPORTED = 'dcr-not-supported' - DEFAULT_DATASET_NOT_FOUND = 'default-dataset-not-found' - DELETING_DEFAULT_BUILD = 'deleting-default-build' - DELETING_UNFINISHED_BUILD = 'deleting-unfinished-build' - EMAIL_ALREADY_TAKEN = 'email-already-taken' - EMAIL_ALREADY_TAKEN_REMOVED_USER = 'email-already-taken-removed-user' - EMAIL_DOMAIN_NOT_ALLOWED_FOR_COUPON = 'email-domain-not-allowed-for-coupon' - EMAIL_INVALID = 'email-invalid' - EMAIL_NOT_ALLOWED = 'email-not-allowed' - EMAIL_NOT_VALID = 'email-not-valid' - EMAIL_UPDATE_TOO_SOON = 'email-update-too-soon' - ELEVATED_PERMISSIONS_NEEDED = 'elevated-permissions-needed' - ENV_VAR_ALREADY_EXISTS = 'env-var-already-exists' - EXCHANGE_RATE_FETCH_FAILED = 'exchange-rate-fetch-failed' - EXPIRED_CONFERENCE_TOKEN = 'expired-conference-token' - FAILED_TO_CHARGE_USER = 'failed-to-charge-user' - FINAL_INVOICE_NEGATIVE = 'final-invoice-negative' - GITHUB_BRANCH_EMPTY = 'github-branch-empty' - GITHUB_ISSUE_ALREADY_EXISTS = 'github-issue-already-exists' - GITHUB_PUBLIC_KEY_NOT_FOUND = 'github-public-key-not-found' - GITHUB_REPOSITORY_NOT_FOUND = 'github-repository-not-found' - GITHUB_SIGNATURE_DOES_NOT_MATCH_PAYLOAD = 'github-signature-does-not-match-payload' - GITHUB_USER_NOT_AUTHORIZED_FOR_ISSUES = 'github-user-not-authorized-for-issues' - GMAIL_NOT_ALLOWED = 'gmail-not-allowed' - ID_DOES_NOT_MATCH = 'id-does-not-match' - INCOMPATIBLE_BILLING_INTERVAL = 'incompatible-billing-interval' - INCOMPLETE_PAYOUT_BILLING_INFO = 'incomplete-payout-billing-info' - INCONSISTENT_CURRENCIES = 'inconsistent-currencies' - INCORRECT_PRICING_MODIFIER_PREFIX = 'incorrect-pricing-modifier-prefix' - INPUT_JSON_INVALID_CHARACTERS = 'input-json-invalid-characters' - INPUT_JSON_NOT_OBJECT = 'input-json-not-object' - INPUT_JSON_TOO_LONG = 'input-json-too-long' - INPUT_UPDATE_COLLISION = 'input-update-collision' - INSUFFICIENT_PERMISSIONS = 'insufficient-permissions' - INSUFFICIENT_PERMISSIONS_TO_CHANGE_FIELD = 'insufficient-permissions-to-change-field' - INSUFFICIENT_SECURITY_MEASURES = 'insufficient-security-measures' - INSUFFICIENT_TAX_COUNTRY_EVIDENCE = 'insufficient-tax-country-evidence' - INTEGRATION_AUTH_ERROR = 'integration-auth-error' - INTERNAL_SERVER_ERROR = 'internal-server-error' - INVALID_BILLING_INFO = 'invalid-billing-info' - INVALID_BILLING_PERIOD_FOR_PAYOUT = 'invalid-billing-period-for-payout' - INVALID_BUILD = 'invalid-build' - INVALID_CLIENT_KEY = 'invalid-client-key' - INVALID_COLLECTION = 'invalid-collection' - INVALID_CONFERENCE_LOGIN_PASSWORD = 'invalid-conference-login-password' - INVALID_CONTENT_TYPE_HEADER = 'invalid-content-type-header' - INVALID_CREDENTIALS = 'invalid-credentials' - INVALID_GIT_AUTH_TOKEN = 'invalid-git-auth-token' - INVALID_GITHUB_ISSUE_URL = 'invalid-github-issue-url' - INVALID_HEADER = 'invalid-header' - INVALID_ID = 'invalid-id' - INVALID_IDEMPOTENCY_KEY = 'invalid-idempotency-key' - INVALID_INPUT = 'invalid-input' - INVALID_INPUT_SCHEMA = 'invalid-input-schema' - INVALID_INVOICE = 'invalid-invoice' - INVALID_INVOICE_TYPE = 'invalid-invoice-type' - INVALID_ISSUE_DATE = 'invalid-issue-date' - INVALID_LABEL_PARAMS = 'invalid-label-params' - INVALID_MAIN_ACCOUNT_USER_ID = 'invalid-main-account-user-id' - INVALID_OAUTH_APP = 'invalid-oauth-app' - INVALID_OAUTH_SCOPE = 'invalid-oauth-scope' - INVALID_ONE_TIME_INVOICE = 'invalid-one-time-invoice' - INVALID_PARAMETER = 'invalid-parameter' - INVALID_PAYOUT_STATUS = 'invalid-payout-status' - INVALID_PICTURE_URL = 'invalid-picture-url' - INVALID_RECORD_KEY = 'invalid-record-key' - INVALID_REQUEST = 'invalid-request' - INVALID_RESOURCE_TYPE = 'invalid-resource-type' - INVALID_SIGNATURE = 'invalid-signature' - INVALID_SUBSCRIPTION_PLAN = 'invalid-subscription-plan' - INVALID_TAX_NUMBER = 'invalid-tax-number' - INVALID_TAX_NUMBER_FORMAT = 'invalid-tax-number-format' - INVALID_TOKEN = 'invalid-token' - INVALID_TOKEN_TYPE = 'invalid-token-type' - INVALID_TWO_FACTOR_CODE = 'invalid-two-factor-code' - INVALID_TWO_FACTOR_CODE_OR_RECOVERY_CODE = 'invalid-two-factor-code-or-recovery-code' - INVALID_TWO_FACTOR_RECOVERY_CODE = 'invalid-two-factor-recovery-code' - INVALID_USERNAME = 'invalid-username' - INVALID_VALUE = 'invalid-value' - INVITATION_INVALID_RESOURCE_TYPE = 'invitation-invalid-resource-type' - INVITATION_NO_LONGER_VALID = 'invitation-no-longer-valid' - INVOICE_CANCELED = 'invoice-canceled' - INVOICE_CANNOT_BE_REFUNDED_DUE_TO_TOO_HIGH_AMOUNT = 'invoice-cannot-be-refunded-due-to-too-high-amount' - INVOICE_INCOMPLETE = 'invoice-incomplete' - INVOICE_IS_DRAFT = 'invoice-is-draft' - INVOICE_LOCKED = 'invoice-locked' - INVOICE_MUST_BE_BUFFER = 'invoice-must-be-buffer' - INVOICE_NOT_CANCELED = 'invoice-not-canceled' - INVOICE_NOT_DRAFT = 'invoice-not-draft' - INVOICE_NOT_FOUND = 'invoice-not-found' - INVOICE_OUTDATED = 'invoice-outdated' - INVOICE_PAID_ALREADY = 'invoice-paid-already' - ISSUE_ALREADY_CONNECTED_TO_GITHUB = 'issue-already-connected-to-github' - ISSUE_NOT_FOUND = 'issue-not-found' - ISSUES_BAD_REQUEST = 'issues-bad-request' - ISSUER_NOT_REGISTERED = 'issuer-not-registered' - JOB_FINISHED = 'job-finished' - LABEL_ALREADY_LINKED = 'label-already-linked' - LAST_API_TOKEN = 'last-api-token' - LIMIT_REACHED = 'limit-reached' - MAX_ITEMS_MUST_BE_GREATER_THAN_ZERO = 'max-items-must-be-greater-than-zero' - MAX_METAMORPHS_EXCEEDED = 'max-metamorphs-exceeded' - MAX_TOTAL_CHARGE_USD_BELOW_MINIMUM = 'max-total-charge-usd-below-minimum' - MAX_TOTAL_CHARGE_USD_MUST_BE_GREATER_THAN_ZERO = 'max-total-charge-usd-must-be-greater-than-zero' - METHOD_NOT_ALLOWED = 'method-not-allowed' - MIGRATION_DISABLED = 'migration-disabled' - MISSING_ACTOR_RIGHTS = 'missing-actor-rights' - MISSING_API_TOKEN = 'missing-api-token' - MISSING_BILLING_INFO = 'missing-billing-info' - MISSING_LINE_ITEMS = 'missing-line-items' - MISSING_PAYMENT_DATE = 'missing-payment-date' - MISSING_PAYOUT_BILLING_INFO = 'missing-payout-billing-info' - MISSING_PROXY_PASSWORD = 'missing-proxy-password' - MISSING_REPORTING_FIELDS = 'missing-reporting-fields' - MISSING_RESOURCE_NAME = 'missing-resource-name' - MISSING_SETTINGS = 'missing-settings' - MISSING_USERNAME = 'missing-username' - MONTHLY_USAGE_LIMIT_TOO_LOW = 'monthly-usage-limit-too-low' - MORE_THAN_ONE_UPDATE_NOT_ALLOWED = 'more-than-one-update-not-allowed' - MULTIPLE_RECORDS_FOUND = 'multiple-records-found' - MUST_BE_ADMIN = 'must-be-admin' - NAME_NOT_UNIQUE = 'name-not-unique' - NEXT_RUNTIME_COMPUTATION_FAILED = 'next-runtime-computation-failed' - NO_COLUMNS_IN_EXPORTED_DATASET = 'no-columns-in-exported-dataset' - NO_PAYMENT_ATTEMPT_FOR_REFUND_FOUND = 'no-payment-attempt-for-refund-found' - NO_PAYMENT_METHOD_AVAILABLE = 'no-payment-method-available' - NO_TEAM_ACCOUNT_SEATS_AVAILABLE = 'no-team-account-seats-available' - NON_TEMPORARY_EMAIL = 'non-temporary-email' - NOT_ENOUGH_USAGE_TO_RUN_PAID_ACTOR = 'not-enough-usage-to-run-paid-actor' - NOT_IMPLEMENTED = 'not-implemented' - NOT_SUPPORTED_CURRENCIES = 'not-supported-currencies' - O_AUTH_SERVICE_ALREADY_CONNECTED = 'o-auth-service-already-connected' - O_AUTH_SERVICE_NOT_CONNECTED = 'o-auth-service-not-connected' - OAUTH_RESOURCE_ACCESS_FAILED = 'oauth-resource-access-failed' - ONE_TIME_INVOICE_ALREADY_MARKED_PAID = 'one-time-invoice-already-marked-paid' - ONLY_DRAFTS_CAN_BE_DELETED = 'only-drafts-can-be-deleted' - OPERATION_CANCELED = 'operation-canceled' - OPERATION_NOT_ALLOWED = 'operation-not-allowed' - OPERATION_TIMED_OUT = 'operation-timed-out' - ORGANIZATION_CANNOT_OWN_ITSELF = 'organization-cannot-own-itself' - ORGANIZATION_ROLE_NOT_FOUND = 'organization-role-not-found' - OVERLAPPING_PAYOUT_BILLING_PERIODS = 'overlapping-payout-billing-periods' - OWN_TOKEN_REQUIRED = 'own-token-required' - PAGE_NOT_FOUND = 'page-not-found' - PARAM_NOT_ONE_OF = 'param-not-one-of' - PARAMETER_REQUIRED = 'parameter-required' - PARAMETERS_MISMATCHED = 'parameters-mismatched' - PASSWORD_RESET_EMAIL_ALREADY_SENT = 'password-reset-email-already-sent' - PASSWORD_RESET_TOKEN_EXPIRED = 'password-reset-token-expired' - PAY_AS_YOU_GO_WITHOUT_MONTHLY_INTERVAL = 'pay-as-you-go-without-monthly-interval' - PAYMENT_ATTEMPT_STATUS_MESSAGE_REQUIRED = 'payment-attempt-status-message-required' - PAYOUT_ALREADY_PAID = 'payout-already-paid' - PAYOUT_CANCELED = 'payout-canceled' - PAYOUT_INVALID_STATE = 'payout-invalid-state' - PAYOUT_MUST_BE_APPROVED_TO_BE_MARKED_PAID = 'payout-must-be-approved-to-be-marked-paid' - PAYOUT_NOT_FOUND = 'payout-not-found' - PAYOUT_NUMBER_ALREADY_EXISTS = 'payout-number-already-exists' - PHONE_NUMBER_INVALID = 'phone-number-invalid' - PHONE_NUMBER_LANDLINE = 'phone-number-landline' - PHONE_NUMBER_OPTED_OUT = 'phone-number-opted-out' - PHONE_VERIFICATION_DISABLED = 'phone-verification-disabled' - PLATFORM_FEATURE_DISABLED = 'platform-feature-disabled' - PRICE_OVERRIDES_VALIDATION_FAILED = 'price-overrides-validation-failed' - PRICING_MODEL_NOT_SUPPORTED = 'pricing-model-not-supported' - PROMOTIONAL_PLAN_NOT_AVAILABLE = 'promotional-plan-not-available' - PROXY_AUTH_IP_NOT_UNIQUE = 'proxy-auth-ip-not-unique' - PUBLIC_ACTOR_DISABLED = 'public-actor-disabled' - QUERY_TIMEOUT = 'query-timeout' - QUOTED_PRICE_OUTDATED = 'quoted-price-outdated' - RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded' - RECAPTCHA_INVALID = 'recaptcha-invalid' - RECAPTCHA_REQUIRED = 'recaptcha-required' - RECORD_NOT_FOUND = 'record-not-found' - RECORD_NOT_PUBLIC = 'record-not-public' - RECORD_OR_TOKEN_NOT_FOUND = 'record-or-token-not-found' - RECORD_TOO_LARGE = 'record-too-large' - REDIRECT_URI_MISMATCH = 'redirect-uri-mismatch' - REDUCED_PLAN_NOT_AVAILABLE = 'reduced-plan-not-available' - RENTAL_CHARGE_ALREADY_REIMBURSED = 'rental-charge-already-reimbursed' - RENTAL_NOT_ALLOWED = 'rental-not-allowed' - REQUEST_ABORTED_PREMATURELY = 'request-aborted-prematurely' - REQUEST_HANDLED_OR_LOCKED = 'request-handled-or-locked' - REQUEST_ID_INVALID = 'request-id-invalid' - REQUEST_QUEUE_DUPLICATE_REQUESTS = 'request-queue-duplicate-requests' - REQUEST_TOO_LARGE = 'request-too-large' - REQUESTED_DATASET_VIEW_DOES_NOT_EXIST = 'requested-dataset-view-does-not-exist' - RESUME_TOKEN_EXPIRED = 'resume-token-expired' - RUN_FAILED = 'run-failed' - RUN_TIMEOUT_EXCEEDED = 'run-timeout-exceeded' - RUSSIA_IS_EVIL = 'russia-is-evil' - SAME_USER = 'same-user' - SCHEDULE_ACTOR_NOT_FOUND = 'schedule-actor-not-found' - SCHEDULE_ACTOR_TASK_NOT_FOUND = 'schedule-actor-task-not-found' - SCHEDULE_NAME_NOT_UNIQUE = 'schedule-name-not-unique' - SCHEMA_VALIDATION = 'schema-validation' - SCHEMA_VALIDATION_ERROR = 'schema-validation-error' - SCHEMA_VALIDATION_FAILED = 'schema-validation-failed' - SIGN_UP_METHOD_NOT_ALLOWED = 'sign-up-method-not-allowed' - SLACK_INTEGRATION_NOT_CUSTOM = 'slack-integration-not-custom' - SOCKET_CLOSED = 'socket-closed' - SOCKET_DESTROYED = 'socket-destroyed' - STORE_SCHEMA_INVALID = 'store-schema-invalid' - STORE_TERMS_NOT_ACCEPTED = 'store-terms-not-accepted' - STRIPE_ENABLED = 'stripe-enabled' - STRIPE_GENERIC_DECLINE = 'stripe-generic-decline' - STRIPE_NOT_ENABLED = 'stripe-not-enabled' - STRIPE_NOT_ENABLED_FOR_USER = 'stripe-not-enabled-for-user' - TAGGED_BUILD_REQUIRED = 'tagged-build-required' - TAX_COUNTRY_INVALID = 'tax-country-invalid' - TAX_NUMBER_INVALID = 'tax-number-invalid' - TAX_NUMBER_VALIDATION_FAILED = 'tax-number-validation-failed' - TAXAMO_CALL_FAILED = 'taxamo-call-failed' - TAXAMO_REQUEST_FAILED = 'taxamo-request-failed' - TESTING_ERROR = 'testing-error' - TOKEN_NOT_PROVIDED = 'token-not-provided' - TOO_FEW_VERSIONS = 'too-few-versions' - TOO_MANY_ACTOR_TASKS = 'too-many-actor-tasks' - TOO_MANY_ACTORS = 'too-many-actors' - TOO_MANY_LABELS_ON_RESOURCE = 'too-many-labels-on-resource' - TOO_MANY_MCP_CONNECTORS = 'too-many-mcp-connectors' - TOO_MANY_O_AUTH_APPS = 'too-many-o-auth-apps' - TOO_MANY_ORGANIZATIONS = 'too-many-organizations' - TOO_MANY_REQUESTS = 'too-many-requests' - TOO_MANY_SCHEDULES = 'too-many-schedules' - TOO_MANY_UI_ACCESS_KEYS = 'too-many-ui-access-keys' - TOO_MANY_USER_LABELS = 'too-many-user-labels' - TOO_MANY_VALUES = 'too-many-values' - TOO_MANY_VERSIONS = 'too-many-versions' - TOO_MANY_WEBHOOKS = 'too-many-webhooks' - UNEXPECTED_ROUTE = 'unexpected-route' - UNKNOWN_BUILD_TAG = 'unknown-build-tag' - UNKNOWN_PAYMENT_PROVIDER = 'unknown-payment-provider' - UNSUBSCRIBE_TOKEN_INVALID = 'unsubscribe-token-invalid' - UNSUPPORTED_ACTOR_PRICING_MODEL_FOR_AGENTIC_PAYMENTS = 'unsupported-actor-pricing-model-for-agentic-payments' - UNSUPPORTED_CONTENT_ENCODING = 'unsupported-content-encoding' - UNSUPPORTED_FILE_TYPE_FOR_ISSUE = 'unsupported-file-type-for-issue' - UNSUPPORTED_FILE_TYPE_IMAGE_EXPECTED = 'unsupported-file-type-image-expected' - UNSUPPORTED_FILE_TYPE_TEXT_OR_JSON_EXPECTED = 'unsupported-file-type-text-or-json-expected' - UNSUPPORTED_PERMISSION = 'unsupported-permission' - UPCOMING_SUBSCRIPTION_BILL_NOT_UP_TO_DATE = 'upcoming-subscription-bill-not-up-to-date' - USER_ALREADY_EXISTS = 'user-already-exists' - USER_ALREADY_VERIFIED = 'user-already-verified' - USER_CREATES_ORGANIZATIONS_TOO_FAST = 'user-creates-organizations-too-fast' - USER_DISABLED = 'user-disabled' - USER_EMAIL_IS_DISPOSABLE = 'user-email-is-disposable' - USER_EMAIL_NOT_SET = 'user-email-not-set' - USER_EMAIL_NOT_VERIFIED = 'user-email-not-verified' - USER_HAS_NO_SUBSCRIPTION = 'user-has-no-subscription' - USER_INTEGRATION_NOT_FOUND = 'user-integration-not-found' - USER_IS_ALREADY_INVITED = 'user-is-already-invited' - USER_IS_ALREADY_ORGANIZATION_MEMBER = 'user-is-already-organization-member' - USER_IS_NOT_MEMBER_OF_ORGANIZATION = 'user-is-not-member-of-organization' - USER_IS_NOT_ORGANIZATION = 'user-is-not-organization' - USER_IS_ORGANIZATION = 'user-is-organization' - USER_IS_ORGANIZATION_OWNER = 'user-is-organization-owner' - USER_IS_REMOVED = 'user-is-removed' - USER_NOT_FOUND = 'user-not-found' - USER_NOT_LOGGED_IN = 'user-not-logged-in' - USER_NOT_VERIFIED = 'user-not-verified' - USER_OR_TOKEN_NOT_FOUND = 'user-or-token-not-found' - USER_PLAN_NOT_ALLOWED_FOR_COUPON = 'user-plan-not-allowed-for-coupon' - USER_PROBLEM_WITH_CARD = 'user-problem-with-card' - USER_RECORD_NOT_FOUND = 'user-record-not-found' - USERNAME_ALREADY_TAKEN = 'username-already-taken' - USERNAME_MISSING = 'username-missing' - USERNAME_NOT_ALLOWED = 'username-not-allowed' - USERNAME_REMOVAL_FORBIDDEN = 'username-removal-forbidden' - USERNAME_REQUIRED = 'username-required' - VERIFICATION_EMAIL_ALREADY_SENT = 'verification-email-already-sent' - VERIFICATION_TOKEN_EXPIRED = 'verification-token-expired' - VERSION_ALREADY_EXISTS = 'version-already-exists' - VERSIONS_SIZE_EXCEEDED = 'versions-size-exceeded' - WEAK_PASSWORD = 'weak-password' - X402_AGENTIC_PAYMENT_ALREADY_FINALIZED = 'x402-agentic-payment-already-finalized' - X402_AGENTIC_PAYMENT_INSUFFICIENT_AMOUNT = 'x402-agentic-payment-insufficient-amount' - X402_AGENTIC_PAYMENT_MALFORMED_TOKEN = 'x402-agentic-payment-malformed-token' - X402_AGENTIC_PAYMENT_SETTLEMENT_FAILED = 'x402-agentic-payment-settlement-failed' - X402_AGENTIC_PAYMENT_SETTLEMENT_IN_PROGRESS = 'x402-agentic-payment-settlement-in-progress' - X402_AGENTIC_PAYMENT_SETTLEMENT_STUCK = 'x402-agentic-payment-settlement-stuck' - X402_AGENTIC_PAYMENT_UNAUTHORIZED = 'x402-agentic-payment-unauthorized' - X402_PAYMENT_REQUIRED = 'x402-payment-required' - ZERO_INVOICE = 'zero-invoice' - - -@docs_group('Models') -class EventData(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_id: Annotated[str, Field(alias='actorId', examples=['vvE7iMKuMc5qTHHsR'])] - actor_run_id: Annotated[str, Field(alias='actorRunId', examples=['JgwXN9BdwxGcu9MMF'])] - - -@docs_group('Models') -class ExampleRunInput(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - body: Annotated[str | None, Field(examples=['{ "helloWorld": 123 }'])] = None - content_type: Annotated[str | None, Field(alias='contentType', examples=['application/json; charset=utf-8'])] = None - - -@docs_group('Models') -class ExampleWebhookDispatch(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - status: WebhookDispatchStatus - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-13T08:36:13.202Z'])] = ( - None - ) - - -@docs_group('Models') -class FlatPricePerMonthActorPricingInfo(CommonActorPricingInfo): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - pricing_model: Annotated[Literal['FLAT_PRICE_PER_MONTH'], Field(alias='pricingModel')] - trial_minutes: Annotated[int, Field(alias='trialMinutes')] - """ - For how long this Actor can be used for free in trial period - """ - price_per_unit_usd: Annotated[float, Field(alias='pricePerUnitUsd')] - """ - Monthly flat price in USD - """ - - -@docs_group('Models') -class FreeActorPricingInfo(CommonActorPricingInfo): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - pricing_model: Annotated[Literal['FREE'], Field(alias='pricingModel')] - - -@docs_group('Models') -class GeneralAccess(StrEnum): - """Defines the general access level for the resource.""" - - ANYONE_WITH_ID_CAN_READ = 'ANYONE_WITH_ID_CAN_READ' - ANYONE_WITH_NAME_CAN_READ = 'ANYONE_WITH_NAME_CAN_READ' - FOLLOW_USER_SETTING = 'FOLLOW_USER_SETTING' - RESTRICTED = 'RESTRICTED' - - -@docs_group('Models') -class HeadAndLockResponse(BaseModel): - """Response containing locked requests from the request queue head.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: LockedRequestQueueHead - - -@docs_group('Models') -class HeadRequest(BaseModel): - """A request from the request queue head without lock information.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - url: Annotated[str, Field(examples=['https://apify.com'])] - """ - The URL of the request. - """ - method: HttpMethod | None = None - retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None - """ - The number of times this request has been retried. - """ - - -@docs_group('Models') -class HeadResponse(BaseModel): - """Response containing requests from the request queue head without locking.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: RequestQueueHead - - -@docs_group('Models') -class HttpMethod(StrEnum): - GET = 'GET' - HEAD = 'HEAD' - POST = 'POST' - PUT = 'PUT' - DELETE = 'DELETE' - CONNECT = 'CONNECT' - OPTIONS = 'OPTIONS' - TRACE = 'TRACE' - PATCH = 'PATCH' - - -@docs_group('Models') -class InvalidItem(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - item_position: Annotated[int | None, Field(alias='itemPosition', examples=[2])] = None - """ - The position of the invalid item in the array. - """ - validation_errors: Annotated[list[ValidationError] | None, Field(alias='validationErrors')] = None - """ - A complete list of AJV validation error objects for the invalid item. - """ - - -@docs_group('Models') -class KeyValueStore(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] - name: Annotated[str | None, Field(examples=['d7b9MDYsbtX5L7XAj'])] = None - user_id: Annotated[str | None, Field(alias='userId', examples=['BPWDBd7Z9c746JAnF'])] = None - username: Annotated[str | None, Field(examples=['janedoe'])] = None - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] - act_id: Annotated[str | None, Field(alias='actId', examples=[None])] = None - act_run_id: Annotated[str | None, Field(alias='actRunId', examples=[None])] = None - console_url: Annotated[ - AnyUrl | None, - Field(alias='consoleUrl', examples=['https://console.apify.com/storage/key-value-stores/27TmTznX9YPeAYhkC']), - ] = None - keys_public_url: Annotated[ - AnyUrl | None, - Field( - alias='keysPublicUrl', - examples=['https://api.apify.com/v2/key-value-stores/WkzbQMuFYuamGv3YF/keys?signature=abc123'], - ), - ] = None - """ - A public link to access keys of the key-value store directly. - """ - url_signing_secret_key: Annotated[str | None, Field(alias='urlSigningSecretKey')] = None - """ - A secret key for generating signed public URLs. It is only provided to clients with WRITE permission for the key-value store. - """ - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - stats: KeyValueStoreStats | None = None - - -@docs_group('Models') -class KeyValueStoreKey(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - key: Annotated[str, Field(examples=['second-key'])] - size: Annotated[int, Field(examples=[36])] - record_public_url: Annotated[ - AnyUrl, - Field( - alias='recordPublicUrl', - examples=['https://api.apify.com/v2/key-value-stores/WkzbQMuFYuamGv3YF/records/some-key?signature=abc123'], - ), - ] - """ - A public link to access this record directly. - """ - - -@docs_group('Models') -class KeyValueStoreResponse(BaseModel): - """Response containing key-value store data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: KeyValueStore - - -@docs_group('Models') -class KeyValueStoreStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - read_count: Annotated[int, Field(alias='readCount', examples=[9])] - write_count: Annotated[int, Field(alias='writeCount', examples=[3])] - delete_count: Annotated[int, Field(alias='deleteCount', examples=[6])] - list_count: Annotated[int, Field(alias='listCount', examples=[2])] - s3_storage_bytes: Annotated[int | None, Field(alias='s3StorageBytes', examples=[18])] = None - - -@docs_group('Models') -class KeyValueStores(BaseModel): - """Aliased key-value store IDs for this run.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - default: Annotated[str | None, Field(examples=['eJNzqsbPiopwJcgGQ'])] = None - """ - ID of the default key-value store for this run. - """ - - -@docs_group('Models') -class Limits(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - max_monthly_usage_usd: Annotated[float, Field(alias='maxMonthlyUsageUsd', examples=[300])] - max_monthly_actor_compute_units: Annotated[float, Field(alias='maxMonthlyActorComputeUnits', examples=[1000])] - max_monthly_external_data_transfer_gbytes: Annotated[ - float, Field(alias='maxMonthlyExternalDataTransferGbytes', examples=[7]) - ] - max_monthly_proxy_serps: Annotated[int, Field(alias='maxMonthlyProxySerps', examples=[50])] - max_monthly_residential_proxy_gbytes: Annotated[ - float, Field(alias='maxMonthlyResidentialProxyGbytes', examples=[0.5]) - ] - max_actor_memory_gbytes: Annotated[float, Field(alias='maxActorMemoryGbytes', examples=[16])] - max_actor_count: Annotated[int, Field(alias='maxActorCount', examples=[100])] - max_actor_task_count: Annotated[int, Field(alias='maxActorTaskCount', examples=[1000])] - max_concurrent_actor_jobs: Annotated[int, Field(alias='maxConcurrentActorJobs', examples=[256])] - max_team_account_seat_count: Annotated[int, Field(alias='maxTeamAccountSeatCount', examples=[9])] - data_retention_days: Annotated[int, Field(alias='dataRetentionDays', examples=[90])] - - -@docs_group('Models') -class LimitsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: AccountLimits - - -@docs_group('Models') -class ListOfActorsInStoreResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfStoreActors - - -@docs_group('Models') -class ListOfActorsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfActors - - -@docs_group('Models') -class ListOfBuildsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfBuilds - - -@docs_group('Models') -class ListOfDatasetsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfDatasets - - -@docs_group('Models') -class ListOfEnvVars(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total: Annotated[int, Field(examples=[5])] - items: list[EnvVar] - - -@docs_group('Models') -class ListOfEnvVarsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfEnvVars - - -@docs_group('Models') -class ListOfKeyValueStoresResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfKeyValueStores - - -@docs_group('Models') -class ListOfKeys(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[KeyValueStoreKey] - count: Annotated[int, Field(examples=[2])] - limit: Annotated[int, Field(examples=[2])] - exclusive_start_key: Annotated[str | None, Field(alias='exclusiveStartKey', examples=['some-key'])] = None - is_truncated: Annotated[bool, Field(alias='isTruncated', examples=[True])] - next_exclusive_start_key: Annotated[str | None, Field(alias='nextExclusiveStartKey', examples=['third-key'])] = None - - -@docs_group('Models') -class ListOfKeysResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfKeys - - -@docs_group('Models') -class ListOfRequestQueuesResponse(BaseModel): - """Response containing a list of request queues.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfRequestQueues - - -@docs_group('Models') -class ListOfRequests(BaseModel): - """A paginated list of requests from the request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[Request] - """ - The array of requests. - """ - count: Annotated[int | None, Field(examples=[2])] = None - """ - The total number of requests matching the query. - """ - limit: Annotated[int, Field(examples=[2])] - """ - The maximum number of requests returned in this response. - """ - exclusive_start_id: Annotated[ - str | None, Field(alias='exclusiveStartId', deprecated=True, examples=['Ihnsp8YrvJ8102Kj']) - ] = None - """ - The ID of the last request from the previous page, used for pagination. - """ - cursor: Annotated[str | None, Field(examples=['eyJyZXF1ZXN0SWQiOiI0SVlLUWFXZ2FKUUlWNlMifQ'])] = None - """ - A cursor string used for current page of results. - """ - next_cursor: Annotated[ - str | None, Field(alias='nextCursor', examples=['eyJyZXF1ZXN0SWQiOiI5eFNNc1BrN1J6VUxTNXoifQ']) - ] = None - """ - A cursor string to be used to continue pagination. - """ - - -@docs_group('Models') -class ListOfRequestsResponse(BaseModel): - """Response containing a list of requests from the request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfRequests - - -@docs_group('Models') -class ListOfRunsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfRuns - - -@docs_group('Models') -class ListOfSchedulesResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfSchedules - - -@docs_group('Models') -class ListOfTasksResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfTasks - - -@docs_group('Models') -class ListOfVersions(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total: Annotated[int, Field(examples=[5])] - items: list[Version] - - -@docs_group('Models') -class ListOfVersionsResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfVersions - - -@docs_group('Models') -class ListOfWebhooksResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfWebhooks - - -@docs_group('Models') -class LockedHeadRequest(BaseModel): - """A request from the request queue head that has been locked for processing.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - url: Annotated[str, Field(examples=['https://apify.com'])] - """ - The URL of the request. - """ - method: HttpMethod | None = None - retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None - """ - The number of times this request has been retried. - """ - lock_expires_at: Annotated[AwareDatetime, Field(alias='lockExpiresAt', examples=['2022-06-14T23:00:00.000Z'])] - """ - The timestamp when the lock on this request expires. - """ - - -@docs_group('Models') -class LockedRequestQueueHead(BaseModel): - """A batch of locked requests from the request queue head.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - limit: Annotated[int, Field(examples=[1000])] - """ - The maximum number of requests returned. - """ - queue_modified_at: Annotated[AwareDatetime, Field(alias='queueModifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - """ - The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. - """ - queue_has_locked_requests: Annotated[bool | None, Field(alias='queueHasLockedRequests', examples=[True])] = None - """ - Whether the request queue contains requests locked by any client (either the one calling the endpoint or a different one). - """ - client_key: Annotated[str | None, Field(alias='clientKey', examples=['client-one'])] = None - """ - The client key used for locking the requests. - """ - had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] - """ - Whether the request queue has been accessed by multiple different clients. - """ - lock_secs: Annotated[int, Field(alias='lockSecs', examples=[60])] - """ - The number of seconds the locks will be held. - """ - items: list[LockedHeadRequest] - """ - The array of locked requests from the request queue head. - """ - - -@docs_group('Models') -class Metamorph(BaseModel): - """Information about a metamorph event that occurred during the run.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-11-30T07:39:24.202Z'])] - """ - Time when the metamorph occurred. - """ - actor_id: Annotated[str, Field(alias='actorId', examples=['nspoEjklmnsF2oosD'])] - """ - ID of the Actor that the run was metamorphed to. - """ - build_id: Annotated[str, Field(alias='buildId', examples=['ME6oKecqy5kXDS4KQ'])] - """ - ID of the build used for the metamorphed Actor. - """ - input_key: Annotated[str | None, Field(alias='inputKey', examples=['INPUT-METAMORPH-1'])] = None - """ - Key of the input record in the key-value store. - """ - - -@docs_group('Models') -class MonthlyUsage(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - usage_cycle: Annotated[UsageCycle, Field(alias='usageCycle')] - monthly_service_usage: Annotated[dict[str, UsageItem], Field(alias='monthlyServiceUsage')] - daily_service_usages: Annotated[list[DailyServiceUsages], Field(alias='dailyServiceUsages')] - total_usage_credits_usd_before_volume_discount: Annotated[ - float, Field(alias='totalUsageCreditsUsdBeforeVolumeDiscount', examples=[0.786143673840067]) - ] - total_usage_credits_usd_after_volume_discount: Annotated[ - float, Field(alias='totalUsageCreditsUsdAfterVolumeDiscount', examples=[0.786143673840067]) - ] - - -@docs_group('Models') -class MonthlyUsageResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: MonthlyUsage - - -@docs_group('Models') -class PaginationResponse(BaseModel): - """Common pagination fields for list responses.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total: Annotated[int, Field(examples=[1], ge=0)] - """ - The total number of items available across all pages. - """ - offset: Annotated[int, Field(examples=[0], ge=0)] - """ - The starting position for this page of results. - """ - limit: Annotated[int, Field(examples=[1000], ge=1)] - """ - The maximum number of items returned per page. - """ - desc: Annotated[bool, Field(examples=[False])] - """ - Whether the results are sorted in descending order. - """ - count: Annotated[int, Field(examples=[1], ge=0)] - """ - The number of items returned in this response. - """ - - -@docs_group('Models') -class ListOfActors(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[ActorShort] - - -@docs_group('Models') -class ListOfBuilds(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[BuildShort] - - -@docs_group('Models') -class ListOfDatasets(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[DatasetListItem] - - -@docs_group('Models') -class ListOfKeyValueStores(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[KeyValueStore] - - -@docs_group('Models') -class ListOfRequestQueues(PaginationResponse): - """A paginated list of request queues.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[RequestQueueShort] - """ - The array of request queues. - """ - - -@docs_group('Models') -class ListOfRuns(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[RunShort] - - -@docs_group('Models') -class ListOfSchedules(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[ScheduleShort] - - -@docs_group('Models') -class ListOfStoreActors(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[StoreListActor] - - -@docs_group('Models') -class ListOfTasks(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[TaskShort] - - -@docs_group('Models') -class ListOfWebhookDispatches(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[WebhookDispatch] - - -@docs_group('Models') -class ListOfWebhooks(PaginationResponse): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - items: list[WebhookShort] - - -@docs_group('Models') -class PayPerEventActorPricingInfo(CommonActorPricingInfo): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - pricing_model: Annotated[Literal['PAY_PER_EVENT'], Field(alias='pricingModel')] - pricing_per_event: Annotated[PricingPerEvent, Field(alias='pricingPerEvent')] - minimal_max_total_charge_usd: Annotated[float | None, Field(alias='minimalMaxTotalChargeUsd')] = None - - -@docs_group('Models') -class Plan(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['Personal'])] - description: Annotated[str, Field(examples=['Cost-effective plan for freelancers, developers and students.'])] - is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] - monthly_base_price_usd: Annotated[float, Field(alias='monthlyBasePriceUsd', examples=[49])] - monthly_usage_credits_usd: Annotated[float, Field(alias='monthlyUsageCreditsUsd', examples=[49])] - usage_discount_percent: Annotated[float | None, Field(alias='usageDiscountPercent', examples=[0])] = None - enabled_platform_features: Annotated[ - list[str], - Field( - alias='enabledPlatformFeatures', examples=[['ACTORS', 'STORAGE', 'PROXY_SERPS', 'SCHEDULER', 'WEBHOOKS']] - ), - ] - max_monthly_usage_usd: Annotated[float, Field(alias='maxMonthlyUsageUsd', examples=[9999])] - max_actor_memory_gbytes: Annotated[float, Field(alias='maxActorMemoryGbytes', examples=[32])] - max_monthly_actor_compute_units: Annotated[float, Field(alias='maxMonthlyActorComputeUnits', examples=[1000])] - max_monthly_residential_proxy_gbytes: Annotated[ - float, Field(alias='maxMonthlyResidentialProxyGbytes', examples=[10]) - ] - max_monthly_proxy_serps: Annotated[int, Field(alias='maxMonthlyProxySerps', examples=[30000])] - max_monthly_external_data_transfer_gbytes: Annotated[ - float, Field(alias='maxMonthlyExternalDataTransferGbytes', examples=[1000]) - ] - max_actor_count: Annotated[int, Field(alias='maxActorCount', examples=[100])] - max_actor_task_count: Annotated[int, Field(alias='maxActorTaskCount', examples=[1000])] - data_retention_days: Annotated[int, Field(alias='dataRetentionDays', examples=[14])] - available_proxy_groups: Annotated[dict[str, int], Field(alias='availableProxyGroups')] - """ - The number of available proxies in this group. - """ - team_account_seat_count: Annotated[int, Field(alias='teamAccountSeatCount', examples=[1])] - support_level: Annotated[str, Field(alias='supportLevel', examples=['COMMUNITY'])] - available_add_ons: Annotated[list[str], Field(alias='availableAddOns', examples=[[]])] - - -@docs_group('Models') -class PricePerDatasetItemActorPricingInfo(CommonActorPricingInfo): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - pricing_model: Annotated[Literal['PRICE_PER_DATASET_ITEM'], Field(alias='pricingModel')] - unit_name: Annotated[str, Field(alias='unitName')] - """ - Name of the unit that is being charged - """ - price_per_unit_usd: Annotated[float, Field(alias='pricePerUnitUsd')] - - -@docs_group('Models') -class PriceTiers(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - quantity_above: Annotated[float, Field(alias='quantityAbove', examples=[0])] - discount_percent: Annotated[float, Field(alias='discountPercent', examples=[100])] - tier_quantity: Annotated[float, Field(alias='tierQuantity', examples=[0.39])] - unit_price_usd: Annotated[float, Field(alias='unitPriceUsd', examples=[0])] - price_usd: Annotated[float, Field(alias='priceUsd', examples=[0])] - - -@docs_group('Models') -class PricingPerEvent(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_charge_events: Annotated[dict[str, ActorChargeEvent] | None, Field(alias='actorChargeEvents')] = None - - -@docs_group('Models') -class PrivateUserDataResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: UserPrivateInfo - - -@docs_group('Models') -class Profile(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - bio: Annotated[str | None, Field(examples=['I started web scraping in 1985 using Altair BASIC.'])] = None - name: Annotated[str | None, Field(examples=['Jane Doe'])] = None - picture_url: Annotated[ - AnyUrl | None, Field(alias='pictureUrl', examples=['https://apify.com/img/anonymous_user_picture.png']) - ] = None - github_username: Annotated[str | None, Field(alias='githubUsername', examples=['torvalds.'])] = None - website_url: Annotated[AnyUrl | None, Field(alias='websiteUrl', examples=['http://www.example.com'])] = None - twitter_username: Annotated[str | None, Field(alias='twitterUsername', examples=['@BillGates'])] = None - - -@docs_group('Models') -class ProlongRequestLockResponse(BaseModel): - """Response containing updated lock information after prolonging a request lock.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: RequestLockInfo - - -@docs_group('Models') -class Proxy(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - password: Annotated[str, Field(examples=['ad78knd9Jkjd86'])] - groups: list[ProxyGroup] - - -@docs_group('Models') -class ProxyGroup(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str, Field(examples=['Group1'])] - description: Annotated[str, Field(examples=['Group1 description'])] - available_count: Annotated[int, Field(alias='availableCount', examples=[10])] - - -@docs_group('Models') -class PublicUserDataResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: UserPublicInfo - - -@docs_group('Models') -class PutItemResponseError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - error: DatasetSchemaValidationError - - -@docs_group('Models') -class PutItemsRequest(BaseModel): - """The request body containing the item(s) to add to the dataset. Can be a single - object or an array of objects. Each object represents one dataset item. - - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class PutRecordRequest(BaseModel): - """The request body contains the value to store in the record. The content type - should be specified in the Content-Type header. - - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class RecordResponse(BaseModel): - """The response body contains the value of the record. The content type of the response - is determined by the Content-Type header stored with the record. - - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class RequestBase(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - unique_key: Annotated[ - str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) - ] = None - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - url: Annotated[str | None, Field(examples=['https://apify.com'])] = None - """ - The URL of the request. - """ - method: HttpMethod | None = None - retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None - """ - The number of times this request has been retried. - """ - loaded_url: Annotated[str | None, Field(alias='loadedUrl', examples=['https://apify.com/jobs'])] = None - """ - The final URL that was loaded, after redirects (if any). - """ - payload: Annotated[str | dict[str, Any] | None, Field(examples=[None])] = None - """ - The request payload, typically used with POST or PUT requests. - """ - headers: Annotated[dict[str, Any] | None, Field(examples=[None])] = None - """ - HTTP headers sent with the request. - """ - user_data: Annotated[RequestUserData | None, Field(alias='userData')] = None - no_retry: Annotated[bool | None, Field(alias='noRetry', examples=[False])] = None - """ - Indicates whether the request should not be retried if processing fails. - """ - error_messages: Annotated[list[str] | None, Field(alias='errorMessages', examples=[None])] = None - """ - Error messages recorded from failed processing attempts. - """ - handled_at: Annotated[AwareDatetime | None, Field(alias='handledAt', examples=['2019-06-16T10:23:31.607Z'])] = None - """ - The timestamp when the request was marked as handled, if applicable. - """ - - -@docs_group('Models') -class Request(RequestBase): - """A request stored in the request queue, including its metadata and processing state.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """ - A unique identifier assigned to the request. - """ - - -@docs_group('Models') -class RequestDraft(BaseModel): - """A request that failed to be processed during a request queue operation and can be retried.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - url: Annotated[str, Field(examples=['https://apify.com'])] - """ - The URL of the request. - """ - method: HttpMethod | None = None - - -@docs_group('Models') -class RequestDraftDeleteById(BaseModel): - """A request that should be deleted, identified by its ID.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[ - str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) - ] = None - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - - -@docs_group('Models') -class RequestDraftDeleteByUniqueKey(BaseModel): - """A request that should be deleted, identified by its unique key.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """ - A unique identifier assigned to the request. - """ - unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] - """ - A unique key used for request de-duplication. Requests with the same unique key are considered identical. - """ - - -@docs_group('Models') -class RequestDraftDelete(RootModel[RequestDraftDeleteById | RequestDraftDeleteByUniqueKey]): - root: Annotated[RequestDraftDeleteById | RequestDraftDeleteByUniqueKey, Field(title='RequestDraftDelete')] - """ - A request that should be deleted. - """ - - -@docs_group('Models') -class RequestLockInfo(BaseModel): - """Information about a request lock.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - lock_expires_at: Annotated[AwareDatetime, Field(alias='lockExpiresAt', examples=['2022-06-14T23:00:00.000Z'])] - """ - The timestamp when the lock on this request expires. - """ - - -@docs_group('Models') -class RequestQueue(BaseModel): - """A request queue object containing metadata and statistics.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] - """ - A unique identifier assigned to the request queue. - """ - name: Annotated[str | None, Field(examples=['some-name'])] = None - """ - The name of the request queue. - """ - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - """ - The ID of the user who owns the request queue. - """ - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - """ - The timestamp when the request queue was created. - """ - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - """ - The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. - """ - accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] - """ - The timestamp when the request queue was last accessed. - """ - total_request_count: Annotated[int, Field(alias='totalRequestCount', examples=[870], ge=0)] - """ - The total number of requests in the request queue. - """ - handled_request_count: Annotated[int, Field(alias='handledRequestCount', examples=[100], ge=0)] - """ - The number of requests that have been handled. - """ - pending_request_count: Annotated[int, Field(alias='pendingRequestCount', examples=[670], ge=0)] - """ - The number of requests that are pending and have not been handled yet. - """ - had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] - """ - Whether the request queue has been accessed by multiple different clients. - """ - console_url: Annotated[ - AnyUrl, Field(alias='consoleUrl', examples=['https://api.apify.com/v2/request-queues/27TmTznX9YPeAYhkC']) - ] - """ - The URL to view the request queue in the Apify console. - """ - stats: RequestQueueStats | None = None - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - - -@docs_group('Models') -class RequestQueueHead(BaseModel): - """A batch of requests from the request queue head without locking.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - limit: Annotated[int, Field(examples=[1000])] - """ - The maximum number of requests returned. - """ - queue_modified_at: Annotated[AwareDatetime, Field(alias='queueModifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - """ - The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. - """ - had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] - """ - Whether the request queue has been accessed by multiple different clients. - """ - items: list[HeadRequest] - """ - The array of requests from the request queue head. - """ - - -@docs_group('Models') -class RequestQueueResponse(BaseModel): - """Response containing request queue data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: RequestQueue - - -@docs_group('Models') -class RequestQueueShort(BaseModel): - """A shortened request queue object for list responses.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] - """ - A unique identifier assigned to the request queue. - """ - name: Annotated[str, Field(examples=['some-name'])] - """ - The name of the request queue. - """ - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - """ - The ID of the user who owns the request queue. - """ - username: Annotated[str, Field(examples=['janedoe'])] - """ - The username of the user who owns the request queue. - """ - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - """ - The timestamp when the request queue was created. - """ - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - """ - The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. - """ - accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] - """ - The timestamp when the request queue was last accessed. - """ - expire_at: Annotated[AwareDatetime | None, Field(alias='expireAt', examples=['2019-06-02T17:15:06.751Z'])] = None - """ - The timestamp when the request queue will expire and be deleted. - """ - total_request_count: Annotated[int, Field(alias='totalRequestCount', examples=[870], ge=0)] - """ - The total number of requests in the request queue. - """ - handled_request_count: Annotated[int, Field(alias='handledRequestCount', examples=[100], ge=0)] - """ - The number of requests that have been handled. - """ - pending_request_count: Annotated[int, Field(alias='pendingRequestCount', examples=[670], ge=0)] - """ - The number of requests that are pending and have not been handled yet. - """ - act_id: Annotated[str | None, Field(alias='actId')] = None - """ - The ID of the Actor that created this request queue. - """ - act_run_id: Annotated[str | None, Field(alias='actRunId')] = None - """ - The ID of the Actor run that created this request queue. - """ - had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] - """ - Whether the request queue has been accessed by multiple different clients. - """ - - -@docs_group('Models') -class RequestQueueStats(BaseModel): - """Statistics about request queue operations and storage.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - delete_count: Annotated[int | None, Field(alias='deleteCount', examples=[0])] = None - """ - The number of delete operations performed on the request queue. - """ - head_item_read_count: Annotated[int | None, Field(alias='headItemReadCount', examples=[5])] = None - """ - The number of times requests from the head were read. - """ - read_count: Annotated[int | None, Field(alias='readCount', examples=[100])] = None - """ - The total number of read operations performed on the request queue. - """ - storage_bytes: Annotated[int | None, Field(alias='storageBytes', examples=[1024])] = None - """ - The total storage size in bytes used by the request queue. - """ - write_count: Annotated[int | None, Field(alias='writeCount', examples=[10])] = None - """ - The total number of write operations performed on the request queue. - """ - - -@docs_group('Models') -class RequestQueues(BaseModel): - """Aliased request queue IDs for this run.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - default: Annotated[str | None, Field(examples=['FL35cSF7jrxr3BY39'])] = None - """ - ID of the default request queue for this run. - """ - - -@docs_group('Models') -class RequestRegistration(BaseModel): - """Result of registering a request in the request queue, either by adding a new request or updating an existing one.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - request_id: Annotated[str, Field(alias='requestId', examples=['sbJ7klsdf7ujN9l'])] - """ - A unique identifier assigned to the request. - """ - was_already_present: Annotated[bool, Field(alias='wasAlreadyPresent', examples=[False])] - """ - Indicates whether a request with the same unique key already existed in the request queue. If true, no new request was created. - """ - was_already_handled: Annotated[bool, Field(alias='wasAlreadyHandled', examples=[False])] - """ - Indicates whether a request with the same unique key has already been processed by the request queue. - """ - - -@docs_group('Models') -class RequestResponse(BaseModel): - """Response containing a single request from the request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Request - - -@docs_group('Models') -class RequestUserData(BaseModel): - """Custom user data attached to the request. Can contain arbitrary fields.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class Run(BaseModel): - """Represents an Actor run and its associated data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] - """ - Unique identifier of the Actor run. - """ - act_id: Annotated[str, Field(alias='actId', examples=['HDSasDasz78YcAPEB'])] - """ - ID of the Actor that was run. - """ - user_id: Annotated[str, Field(alias='userId', examples=['7sT5jcggjjA9fNcxF'])] - """ - ID of the user who started the run. - """ - actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['KJHSKHausidyaJKHs'])] = None - """ - ID of the Actor task, if the run was started from a task. - """ - started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] - """ - Time when the Actor run started. - """ - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( - None - ) - """ - Time when the Actor run finished. - """ - status: ActorJobStatus - """ - Current status of the Actor run. - """ - status_message: Annotated[str | None, Field(alias='statusMessage', examples=['Actor is running'])] = None - """ - Detailed message about the run status. - """ - is_status_message_terminal: Annotated[bool | None, Field(alias='isStatusMessageTerminal', examples=[False])] = None - """ - Whether the status message is terminal (final). - """ - meta: RunMeta - """ - Metadata about the Actor run. - """ - pricing_info: Annotated[ - PayPerEventActorPricingInfo - | PricePerDatasetItemActorPricingInfo - | FlatPricePerMonthActorPricingInfo - | FreeActorPricingInfo - | None, - Field(alias='pricingInfo', discriminator='pricing_model', title='ActorRunPricingInfo'), - ] = None - """ - Pricing information for the Actor. - """ - stats: RunStats - """ - Statistics of the Actor run. - """ - charged_event_counts: Annotated[ - dict[str, int] | None, - Field(alias='chargedEventCounts', examples=[{'actor-start': 1, 'page-crawled': 150, 'data-extracted': 75}]), - ] = None - """ - A map of charged event types to their counts. The keys are event type identifiers defined by the Actor's pricing model (pay-per-event), and the values are the number of times each event was charged during this run. - """ - options: RunOptions - """ - Configuration options for the Actor run. - """ - build_id: Annotated[str, Field(alias='buildId', examples=['7sT5jcggjjA9fNcxF'])] - """ - ID of the Actor build used for this run. - """ - exit_code: Annotated[int | None, Field(alias='exitCode', examples=[0])] = None - """ - Exit code of the Actor run process. - """ - general_access: Annotated[GeneralAccess, Field(alias='generalAccess')] - """ - General access level for the Actor run. - """ - default_key_value_store_id: Annotated[str, Field(alias='defaultKeyValueStoreId', examples=['eJNzqsbPiopwJcgGQ'])] - """ - ID of the default key-value store for this run. - """ - default_dataset_id: Annotated[str, Field(alias='defaultDatasetId', examples=['wmKPijuyDnPZAPRMk'])] - """ - ID of the default dataset for this run. - """ - default_request_queue_id: Annotated[str, Field(alias='defaultRequestQueueId', examples=['FL35cSF7jrxr3BY39'])] - """ - ID of the default request queue for this run. - """ - storage_ids: Annotated[StorageIds | None, Field(alias='storageIds')] = None - """ - A map of aliased storage IDs associated with this run, grouped by storage type. - """ - build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.36'])] = None - """ - Build number of the Actor build used for this run. - """ - container_url: Annotated[ - AnyUrl | None, Field(alias='containerUrl', examples=['https://g8kd8kbc5ge8.runs.apify.net']) - ] = None - """ - URL of the container running the Actor. - """ - is_container_server_ready: Annotated[bool | None, Field(alias='isContainerServerReady', examples=[True])] = None - """ - Whether the container's HTTP server is ready to accept requests. - """ - git_branch_name: Annotated[str | None, Field(alias='gitBranchName', examples=['master'])] = None - """ - Name of the git branch used for the Actor build. - """ - usage: RunUsage | None = None - """ - Resource usage statistics for the run. - """ - usage_total_usd: Annotated[float | None, Field(alias='usageTotalUsd', examples=[0.2654])] = None - """ - Total cost in USD for this run. Represents what you actually pay. For run owners: includes platform usage (compute units) and/or event costs depending on the Actor's pricing model. For run non-owners: only available for Pay-Per-Event Actors (event costs only). Requires authentication token to access. - """ - usage_usd: Annotated[RunUsageUsd | None, Field(alias='usageUsd')] = None - """ - Platform usage costs breakdown in USD. Only present if you own the run AND are paying for platform usage (Pay-Per-Usage, Rental, or Pay-Per-Event with usage costs like standby Actors). Not available for standard Pay-Per-Event Actors. Requires authentication token to access. - """ - metamorphs: list[Metamorph] | None = None - """ - List of metamorph events that occurred during the run. - """ - - -@docs_group('Models') -class RunFailedErrorDetail(ErrorDetail): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Annotated[Literal['run-failed'], Field(title='ErrorType')] = 'run-failed' - """ - Machine-processable error type identifier. - """ - - -@docs_group('Models') -class RunMeta(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - origin: RunOrigin - client_ip: Annotated[str | None, Field(alias='clientIp')] = None - """ - IP address of the client that started the run. - """ - user_agent: Annotated[str | None, Field(alias='userAgent')] = None - """ - User agent of the client that started the run. - """ - schedule_id: Annotated[str | None, Field(alias='scheduleId')] = None - """ - ID of the schedule that triggered the run. - """ - scheduled_at: Annotated[AwareDatetime | None, Field(alias='scheduledAt')] = None - """ - Time when the run was scheduled. - """ - - -@docs_group('Models') -class RunOptions(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - build: Annotated[str, Field(examples=['latest'])] - timeout_secs: Annotated[int, Field(alias='timeoutSecs', examples=[300], ge=0)] - memory_mbytes: Annotated[int, Field(alias='memoryMbytes', examples=[1024], ge=128, le=32768)] - disk_mbytes: Annotated[int, Field(alias='diskMbytes', examples=[2048], ge=0)] - max_items: Annotated[int | None, Field(alias='maxItems', examples=[1000], ge=1)] = None - max_total_charge_usd: Annotated[float | None, Field(alias='maxTotalChargeUsd', examples=[5], ge=0.0)] = None - - -@docs_group('Models') -class RunOrigin(StrEnum): - DEVELOPMENT = 'DEVELOPMENT' - WEB = 'WEB' - API = 'API' - SCHEDULER = 'SCHEDULER' - TEST = 'TEST' - WEBHOOK = 'WEBHOOK' - ACTOR = 'ACTOR' - CLI = 'CLI' - STANDBY = 'STANDBY' - - -@docs_group('Models') -class RunResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Run - - -@docs_group('Models') -class RunShort(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] - act_id: Annotated[str, Field(alias='actId', examples=['HDSasDasz78YcAPEB'])] - actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['KJHSKHausidyaJKHs'])] = None - status: ActorJobStatus - started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( - None - ) - build_id: Annotated[str, Field(alias='buildId', examples=['HG7ML7M8z78YcAPEB'])] - build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.2'])] = None - meta: RunMeta - usage_total_usd: Annotated[float, Field(alias='usageTotalUsd', examples=[0.2])] - default_key_value_store_id: Annotated[str, Field(alias='defaultKeyValueStoreId', examples=['sfAjeR4QmeJCQzTfe'])] - default_dataset_id: Annotated[str, Field(alias='defaultDatasetId', examples=['3ZojQDdFTsyE7Moy4'])] - default_request_queue_id: Annotated[str, Field(alias='defaultRequestQueueId', examples=['so93g2shcDzK3pA85'])] - - -@docs_group('Models') -class RunStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - input_body_len: Annotated[int | None, Field(alias='inputBodyLen', examples=[240], ge=0)] = None - migration_count: Annotated[int | None, Field(alias='migrationCount', examples=[0], ge=0)] = None - reboot_count: Annotated[int | None, Field(alias='rebootCount', examples=[0], ge=0)] = None - restart_count: Annotated[int, Field(alias='restartCount', examples=[0], ge=0)] - resurrect_count: Annotated[int, Field(alias='resurrectCount', examples=[2], ge=0)] - mem_avg_bytes: Annotated[float | None, Field(alias='memAvgBytes', examples=[267874071.9])] = None - mem_max_bytes: Annotated[int | None, Field(alias='memMaxBytes', examples=[404713472], ge=0)] = None - mem_current_bytes: Annotated[int | None, Field(alias='memCurrentBytes', examples=[0], ge=0)] = None - cpu_avg_usage: Annotated[float | None, Field(alias='cpuAvgUsage', examples=[33.7532101107538])] = None - cpu_max_usage: Annotated[float | None, Field(alias='cpuMaxUsage', examples=[169.650735534941])] = None - cpu_current_usage: Annotated[float | None, Field(alias='cpuCurrentUsage', examples=[0])] = None - net_rx_bytes: Annotated[int | None, Field(alias='netRxBytes', examples=[103508042], ge=0)] = None - net_tx_bytes: Annotated[int | None, Field(alias='netTxBytes', examples=[4854600], ge=0)] = None - duration_millis: Annotated[int | None, Field(alias='durationMillis', examples=[248472], ge=0)] = None - run_time_secs: Annotated[float | None, Field(alias='runTimeSecs', examples=[248.472], ge=0.0)] = None - metamorph: Annotated[int | None, Field(examples=[0], ge=0)] = None - compute_units: Annotated[float, Field(alias='computeUnits', examples=[0.13804], ge=0.0)] - - -@docs_group('Models') -class RunTimeoutExceededErrorDetail(ErrorDetail): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Annotated[Literal['run-timeout-exceeded'], Field(title='ErrorType')] = 'run-timeout-exceeded' - """ - Machine-processable error type identifier. - """ - - -@docs_group('Models') -class RunUsage(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[3])] = None - dataset_reads: Annotated[int | None, Field(alias='DATASET_READS', examples=[4])] = None - dataset_writes: Annotated[int | None, Field(alias='DATASET_WRITES', examples=[4])] = None - key_value_store_reads: Annotated[int | None, Field(alias='KEY_VALUE_STORE_READS', examples=[5])] = None - key_value_store_writes: Annotated[int | None, Field(alias='KEY_VALUE_STORE_WRITES', examples=[3])] = None - key_value_store_lists: Annotated[int | None, Field(alias='KEY_VALUE_STORE_LISTS', examples=[5])] = None - request_queue_reads: Annotated[int | None, Field(alias='REQUEST_QUEUE_READS', examples=[2])] = None - request_queue_writes: Annotated[int | None, Field(alias='REQUEST_QUEUE_WRITES', examples=[1])] = None - data_transfer_internal_gbytes: Annotated[ - float | None, Field(alias='DATA_TRANSFER_INTERNAL_GBYTES', examples=[1]) - ] = None - data_transfer_external_gbytes: Annotated[ - float | None, Field(alias='DATA_TRANSFER_EXTERNAL_GBYTES', examples=[3]) - ] = None - proxy_residential_transfer_gbytes: Annotated[ - float | None, Field(alias='PROXY_RESIDENTIAL_TRANSFER_GBYTES', examples=[34]) - ] = None - proxy_serps: Annotated[int | None, Field(alias='PROXY_SERPS', examples=[3])] = None - - -@docs_group('Models') -class RunUsageUsd(BaseModel): - """Resource usage costs in USD. All values are monetary amounts in US dollars.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[0.0003])] = None - dataset_reads: Annotated[float | None, Field(alias='DATASET_READS', examples=[0.0001])] = None - dataset_writes: Annotated[float | None, Field(alias='DATASET_WRITES', examples=[0.0001])] = None - key_value_store_reads: Annotated[float | None, Field(alias='KEY_VALUE_STORE_READS', examples=[0.0001])] = None - key_value_store_writes: Annotated[float | None, Field(alias='KEY_VALUE_STORE_WRITES', examples=[5e-05])] = None - key_value_store_lists: Annotated[float | None, Field(alias='KEY_VALUE_STORE_LISTS', examples=[0.0001])] = None - request_queue_reads: Annotated[float | None, Field(alias='REQUEST_QUEUE_READS', examples=[0.0001])] = None - request_queue_writes: Annotated[float | None, Field(alias='REQUEST_QUEUE_WRITES', examples=[0.0001])] = None - data_transfer_internal_gbytes: Annotated[ - float | None, Field(alias='DATA_TRANSFER_INTERNAL_GBYTES', examples=[0.001]) - ] = None - data_transfer_external_gbytes: Annotated[ - float | None, Field(alias='DATA_TRANSFER_EXTERNAL_GBYTES', examples=[0.003]) - ] = None - proxy_residential_transfer_gbytes: Annotated[ - float | None, Field(alias='PROXY_RESIDENTIAL_TRANSFER_GBYTES', examples=[0.034]) - ] = None - proxy_serps: Annotated[float | None, Field(alias='PROXY_SERPS', examples=[0.003])] = None - - -@docs_group('Models') -class ScheduleActionRunActor(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['c6KfSgoQzFhMk3etc'])] - type: Literal['RUN_ACTOR'] - actor_id: Annotated[str, Field(alias='actorId', examples=['jF8GGEvbEg4Au3NLA'])] - run_input: Annotated[ScheduleActionRunInput | None, Field(alias='runInput')] = None - run_options: Annotated[TaskOptions | None, Field(alias='runOptions')] = None - - -@docs_group('Models') -class ScheduleActionRunActorTask(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['c6KfSgoQzFhMk3etc'])] - type: Literal['RUN_ACTOR_TASK'] - actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['jF8GGEvbEg4Au3NLA'])] - input: dict[str, Any] | None = None - - -@docs_group('Models') -class ScheduleActionRunInput(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - body: Annotated[str | None, Field(examples=['{\\n "foo": "actor"\\n}'])] = None - content_type: Annotated[str | None, Field(alias='contentType', examples=['application/json; charset=utf-8'])] = None - - -@docs_group('Models') -class ScheduleActionShortRunActor(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['ZReCs7hkdieq8ZUki'])] - type: Literal['RUN_ACTOR'] - actor_id: Annotated[str, Field(alias='actorId', examples=['HKhKmiCMrDgu9eXeE'])] - - -@docs_group('Models') -class ScheduleActionShortRunActorTask(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['ZReCs7hkdieq8ZUki'])] - type: Literal['RUN_ACTOR_TASK'] - actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['HKhKmiCMrDgu9eXeE'])] - - -@docs_group('Models') -class ScheduleBase(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['asdLZtadYvn4mBZmm'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - name: Annotated[str, Field(examples=['my-schedule'])] - cron_expression: Annotated[str, Field(alias='cronExpression', examples=['* * * * *'])] - timezone: Annotated[str, Field(examples=['UTC'])] - is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] - is_exclusive: Annotated[bool, Field(alias='isExclusive', examples=[True])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-20T06:33:11.202Z'])] - next_run_at: Annotated[AwareDatetime | None, Field(alias='nextRunAt', examples=['2019-04-12T07:34:10.202Z'])] = None - last_run_at: Annotated[AwareDatetime | None, Field(alias='lastRunAt', examples=['2019-04-12T07:33:10.202Z'])] = None - - -@docs_group('Models') -class Schedule(ScheduleBase): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - description: Annotated[str | None, Field(examples=['Schedule of actor ...'])] = None - title: str | None = None - actions: list[Annotated[ScheduleActionRunActor | ScheduleActionRunActorTask, Field(discriminator='type')]] - - -@docs_group('Models') -class ScheduleCreate(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str | None, Field(examples=['my-schedule'])] = None - is_enabled: Annotated[bool | None, Field(alias='isEnabled', examples=[True])] = None - is_exclusive: Annotated[bool | None, Field(alias='isExclusive', examples=[True])] = None - cron_expression: Annotated[str | None, Field(alias='cronExpression', examples=['* * * * *'])] = None - timezone: Annotated[str | None, Field(examples=['UTC'])] = None - description: Annotated[str | None, Field(examples=['Schedule of actor ...'])] = None - title: str | None = None - actions: ( - list[Annotated[ScheduleCreateActionRunActor | ScheduleCreateActionRunActorTask, Field(discriminator='type')]] - | None - ) = None - - -@docs_group('Models') -class ScheduleCreateActionRunActor(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Literal['RUN_ACTOR'] - actor_id: Annotated[str, Field(alias='actorId', examples=['jF8GGEvbEg4Au3NLA'])] - run_input: Annotated[ScheduleActionRunInput | None, Field(alias='runInput')] = None - run_options: Annotated[TaskOptions | None, Field(alias='runOptions')] = None - - -@docs_group('Models') -class ScheduleCreateActionRunActorTask(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Literal['RUN_ACTOR_TASK'] - actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['jF8GGEvbEg4Au3NLA'])] - input: dict[str, Any] | None = None - - -@docs_group('Models') -class ScheduleInvoked(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - message: Annotated[str, Field(examples=['Schedule invoked'])] - level: Annotated[str, Field(examples=['INFO'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-03-26T12:28:00.370Z'])] - - -@docs_group('Models') -class ScheduleLogResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: list[ScheduleInvoked] - - -@docs_group('Models') -class ScheduleResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Schedule - - -@docs_group('Models') -class ScheduleShort(ScheduleBase): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actions: list[Annotated[ScheduleActionShortRunActor | ScheduleActionShortRunActorTask, Field(discriminator='type')]] - - -@docs_group('Models') -class SchemaValidationErrorData(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - invalid_items: Annotated[list[InvalidItem], Field(alias='invalidItems')] - """ - A list of invalid items in the received array of items. - """ - - -@docs_group('Models') -class SourceCodeFile(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - format: SourceCodeFileFormat | None = None - content: Annotated[str | None, Field(examples=["console.log('This is the main.js file');"])] = None - name: Annotated[str, Field(examples=['src/main.js'])] - - -@docs_group('Models') -class SourceCodeFileFormat(StrEnum): - BASE64 = 'BASE64' - TEXT = 'TEXT' - - -@docs_group('Models') -class SourceCodeFolder(BaseModel): - """Represents a folder in the Actor's source code structure. Distinguished from - SourceCodeFile by the presence of the `folder` property set to `true`. - - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str, Field(examples=['src/utils'])] - """ - The folder path relative to the Actor's root directory. - """ - folder: Annotated[bool, Field(examples=[True])] - """ - Always `true` for folders. Used to distinguish folders from files. - """ - - -@docs_group('Models') -class StorageIds(BaseModel): - """A map of aliased storage IDs associated with this run, grouped by storage type.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - datasets: Datasets | None = None - """ - Aliased dataset IDs for this run. - """ - key_value_stores: Annotated[KeyValueStores | None, Field(alias='keyValueStores')] = None - """ - Aliased key-value store IDs for this run. - """ - request_queues: Annotated[RequestQueues | None, Field(alias='requestQueues')] = None - """ - Aliased request queue IDs for this run. - """ - - -@docs_group('Models') -class StorageOwnership(StrEnum): - OWNED_BY_ME = 'ownedByMe' - SHARED_WITH_ME = 'sharedWithMe' - - -@docs_group('Models') -class Storages(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - dataset: dict[str, Any] | None = None - """ - Defines the schema of items in your dataset, the full specification can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema) - """ - - -@docs_group('Models') -class StoreListActor(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] - title: Annotated[str, Field(examples=['My Public Actor'])] - name: Annotated[str, Field(examples=['my-public-actor'])] - username: Annotated[str, Field(examples=['jane35'])] - user_full_name: Annotated[str, Field(alias='userFullName', examples=['Jane H. Doe'])] - description: Annotated[str, Field(examples=['My public actor!'])] - categories: Annotated[list[str] | None, Field(examples=[['MARKETING', 'LEAD_GENERATION']])] = None - notice: str | None = None - picture_url: Annotated[AnyUrl | None, Field(alias='pictureUrl', examples=['https://...'])] = None - user_picture_url: Annotated[AnyUrl | None, Field(alias='userPictureUrl', examples=['https://...'])] = None - url: Annotated[AnyUrl | None, Field(examples=['https://...'])] = None - stats: ActorStats - current_pricing_info: Annotated[CurrentPricingInfo, Field(alias='currentPricingInfo')] - is_white_listed_for_agentic_payment: Annotated[bool | None, Field(alias='isWhiteListedForAgenticPayment')] = None - """ - Whether the Actor is whitelisted for agentic payment processing. - """ - readme_summary: Annotated[str | None, Field(alias='readmeSummary')] = None - """ - A brief, LLM-generated readme summary - """ - - -@docs_group('Models') -class TaggedBuildInfo(BaseModel): - """Information about a tagged build.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - build_id: Annotated[str | None, Field(alias='buildId', examples=['z2EryhbfhgSyqj6Hn'])] = None - """ - The ID of the build associated with this tag. - """ - build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.2'])] = None - """ - The build number/version string. - """ - finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-06-10T11:15:49.286Z'])] = ( - None - ) - """ - The timestamp when the build finished. - """ - - -@docs_group('Models') -class Task(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] - name: Annotated[str, Field(examples=['my-task'])] - username: Annotated[str | None, Field(examples=['janedoe'])] = None - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2018-10-26T07:23:14.855Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2018-10-26T13:30:49.578Z'])] - removed_at: Annotated[AwareDatetime | None, Field(alias='removedAt')] = None - stats: TaskStats | None = None - options: TaskOptions | None = None - input: TaskInput | None = None - title: str | None = None - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - standby_url: Annotated[AnyUrl | None, Field(alias='standbyUrl')] = None - - -@docs_group('Models') -class TaskInput(BaseModel): - """The input configuration for the Actor task. This is a user-defined JSON object - that will be passed to the Actor when the task is run. - - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - -@docs_group('Models') -class TaskOptions(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - build: Annotated[str | None, Field(examples=['latest'])] = None - timeout_secs: Annotated[int | None, Field(alias='timeoutSecs', examples=[300])] = None - memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[1024])] = None - max_items: Annotated[int | None, Field(alias='maxItems', examples=[1000])] = None - max_total_charge_usd: Annotated[float | None, Field(alias='maxTotalChargeUsd', examples=[5])] = None - restart_on_error: Annotated[bool | None, Field(alias='restartOnError', examples=[False])] = None - - -@docs_group('Models') -class TaskResponse(BaseModel): - """Response containing Actor task data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Task - - -@docs_group('Models') -class TaskShort(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] - act_name: Annotated[str | None, Field(alias='actName', examples=['my-actor'])] = None - name: Annotated[str, Field(examples=['my-task'])] - username: Annotated[str | None, Field(examples=['janedoe'])] = None - act_username: Annotated[str | None, Field(alias='actUsername', examples=['janedoe'])] = None - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2018-10-26T07:23:14.855Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2018-10-26T13:30:49.578Z'])] - stats: TaskStats | None = None - - -@docs_group('Models') -class TaskStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total_runs: Annotated[int | None, Field(alias='totalRuns', examples=[15])] = None - - -@docs_group('Models') -class TestWebhookResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: WebhookDispatch - - -@docs_group('Models') -class UnknownBuildTagError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - error: UnknownBuildTagErrorDetail | None = None - - -@docs_group('Models') -class UnknownBuildTagErrorDetail(ErrorDetail): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - type: Annotated[Literal['unknown-build-tag'], Field(title='ErrorType')] = 'unknown-build-tag' - """ - Machine-processable error type identifier. - """ - - -@docs_group('Models') -class UnlockRequestsResponse(BaseModel): - """Response containing the result of unlocking requests.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: UnlockRequestsResult - - -@docs_group('Models') -class UnlockRequestsResult(BaseModel): - """Result of unlocking requests in the request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - unlocked_count: Annotated[int, Field(alias='unlockedCount', examples=[10])] - """ - Number of requests that were successfully unlocked. - """ - - -@docs_group('Models') -class UpdateActorRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str | None, Field(examples=['MyActor'])] = None - description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None - is_public: Annotated[bool | None, Field(alias='isPublic', examples=[False])] = None - actor_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='actorPermissionLevel')] = None - seo_title: Annotated[str | None, Field(alias='seoTitle', examples=['My actor'])] = None - seo_description: Annotated[str | None, Field(alias='seoDescription', examples=['My actor is the best'])] = None - title: Annotated[str | None, Field(examples=['My Actor'])] = None - restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None - versions: list[CreateOrUpdateVersionRequest] | None = None - pricing_infos: Annotated[ - list[ - Annotated[ - PayPerEventActorPricingInfo - | PricePerDatasetItemActorPricingInfo - | FlatPricePerMonthActorPricingInfo - | FreeActorPricingInfo, - Field(discriminator='pricing_model'), - ] - ] - | None, - Field(alias='pricingInfos'), - ] = None - categories: list[str] | None = None - default_run_options: Annotated[DefaultRunOptions | None, Field(alias='defaultRunOptions')] = None - tagged_builds: Annotated[ - dict[str, Any] | None, - Field(alias='taggedBuilds', examples=[{'latest': {'buildId': 'z2EryhbfhgSyqj6Hn'}, 'beta': None}]), - ] = None - """ - An object to modify tags on the Actor's builds. The key is the tag name (e.g., _latest_), and the value is either an object with a `buildId` or `null`. - - This operation is a patch; any existing tags that you omit from this object will be preserved. - - - **To create or reassign a tag**, provide the tag name with a `buildId`. e.g., to assign the _latest_ tag: - -   - - ```json - { - "latest": { - "buildId": "z2EryhbfhgSyqj6Hn" - } - } - ``` - - - **To remove a tag**, provide the tag name with a `null` value. e.g., to remove the _beta_ tag: - -   - - ```json - { - "beta": null - } - ``` - - - **To perform multiple operations**, combine them. The following reassigns _latest_ and removes _beta_, while preserving any other existing tags. - -   - - ```json - { - "latest": { - "buildId": "z2EryhbfhgSyqj6Hn" - }, - "beta": null - } - ``` - - """ - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None - is_deprecated: Annotated[bool | None, Field(alias='isDeprecated')] = None - - -@docs_group('Models') -class UpdateDatasetRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: str | None = None - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - - -@docs_group('Models') -class UpdateLimitsRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - max_monthly_usage_usd: Annotated[float | None, Field(alias='maxMonthlyUsageUsd', examples=[300])] = None - """ - If your platform usage in the billing period exceeds the prepaid usage, you will be charged extra. Setting this property you can update your hard limit on monthly platform usage to prevent accidental overage or to limit the extra charges. - - """ - data_retention_days: Annotated[int | None, Field(alias='dataRetentionDays', examples=[90])] = None - """ - Apify securely stores your ten most recent Actor runs indefinitely, ensuring they are always accessible. Unnamed storages and other Actor runs are automatically deleted after the retention period. If you're subscribed, you can change it to keep data for longer or to limit your usage. [Lear more](https://docs.apify.com/platform/storage/usage#data-retention). - - """ - - -@docs_group('Models') -class UpdateRequestQueueRequest(BaseModel): - """Request object for updating a request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: str | None = None - """ - The new name for the request queue. - """ - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - - -@docs_group('Models') -class UpdateRequestResponse(BaseModel): - """Response containing the result of updating a request in the request queue.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: RequestRegistration - - -@docs_group('Models') -class UpdateRunRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - run_id: Annotated[str | None, Field(alias='runId', examples=['3KH8gEpp4d8uQSe8T'])] = None - status_message: Annotated[str | None, Field(alias='statusMessage', examples=['Actor has finished'])] = None - is_status_message_terminal: Annotated[bool | None, Field(alias='isStatusMessageTerminal', examples=[True])] = None - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - - -@docs_group('Models') -class UpdateStoreRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: str | None = None - general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None - - -@docs_group('Models') -class UpdateTaskRequest(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - name: Annotated[str | None, Field(examples=['my-task'])] = None - options: TaskOptions | None = None - input: TaskInput | None = None - title: str | None = None - actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None - - -@docs_group('Models') -class UsageCycle(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - start_at: Annotated[AwareDatetime, Field(alias='startAt', examples=['2022-10-02T00:00:00.000Z'])] - end_at: Annotated[AwareDatetime, Field(alias='endAt', examples=['2022-11-01T23:59:59.999Z'])] - - -@docs_group('Models') -class UsageItem(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - quantity: Annotated[float, Field(examples=[2.784475])] - base_amount_usd: Annotated[float, Field(alias='baseAmountUsd', examples=[0.69611875])] - base_unit_price_usd: Annotated[float | None, Field(alias='baseUnitPriceUsd', examples=[0.25])] = None - amount_after_volume_discount_usd: Annotated[ - float | None, Field(alias='amountAfterVolumeDiscountUsd', examples=[0.69611875]) - ] = None - price_tiers: Annotated[list[PriceTiers] | None, Field(alias='priceTiers')] = None - - -@docs_group('Models') -class UserPrivateInfo(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] - username: Annotated[str, Field(examples=['myusername'])] - profile: Profile - email: Annotated[EmailStr, Field(examples=['bob@example.com'])] - proxy: Proxy - plan: Plan - effective_platform_features: Annotated[EffectivePlatformFeatures, Field(alias='effectivePlatformFeatures')] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2022-11-29T14:48:29.381Z'])] - is_paying: Annotated[bool, Field(alias='isPaying', examples=[True])] - - -@docs_group('Models') -class UserPublicInfo(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - username: Annotated[str, Field(examples=['d7b9MDYsbtX5L7XAj'])] - profile: Profile | None = None - - -@docs_group('Models') -class ValidationError(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - instance_path: Annotated[str | None, Field(alias='instancePath')] = None - """ - The path to the instance being validated. - """ - schema_path: Annotated[str | None, Field(alias='schemaPath')] = None - """ - The path to the schema that failed the validation. - """ - keyword: str | None = None - """ - The validation keyword that caused the error. - """ - message: str | None = None - """ - A message describing the validation error. - """ - params: dict[str, Any] | None = None - """ - Additional parameters specific to the validation error. - """ - - -@docs_group('Models') -class Version(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - version_number: Annotated[str, Field(alias='versionNumber', examples=['0.0'])] - source_type: Annotated[VersionSourceType | None, Field(alias='sourceType')] - env_vars: Annotated[list[EnvVar] | None, Field(alias='envVars')] = None - apply_env_vars_to_build: Annotated[bool | None, Field(alias='applyEnvVarsToBuild', examples=[False])] = None - build_tag: Annotated[str | None, Field(alias='buildTag', examples=['latest'])] = None - source_files: Annotated[ - list[SourceCodeFile | SourceCodeFolder] | None, Field(alias='sourceFiles', title='VersionSourceFiles') - ] = None - git_repo_url: Annotated[str | None, Field(alias='gitRepoUrl')] = None - """ - URL of the Git repository when sourceType is GIT_REPO. - """ - tarball_url: Annotated[str | None, Field(alias='tarballUrl')] = None - """ - URL of the tarball when sourceType is TARBALL. - """ - github_gist_url: Annotated[str | None, Field(alias='gitHubGistUrl')] = None - """ - URL of the GitHub Gist when sourceType is GITHUB_GIST. - """ - - -@docs_group('Models') -class VersionResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Version - - -@docs_group('Models') -class VersionSourceType(StrEnum): - SOURCE_FILES = 'SOURCE_FILES' - GIT_REPO = 'GIT_REPO' - TARBALL = 'TARBALL' - GITHUB_GIST = 'GITHUB_GIST' - - -@docs_group('Models') -class Webhook(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None - should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None - event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] - condition: WebhookCondition - ignore_ssl_errors: Annotated[bool, Field(alias='ignoreSslErrors', examples=[False])] - do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None - request_url: Annotated[AnyUrl, Field(alias='requestUrl', examples=['http://example.com/'])] - payload_template: Annotated[ - str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) - ] = None - headers_template: Annotated[ - str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) - ] = None - description: Annotated[str | None, Field(examples=['this is webhook description'])] = None - last_dispatch: Annotated[ExampleWebhookDispatch | None, Field(alias='lastDispatch')] = None - stats: WebhookStats | None = None - - -@docs_group('Models') -class WebhookCondition(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - actor_id: Annotated[str | None, Field(alias='actorId', examples=['hksJZtadYvn4mBuin'])] = None - actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['asdLZtadYvn4mBZmm'])] = None - actor_run_id: Annotated[str | None, Field(alias='actorRunId', examples=['hgdKZtadYvn4mBpoi'])] = None - - -@docs_group('Models') -class WebhookCreate(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None - event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] - condition: WebhookCondition - idempotency_key: Annotated[str | None, Field(alias='idempotencyKey', examples=['fdSJmdP3nfs7sfk3y'])] = None - ignore_ssl_errors: Annotated[bool | None, Field(alias='ignoreSslErrors', examples=[False])] = None - do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None - request_url: Annotated[str, Field(alias='requestUrl', examples=['http://example.com/'])] - payload_template: Annotated[ - str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) - ] = None - headers_template: Annotated[ - str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) - ] = None - description: Annotated[str | None, Field(examples=['this is webhook description'])] = None - should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None - - -@docs_group('Models') -class WebhookDispatch(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['asdLZtadYvn4mBZmm'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - webhook_id: Annotated[str, Field(alias='webhookId', examples=['asdLZtadYvn4mBZmm'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - status: WebhookDispatchStatus - event_type: Annotated[WebhookEventType, Field(alias='eventType')] - event_data: Annotated[EventData | None, Field(alias='eventData', title='eventData')] = None - calls: Annotated[list[Call] | None, Field(title='calls')] = None - - -@docs_group('Models') -class WebhookDispatchList(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: ListOfWebhookDispatches | None = None - - -@docs_group('Models') -class WebhookDispatchResponse(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: WebhookDispatch - - -@docs_group('Models') -class WebhookDispatchStatus(StrEnum): - """Status of the webhook dispatch indicating whether the HTTP request was successful.""" - - ACTIVE = 'ACTIVE' - SUCCEEDED = 'SUCCEEDED' - FAILED = 'FAILED' - - -@docs_group('Models') -class WebhookEventType(StrEnum): - """Type of event that triggers the webhook.""" - - ACTOR_BUILD_ABORTED = 'ACTOR.BUILD.ABORTED' - ACTOR_BUILD_CREATED = 'ACTOR.BUILD.CREATED' - ACTOR_BUILD_FAILED = 'ACTOR.BUILD.FAILED' - ACTOR_BUILD_SUCCEEDED = 'ACTOR.BUILD.SUCCEEDED' - ACTOR_BUILD_TIMED_OUT = 'ACTOR.BUILD.TIMED_OUT' - ACTOR_RUN_ABORTED = 'ACTOR.RUN.ABORTED' - ACTOR_RUN_CREATED = 'ACTOR.RUN.CREATED' - ACTOR_RUN_FAILED = 'ACTOR.RUN.FAILED' - ACTOR_RUN_RESURRECTED = 'ACTOR.RUN.RESURRECTED' - ACTOR_RUN_SUCCEEDED = 'ACTOR.RUN.SUCCEEDED' - ACTOR_RUN_TIMED_OUT = 'ACTOR.RUN.TIMED_OUT' - TEST = 'TEST' - - -@docs_group('Models') -class WebhookResponse(BaseModel): - """Response containing webhook data.""" - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - data: Webhook - - -@docs_group('Models') -class WebhookShort(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] - created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] - modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] - user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] - is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None - should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None - event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] - condition: WebhookCondition - ignore_ssl_errors: Annotated[bool, Field(alias='ignoreSslErrors', examples=[False])] - do_not_retry: Annotated[bool, Field(alias='doNotRetry', examples=[False])] - request_url: Annotated[AnyUrl, Field(alias='requestUrl', examples=['http://example.com/'])] - last_dispatch: Annotated[ExampleWebhookDispatch | None, Field(alias='lastDispatch')] = None - stats: WebhookStats | None = None - - -@docs_group('Models') -class WebhookStats(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - total_dispatches: Annotated[int, Field(alias='totalDispatches', examples=[1])] - - -@docs_group('Models') -class WebhookUpdate(BaseModel): - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None - event_types: Annotated[ - list[WebhookEventType] | None, Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']]) - ] = None - condition: WebhookCondition | None = None - ignore_ssl_errors: Annotated[bool | None, Field(alias='ignoreSslErrors', examples=[False])] = None - do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None - request_url: Annotated[AnyUrl | None, Field(alias='requestUrl', examples=['http://example.com/'])] = None - payload_template: Annotated[ - str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) - ] = None - headers_template: Annotated[ - str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) - ] = None - description: Annotated[str | None, Field(examples=['this is webhook description'])] = None - should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None + @model_validator(mode='after') + def _check_at_least_one_identifier(self) -> RequestDeleteInput: + """Ensure at least one of `id` or `unique_key` is set.""" + if self.id is None and self.unique_key is None: + raise ValueError('At least one of `id` or `unique_key` must be provided') + return self diff --git a/src/apify_client/_models_generated.py b/src/apify_client/_models_generated.py new file mode 100644 index 00000000..284d6780 --- /dev/null +++ b/src/apify_client/_models_generated.py @@ -0,0 +1,4016 @@ +# generated by datamodel-codegen + +from __future__ import annotations + +from enum import StrEnum +from typing import Annotated, Any, Literal + +from pydantic import AnyUrl, AwareDatetime, BaseModel, ConfigDict, EmailStr, Field, RootModel + +from apify_client._docs import docs_group + + +@docs_group('Models') +class AccountLimits(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + monthly_usage_cycle: Annotated[UsageCycle, Field(alias='monthlyUsageCycle')] + limits: Limits + current: Current + + +@docs_group('Models') +class Actor(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + name: Annotated[str, Field(examples=['MyActor'])] + username: Annotated[str, Field(examples=['jane35'])] + description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None + restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None + is_public: Annotated[bool, Field(alias='isPublic', examples=[False])] + actor_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='actorPermissionLevel')] = None + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-07-08T11:27:57.401Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-07-08T14:01:05.546Z'])] + stats: ActorStats + versions: list[Version] + pricing_infos: Annotated[ + list[ + Annotated[ + PayPerEventActorPricingInfo + | PricePerDatasetItemActorPricingInfo + | FlatPricePerMonthActorPricingInfo + | FreeActorPricingInfo, + Field(discriminator='pricing_model'), + ] + ] + | None, + Field(alias='pricingInfos'), + ] = None + default_run_options: Annotated[DefaultRunOptions, Field(alias='defaultRunOptions')] + example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None + is_deprecated: Annotated[bool | None, Field(alias='isDeprecated', examples=[False])] = None + deployment_key: Annotated[str | None, Field(alias='deploymentKey', examples=['ssh-rsa AAAA ...'])] = None + title: Annotated[str | None, Field(examples=['My Actor'])] = None + tagged_builds: Annotated[dict[str, TaggedBuildInfo | None] | None, Field(alias='taggedBuilds')] = None + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + readme_summary: Annotated[str | None, Field(alias='readmeSummary')] = None + """ + A brief, LLM-generated readme summary + """ + + +@docs_group('Models') +class ActorChargeEvent(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + event_price_usd: Annotated[float, Field(alias='eventPriceUsd')] + event_title: Annotated[str, Field(alias='eventTitle')] + event_description: Annotated[str, Field(alias='eventDescription')] + + +@docs_group('Models') +class ActorDefinition(BaseModel): + """The definition of the Actor, the full specification of this field can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/actor-json).""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_specification: Annotated[Literal[1], Field(alias='actorSpecification')] = 1 + """ + The Actor specification version that this Actor follows. This property must be set to 1. + """ + name: str | None = None + """ + The name of the Actor. + """ + version: Annotated[str | None, Field(pattern='^[0-9]+\\.[0-9]+$')] = None + """ + The version of the Actor, specified in the format [Number].[Number], e.g., 0.1, 1.0. + """ + build_tag: Annotated[str | None, Field(alias='buildTag')] = None + """ + The tag name to be applied to a successful build of the Actor. Defaults to 'latest' if not specified. + """ + environment_variables: Annotated[dict[str, str] | None, Field(alias='environmentVariables')] = None + """ + A map of environment variables to be used during local development and deployment. + """ + dockerfile: str | None = None + """ + The path to the Dockerfile used for building the Actor on the platform. + """ + docker_context_dir: Annotated[str | None, Field(alias='dockerContextDir')] = None + """ + The path to the directory used as the Docker context when building the Actor. + """ + readme: str | None = None + """ + The path to the README file for the Actor. + """ + input: dict[str, Any] | None = None + """ + The input schema object, the full specification can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/input-schema) + """ + changelog: str | None = None + """ + The path to the CHANGELOG file displayed in the Actor's information tab. + """ + storages: Storages | None = None + default_memory_mbytes: Annotated[str | int | None, Field(alias='defaultMemoryMbytes')] = None + """ + Specifies the default amount of memory in megabytes to be used when the Actor is started. Can be an integer or a [dynamic memory expression](/platform/actors/development/actor-definition/dynamic-actor-memory). + """ + min_memory_mbytes: Annotated[int | None, Field(alias='minMemoryMbytes', ge=256)] = None + """ + Specifies the minimum amount of memory in megabytes required by the Actor. + """ + max_memory_mbytes: Annotated[int | None, Field(alias='maxMemoryMbytes', ge=256)] = None + """ + Specifies the maximum amount of memory in megabytes required by the Actor. + """ + uses_standby_mode: Annotated[bool | None, Field(alias='usesStandbyMode')] = None + """ + Specifies whether Standby mode is enabled for the Actor. + """ + + +@docs_group('Models') +class ActorJobStatus(StrEnum): + """Status of an Actor job (run or build).""" + + READY = 'READY' + RUNNING = 'RUNNING' + SUCCEEDED = 'SUCCEEDED' + FAILED = 'FAILED' + TIMING_OUT = 'TIMING-OUT' + TIMED_OUT = 'TIMED-OUT' + ABORTING = 'ABORTING' + ABORTED = 'ABORTED' + + +@docs_group('Models') +class ActorPermissionLevel(StrEnum): + """Determines permissions that the Actor requires to run. For more information, see the [Actor permissions documentation](https://docs.apify.com/platform/actors/development/permissions).""" + + LIMITED_PERMISSIONS = 'LIMITED_PERMISSIONS' + FULL_PERMISSIONS = 'FULL_PERMISSIONS' + + +@docs_group('Models') +class ActorResponse(BaseModel): + """Response containing Actor data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Actor + + +@docs_group('Models') +class ActorRunFailedError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + error: RunFailedErrorDetail | None = None + + +@docs_group('Models') +class ActorRunTimeoutExceededError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + error: RunTimeoutExceededErrorDetail | None = None + + +@docs_group('Models') +class ActorShort(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['br9CKmk457'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-10-29T07:34:24.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-10-30T07:34:24.202Z'])] + name: Annotated[str, Field(examples=['MyAct'])] + username: Annotated[str, Field(examples=['janedoe'])] + title: Annotated[str | None, Field(examples=['Hello World Example'])] = None + stats: ActorStats | None = None + + +@docs_group('Models') +class ActorStandby(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + is_enabled: Annotated[bool | None, Field(alias='isEnabled')] = None + desired_requests_per_actor_run: Annotated[int | None, Field(alias='desiredRequestsPerActorRun')] = None + max_requests_per_actor_run: Annotated[int | None, Field(alias='maxRequestsPerActorRun')] = None + idle_timeout_secs: Annotated[int | None, Field(alias='idleTimeoutSecs')] = None + build: str | None = None + memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes')] = None + disable_standby_fields_override: Annotated[bool | None, Field(alias='disableStandbyFieldsOverride')] = None + should_pass_actor_input: Annotated[bool | None, Field(alias='shouldPassActorInput')] = None + + +@docs_group('Models') +class ActorStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total_builds: Annotated[int | None, Field(alias='totalBuilds', examples=[9])] = None + total_runs: Annotated[int | None, Field(alias='totalRuns', examples=[16])] = None + total_users: Annotated[int | None, Field(alias='totalUsers', examples=[6])] = None + total_users7_days: Annotated[int | None, Field(alias='totalUsers7Days', examples=[2])] = None + total_users30_days: Annotated[int | None, Field(alias='totalUsers30Days', examples=[6])] = None + total_users90_days: Annotated[int | None, Field(alias='totalUsers90Days', examples=[6])] = None + total_metamorphs: Annotated[int | None, Field(alias='totalMetamorphs', examples=[2])] = None + last_run_started_at: Annotated[ + AwareDatetime | None, Field(alias='lastRunStartedAt', examples=['2019-07-08T14:01:05.546Z']) + ] = None + + +@docs_group('Models') +class AddRequestResponse(BaseModel): + """Response containing the result of adding a request to the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: RequestRegistration + + +@docs_group('Models') +class AddedRequest(BaseModel): + """Information about a request that was successfully added to a request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + request_id: Annotated[str, Field(alias='requestId', examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + was_already_present: Annotated[bool, Field(alias='wasAlreadyPresent', examples=[False])] + """ + Indicates whether a request with the same unique key already existed in the request queue. If true, no new request was created. + """ + was_already_handled: Annotated[bool, Field(alias='wasAlreadyHandled', examples=[False])] + """ + Indicates whether a request with the same unique key has already been processed by the request queue. + """ + + +@docs_group('Models') +class BatchAddResponse(BaseModel): + """Response containing the result of a batch add operation.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: BatchAddResult + + +@docs_group('Models') +class BatchAddResult(BaseModel): + """Result of a batch add operation containing successfully processed and failed requests.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + processed_requests: Annotated[list[AddedRequest], Field(alias='processedRequests')] + """ + Requests that were successfully added to the request queue. + """ + unprocessed_requests: Annotated[list[RequestDraft], Field(alias='unprocessedRequests')] + """ + Requests that failed to be added and can be retried. + """ + + +@docs_group('Models') +class BatchDeleteResponse(BaseModel): + """Response containing the result of a batch delete operation.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: BatchDeleteResult + + +@docs_group('Models') +class BatchDeleteResult(BaseModel): + """Result of a batch delete operation containing successfully deleted and failed requests.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + processed_requests: Annotated[ + list[DeletedRequestById | DeletedRequestByUniqueKey], Field(alias='processedRequests') + ] + """ + Requests that were successfully deleted from the request queue. + """ + unprocessed_requests: Annotated[list[RequestDraft], Field(alias='unprocessedRequests')] + """ + Requests that failed to be deleted and can be retried. + """ + + +@docs_group('Models') +class BrowserInfoResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + method: Annotated[str, Field(examples=['GET'])] + """ + HTTP method of the request. + """ + client_ip: Annotated[str | None, Field(alias='clientIp', examples=['1.2.3.4'])] + """ + IP address of the client. + """ + country_code: Annotated[str | None, Field(alias='countryCode', examples=['US'])] + """ + Two-letter country code resolved from the client IP address. + """ + body_length: Annotated[int, Field(alias='bodyLength', examples=[0])] + """ + Length of the request body in bytes. + """ + headers: dict[str, str | list[str]] | None = None + """ + Request headers. Omitted when `skipHeaders=true`. + + """ + raw_headers: Annotated[list[str] | None, Field(alias='rawHeaders')] = None + """ + Raw request headers as a flat list of alternating name/value strings. + Included only when `rawHeaders=true`. + + """ + + +@docs_group('Models') +class Build(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] + act_id: Annotated[str, Field(alias='actId', examples=['janedoe~my-actor'])] + user_id: Annotated[str, Field(alias='userId', examples=['klmdEpoiojmdEMlk3'])] + started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( + None + ) + status: ActorJobStatus + meta: BuildsMeta + stats: BuildStats | None = None + options: BuildOptions | None = None + usage: BuildUsage | None = None + usage_total_usd: Annotated[float | None, Field(alias='usageTotalUsd', examples=[0.02])] = None + """ + Total cost in USD for this build. Requires authentication token to access. + """ + usage_usd: Annotated[BuildUsage | None, Field(alias='usageUsd')] = None + """ + Platform usage costs breakdown in USD for this build. Requires authentication token to access. + """ + input_schema: Annotated[ + str | None, Field(alias='inputSchema', deprecated=True, examples=['{\\n "title": "Schema for ... }']) + ] = None + readme: Annotated[str | None, Field(deprecated=True, examples=['# Magic Actor\\nThis Actor is magic.'])] = None + build_number: Annotated[str, Field(alias='buildNumber', examples=['0.1.1'])] + actor_definition: Annotated[ActorDefinition | None, Field(alias='actorDefinition')] = None + + +@docs_group('Models') +class BuildOptions(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + use_cache: Annotated[bool | None, Field(alias='useCache', examples=[False])] = None + beta_packages: Annotated[bool | None, Field(alias='betaPackages', examples=[False])] = None + memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[1024])] = None + disk_mbytes: Annotated[int | None, Field(alias='diskMbytes', examples=[2048])] = None + + +@docs_group('Models') +class BuildResponse(BaseModel): + """Response containing Actor build data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Build + + +@docs_group('Models') +class BuildShort(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] + act_id: Annotated[str | None, Field(alias='actId', examples=['janedoe~my-actor'])] = None + status: ActorJobStatus + started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( + None + ) + usage_total_usd: Annotated[float, Field(alias='usageTotalUsd', examples=[0.02])] + meta: BuildsMeta | None = None + + +@docs_group('Models') +class BuildStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + duration_millis: Annotated[int | None, Field(alias='durationMillis', examples=[1000])] = None + run_time_secs: Annotated[float | None, Field(alias='runTimeSecs', examples=[45.718])] = None + compute_units: Annotated[float, Field(alias='computeUnits', examples=[0.0126994444444444])] + + +@docs_group('Models') +class BuildTag(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + build_id: Annotated[str, Field(alias='buildId')] + + +@docs_group('Models') +class BuildUsage(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[0.08])] = None + + +@docs_group('Models') +class BuildsMeta(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + origin: RunOrigin + client_ip: Annotated[str | None, Field(alias='clientIp', examples=['172.234.12.34'])] = None + """ + IP address of the client that started the build. + """ + user_agent: Annotated[str | None, Field(alias='userAgent', examples=['Mozilla/5.0 (iPad)'])] = None + """ + User agent of the client that started the build. + """ + + +@docs_group('Models') +class Call(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + started_at: Annotated[AwareDatetime | None, Field(alias='startedAt', examples=['2019-12-12T07:34:14.202Z'])] = None + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T07:34:14.202Z'])] = ( + None + ) + error_message: Annotated[str | None, Field(alias='errorMessage', examples=['Cannot send request'])] = None + response_status: Annotated[int | None, Field(alias='responseStatus', examples=[200])] = None + response_body: Annotated[str | None, Field(alias='responseBody', examples=['{"foo": "bar"}'])] = None + + +@docs_group('Models') +class ChargeRunRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + event_name: Annotated[str, Field(alias='eventName', examples=['ANALYZE_PAGE'])] + count: Annotated[int, Field(examples=[1])] + + +@docs_group('Models') +class CommonActorPricingInfo(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + apify_margin_percentage: Annotated[float, Field(alias='apifyMarginPercentage')] + """ + In [0, 1], fraction of pricePerUnitUsd that goes to Apify + """ + created_at: Annotated[AwareDatetime, Field(alias='createdAt')] + """ + When this pricing info record has been created + """ + started_at: Annotated[AwareDatetime, Field(alias='startedAt')] + """ + Since when is this pricing info record effective for a given Actor + """ + notified_about_future_change_at: Annotated[AwareDatetime | None, Field(alias='notifiedAboutFutureChangeAt')] = None + notified_about_change_at: Annotated[AwareDatetime | None, Field(alias='notifiedAboutChangeAt')] = None + reason_for_change: Annotated[str | None, Field(alias='reasonForChange')] = None + + +@docs_group('Models') +class CreateActorRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str | None, Field(examples=['MyActor'])] = None + description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None + title: Annotated[str | None, Field(examples=['My actor'])] = None + is_public: Annotated[bool | None, Field(alias='isPublic', examples=[False])] = None + seo_title: Annotated[str | None, Field(alias='seoTitle', examples=['My actor'])] = None + seo_description: Annotated[str | None, Field(alias='seoDescription', examples=['My actor is the best'])] = None + restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None + versions: list[Version] | None = None + pricing_infos: Annotated[ + list[ + Annotated[ + PayPerEventActorPricingInfo + | PricePerDatasetItemActorPricingInfo + | FlatPricePerMonthActorPricingInfo + | FreeActorPricingInfo, + Field(discriminator='pricing_model'), + ] + ] + | None, + Field(alias='pricingInfos'), + ] = None + categories: list[str] | None = None + default_run_options: Annotated[DefaultRunOptions | None, Field(alias='defaultRunOptions')] = None + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None + is_deprecated: Annotated[bool | None, Field(alias='isDeprecated')] = None + + +@docs_group('Models') +class CreateOrUpdateVersionRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + version_number: Annotated[str | None, Field(alias='versionNumber', examples=['0.0'])] = None + source_type: Annotated[VersionSourceType | None, Field(alias='sourceType')] = None + env_vars: Annotated[list[EnvVarRequest] | None, Field(alias='envVars')] = None + apply_env_vars_to_build: Annotated[bool | None, Field(alias='applyEnvVarsToBuild', examples=[False])] = None + build_tag: Annotated[str | None, Field(alias='buildTag', examples=['latest'])] = None + source_files: Annotated[ + list[SourceCodeFile | SourceCodeFolder] | None, Field(alias='sourceFiles', title='VersionSourceFiles') + ] = None + git_repo_url: Annotated[str | None, Field(alias='gitRepoUrl')] = None + """ + URL of the Git repository when sourceType is GIT_REPO. + """ + tarball_url: Annotated[str | None, Field(alias='tarballUrl')] = None + """ + URL of the tarball when sourceType is TARBALL. + """ + github_gist_url: Annotated[str | None, Field(alias='gitHubGistUrl')] = None + """ + URL of the GitHub Gist when sourceType is GITHUB_GIST. + """ + + +@docs_group('Models') +class CreateTaskRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] + name: Annotated[str | None, Field(examples=['my-task'])] = None + options: TaskOptions | None = None + input: TaskInput | None = None + title: str | None = None + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + + +@docs_group('Models') +class Current(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + monthly_usage_usd: Annotated[float, Field(alias='monthlyUsageUsd', examples=[43])] + monthly_actor_compute_units: Annotated[float, Field(alias='monthlyActorComputeUnits', examples=[500.784475])] + monthly_external_data_transfer_gbytes: Annotated[ + float, Field(alias='monthlyExternalDataTransferGbytes', examples=[3.00861903931946]) + ] + monthly_proxy_serps: Annotated[int, Field(alias='monthlyProxySerps', examples=[34])] + monthly_residential_proxy_gbytes: Annotated[float, Field(alias='monthlyResidentialProxyGbytes', examples=[0.4])] + actor_memory_gbytes: Annotated[float, Field(alias='actorMemoryGbytes', examples=[8])] + actor_count: Annotated[int, Field(alias='actorCount', examples=[31])] + actor_task_count: Annotated[int, Field(alias='actorTaskCount', examples=[130])] + active_actor_job_count: Annotated[int, Field(alias='activeActorJobCount', examples=[0])] + team_account_seat_count: Annotated[int, Field(alias='teamAccountSeatCount', examples=[5])] + + +@docs_group('Models') +class CurrentPricingInfo(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + pricing_model: Annotated[str, Field(alias='pricingModel', examples=['FREE'])] + + +@docs_group('Models') +class DailyServiceUsages(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + date: Annotated[str, Field(examples=['2022-10-02T00:00:00.000Z'])] + service_usage: Annotated[dict[str, UsageItem], Field(alias='serviceUsage')] + total_usage_credits_usd: Annotated[float, Field(alias='totalUsageCreditsUsd', examples=[0.0474385791970591])] + + +@docs_group('Models') +class Dataset(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] + name: Annotated[str | None, Field(examples=['d7b9MDYsbtX5L7XAj'])] = None + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] + item_count: Annotated[int, Field(alias='itemCount', examples=[7], ge=0)] + clean_item_count: Annotated[int, Field(alias='cleanItemCount', examples=[5], ge=0)] + act_id: Annotated[str | None, Field(alias='actId')] = None + act_run_id: Annotated[str | None, Field(alias='actRunId')] = None + fields: list[str] | None = None + schema_: Annotated[ + dict[str, Any] | None, + Field( + alias='schema', + examples=[ + { + 'actorSpecification': 1, + 'title': 'My dataset', + 'views': { + 'overview': { + 'title': 'Overview', + 'transformation': {'fields': ['linkUrl']}, + 'display': { + 'component': 'table', + 'properties': {'linkUrl': {'label': 'Link URL', 'format': 'link'}}, + }, + } + }, + } + ], + ), + ] = None + """ + Defines the schema of items in your dataset, the full specification can be found in [Apify docs](/platform/actors/development/actor-definition/dataset-schema) + """ + console_url: Annotated[ + AnyUrl, Field(alias='consoleUrl', examples=['https://console.apify.com/storage/datasets/27TmTznX9YPeAYhkC']) + ] + items_public_url: Annotated[ + AnyUrl | None, + Field( + alias='itemsPublicUrl', + examples=['https://api.apify.com/v2/datasets/WkzbQMuFYuamGv3YF/items?signature=abc123'], + ), + ] = None + """ + A public link to access the dataset items directly. + """ + url_signing_secret_key: Annotated[str | None, Field(alias='urlSigningSecretKey')] = None + """ + A secret key for generating signed public URLs. It is only provided to clients with WRITE permission for the dataset. + """ + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + stats: DatasetStats | None = None + + +@docs_group('Models') +class DatasetFieldStatistics(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + min: float | None = None + """ + Minimum value of the field. For numbers, this is calculated directly. For strings, this is the length of the shortest string. For arrays, this is the length of the shortest array. For objects, this is the number of keys in the smallest object. + """ + max: float | None = None + """ + Maximum value of the field. For numbers, this is calculated directly. For strings, this is the length of the longest string. For arrays, this is the length of the longest array. For objects, this is the number of keys in the largest object. + """ + null_count: Annotated[int | None, Field(alias='nullCount')] = None + """ + How many items in the dataset have a null value for this field. + """ + empty_count: Annotated[int | None, Field(alias='emptyCount')] = None + """ + How many items in the dataset are `undefined`, meaning that for example empty string is not considered empty. + """ + + +@docs_group('Models') +class DatasetListItem(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] + name: Annotated[str, Field(examples=['d7b9MDYsbtX5L7XAj'])] + user_id: Annotated[str, Field(alias='userId', examples=['tbXmWu7GCxnyYtSiL'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] + item_count: Annotated[int, Field(alias='itemCount', examples=[7])] + clean_item_count: Annotated[int, Field(alias='cleanItemCount', examples=[5])] + act_id: Annotated[str | None, Field(alias='actId', examples=['zdc3Pyhyz3m8vjDeM'])] = None + act_run_id: Annotated[str | None, Field(alias='actRunId', examples=['HG7ML7M8z78YcAPEB'])] = None + + +@docs_group('Models') +class DatasetResponse(BaseModel): + """Response containing dataset metadata.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Dataset + + +@docs_group('Models') +class DatasetSchemaValidationError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Annotated[str | None, Field(examples=['schema-validation-error'])] = None + """ + The type of the error. + """ + message: Annotated[str | None, Field(examples=['Schema validation failed'])] = None + """ + A human-readable message describing the error. + """ + data: SchemaValidationErrorData | None = None + + +@docs_group('Models') +class DatasetStatistics(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + field_statistics: Annotated[dict[str, Any] | None, Field(alias='fieldStatistics')] = None + """ + When you configure the dataset [fields schema](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema/validation), we measure the statistics such as `min`, `max`, `nullCount` and `emptyCount` for each field. This property provides statistics for each field from dataset fields schema.

See dataset field statistics [documentation](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema/validation#dataset-field-statistics) for more information. + """ + + +@docs_group('Models') +class DatasetStatisticsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: DatasetStatistics + + +@docs_group('Models') +class DatasetStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + read_count: Annotated[int, Field(alias='readCount', examples=[22])] + write_count: Annotated[int, Field(alias='writeCount', examples=[3])] + storage_bytes: Annotated[int, Field(alias='storageBytes', examples=[783])] + + +@docs_group('Models') +class Datasets(BaseModel): + """Aliased dataset IDs for this run.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + default: Annotated[str | None, Field(examples=['wmKPijuyDnPZAPRMk'])] = None + """ + ID of the default dataset for this run. + """ + + +@docs_group('Models') +class DecodeAndVerifyData(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + decoded: Any + """ + The original object that was encoded. + """ + encoded_by_user_id: Annotated[str | None, Field(alias='encodedByUserId', examples=['wRwJZtadYvn4mBZmm'])] + is_verified_user: Annotated[bool, Field(alias='isVerifiedUser', examples=[False])] + + +@docs_group('Models') +class DecodeAndVerifyRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + encoded: Annotated[str, Field(examples=['eyJwYXlsb2FkIjoiLi4uIiwic2lnbmF0dXJlIjoiLi4uIn0='])] + + +@docs_group('Models') +class DecodeAndVerifyResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: DecodeAndVerifyData + + +@docs_group('Models') +class DefaultRunOptions(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + build: Annotated[str | None, Field(examples=['latest'])] = None + timeout_secs: Annotated[int | None, Field(alias='timeoutSecs', examples=[3600])] = None + memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[2048])] = None + restart_on_error: Annotated[bool | None, Field(alias='restartOnError', examples=[False])] = None + max_items: Annotated[int | None, Field(alias='maxItems')] = None + force_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='forcePermissionLevel')] = None + + +@docs_group('Models') +class DeletedRequestById(BaseModel): + """Confirmation of a request that was successfully deleted, identified by its ID.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + unique_key: Annotated[ + str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) + ] = None + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + + +@docs_group('Models') +class DeletedRequestByUniqueKey(BaseModel): + """Confirmation of a request that was successfully deleted, identified by its unique key.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """ + A unique identifier assigned to the request. + """ + + +@docs_group('Models') +class EffectivePlatformFeature(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] + disabled_reason: Annotated[ + str | None, + Field( + alias='disabledReason', + examples=[ + 'The "Selected public Actors for developers" feature is not enabled for your account. Please upgrade your plan or contact support@apify.com' + ], + ), + ] + disabled_reason_type: Annotated[str | None, Field(alias='disabledReasonType', examples=['DISABLED'])] + is_trial: Annotated[bool, Field(alias='isTrial', examples=[False])] + trial_expiration_at: Annotated[ + AwareDatetime | None, Field(alias='trialExpirationAt', examples=['2025-01-01T14:00:00.000Z']) + ] + + +@docs_group('Models') +class EffectivePlatformFeatures(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actors: Annotated[EffectivePlatformFeature, Field(alias='ACTORS')] + storage: Annotated[EffectivePlatformFeature, Field(alias='STORAGE')] + scheduler: Annotated[EffectivePlatformFeature, Field(alias='SCHEDULER')] + proxy: Annotated[EffectivePlatformFeature, Field(alias='PROXY')] + proxy_external_access: Annotated[EffectivePlatformFeature, Field(alias='PROXY_EXTERNAL_ACCESS')] + proxy_residential: Annotated[EffectivePlatformFeature, Field(alias='PROXY_RESIDENTIAL')] + proxy_serps: Annotated[EffectivePlatformFeature, Field(alias='PROXY_SERPS')] + webhooks: Annotated[EffectivePlatformFeature, Field(alias='WEBHOOKS')] + actors_public_all: Annotated[EffectivePlatformFeature, Field(alias='ACTORS_PUBLIC_ALL')] + actors_public_developer: Annotated[EffectivePlatformFeature, Field(alias='ACTORS_PUBLIC_DEVELOPER')] + + +@docs_group('Models') +class EncodeAndSignData(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + encoded: Annotated[str, Field(examples=['eyJwYXlsb2FkIjoiLi4uIiwic2lnbmF0dXJlIjoiLi4uIn0='])] + + +@docs_group('Models') +class EncodeAndSignResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: EncodeAndSignData + + +@docs_group('Models') +class EnvVar(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str, Field(examples=['MY_ENV_VAR'])] + value: Annotated[str | None, Field(examples=['my-value'])] = None + """ + The environment variable value. This field is absent in responses when `isSecret` is `true`, as secret values are never returned by the API. + """ + is_secret: Annotated[bool | None, Field(alias='isSecret', examples=[False])] = None + + +@docs_group('Models') +class EnvVarRequest(EnvVar): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class EnvVarResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: EnvVar + + +@docs_group('Models') +class ErrorDetail(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: ErrorType | None = None + message: str | None = None + """ + Human-readable error message describing what went wrong. + """ + + +@docs_group('Models') +class ErrorResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + error: ErrorDetail + + +@docs_group('Models') +class ErrorType(StrEnum): + """Machine-processable error type identifier.""" + + FIELD_3D_SECURE_AUTH_FAILED = '3d-secure-auth-failed' + ACCESS_RIGHT_ALREADY_EXISTS = 'access-right-already-exists' + ACTION_NOT_FOUND = 'action-not-found' + ACTOR_ALREADY_RENTED = 'actor-already-rented' + ACTOR_CAN_NOT_BE_RENTED = 'actor-can-not-be-rented' + ACTOR_DISABLED = 'actor-disabled' + ACTOR_IS_NOT_RENTED = 'actor-is-not-rented' + ACTOR_MEMORY_LIMIT_EXCEEDED = 'actor-memory-limit-exceeded' + ACTOR_NAME_EXISTS_NEW_OWNER = 'actor-name-exists-new-owner' + ACTOR_NAME_NOT_UNIQUE = 'actor-name-not-unique' + ACTOR_NOT_FOUND = 'actor-not-found' + ACTOR_NOT_GITHUB_ACTOR = 'actor-not-github-actor' + ACTOR_NOT_PUBLIC = 'actor-not-public' + ACTOR_PERMISSION_LEVEL_NOT_SUPPORTED_FOR_AGENTIC_PAYMENTS = ( + 'actor-permission-level-not-supported-for-agentic-payments' + ) + ACTOR_REVIEW_ALREADY_EXISTS = 'actor-review-already-exists' + ACTOR_RUN_FAILED = 'actor-run-failed' + ACTOR_STANDBY_NOT_SUPPORTED_FOR_AGENTIC_PAYMENTS = 'actor-standby-not-supported-for-agentic-payments' + ACTOR_TASK_NAME_NOT_UNIQUE = 'actor-task-name-not-unique' + AGENTIC_PAYMENT_INFO_RETRIEVAL_ERROR = 'agentic-payment-info-retrieval-error' + AGENTIC_PAYMENT_INFORMATION_MISSING = 'agentic-payment-information-missing' + AGENTIC_PAYMENT_INSUFFICIENT_AMOUNT = 'agentic-payment-insufficient-amount' + AGENTIC_PAYMENT_PROVIDER_INTERNAL_ERROR = 'agentic-payment-provider-internal-error' + AGENTIC_PAYMENT_PROVIDER_UNAUTHORIZED = 'agentic-payment-provider-unauthorized' + AIRTABLE_WEBHOOK_DEPRECATED = 'airtable-webhook-deprecated' + ALREADY_SUBSCRIBED_TO_PAID_ACTOR = 'already-subscribed-to-paid-actor' + APIFY_PLAN_REQUIRED_TO_USE_PAID_ACTOR = 'apify-plan-required-to-use-paid-actor' + APIFY_SIGNUP_NOT_ALLOWED = 'apify-signup-not-allowed' + AUTH_METHOD_NOT_SUPPORTED = 'auth-method-not-supported' + AUTHORIZATION_SERVER_NOT_FOUND = 'authorization-server-not-found' + AUTO_ISSUE_DATE_INVALID = 'auto-issue-date-invalid' + BACKGROUND_CHECK_REQUIRED = 'background-check-required' + BILLING_SYSTEM_ERROR = 'billing-system-error' + BLACK_FRIDAY_PLAN_EXPIRED = 'black-friday-plan-expired' + BRAINTREE_ERROR = 'braintree-error' + BRAINTREE_NOT_LINKED = 'braintree-not-linked' + BRAINTREE_OPERATION_TIMED_OUT = 'braintree-operation-timed-out' + BRAINTREE_UNSUPPORTED_CURRENCY = 'braintree-unsupported-currency' + BUILD_NOT_FOUND = 'build-not-found' + BUILD_OUTDATED = 'build-outdated' + CANNOT_ADD_APIFY_EVENTS_TO_PPE_ACTOR = 'cannot-add-apify-events-to-ppe-actor' + CANNOT_ADD_MULTIPLE_PRICING_INFOS = 'cannot-add-multiple-pricing-infos' + CANNOT_ADD_PRICING_INFO_THAT_ALTERS_PAST = 'cannot-add-pricing-info-that-alters-past' + CANNOT_ADD_SECOND_FUTURE_PRICING_INFO = 'cannot-add-second-future-pricing-info' + CANNOT_BUILD_ACTOR_FROM_WEBHOOK = 'cannot-build-actor-from-webhook' + CANNOT_CHANGE_BILLING_INTERVAL = 'cannot-change-billing-interval' + CANNOT_CHANGE_OWNER = 'cannot-change-owner' + CANNOT_CHARGE_APIFY_EVENT = 'cannot-charge-apify-event' + CANNOT_CHARGE_NON_PAY_PER_EVENT_ACTOR = 'cannot-charge-non-pay-per-event-actor' + CANNOT_COMMENT_AS_OTHER_USER = 'cannot-comment-as-other-user' + CANNOT_COPY_ACTOR_TASK = 'cannot-copy-actor-task' + CANNOT_CREATE_PAYOUT = 'cannot-create-payout' + CANNOT_CREATE_PUBLIC_ACTOR = 'cannot-create-public-actor' + CANNOT_CREATE_TAX_TRANSACTION = 'cannot-create-tax-transaction' + CANNOT_DELETE_CRITICAL_ACTOR = 'cannot-delete-critical-actor' + CANNOT_DELETE_INVOICE = 'cannot-delete-invoice' + CANNOT_DELETE_PAID_ACTOR = 'cannot-delete-paid-actor' + CANNOT_DISABLE_ONE_TIME_EVENT_FOR_APIFY_START_EVENT = 'cannot-disable-one-time-event-for-apify-start-event' + CANNOT_DISABLE_ORGANIZATION_WITH_ENABLED_MEMBERS = 'cannot-disable-organization-with-enabled-members' + CANNOT_DISABLE_USER_WITH_SUBSCRIPTION = 'cannot-disable-user-with-subscription' + CANNOT_LINK_OAUTH_TO_UNVERIFIED_EMAIL = 'cannot-link-oauth-to-unverified-email' + CANNOT_METAMORPH_TO_PAY_PER_RESULT_ACTOR = 'cannot-metamorph-to-pay-per-result-actor' + CANNOT_MODIFY_ACTOR_PRICING_TOO_FREQUENTLY = 'cannot-modify-actor-pricing-too-frequently' + CANNOT_MODIFY_ACTOR_PRICING_WITH_IMMEDIATE_EFFECT = 'cannot-modify-actor-pricing-with-immediate-effect' + CANNOT_OVERRIDE_PAID_ACTOR_TRIAL = 'cannot-override-paid-actor-trial' + CANNOT_PERMANENTLY_DELETE_SUBSCRIPTION = 'cannot-permanently-delete-subscription' + CANNOT_PUBLISH_ACTOR = 'cannot-publish-actor' + CANNOT_REDUCE_LAST_FULL_TOKEN = 'cannot-reduce-last-full-token' + CANNOT_REIMBURSE_MORE_THAN_ORIGINAL_CHARGE = 'cannot-reimburse-more-than-original-charge' + CANNOT_REIMBURSE_NON_RENTAL_CHARGE = 'cannot-reimburse-non-rental-charge' + CANNOT_REMOVE_OWN_ACTOR_FROM_RECENTLY_USED = 'cannot-remove-own-actor-from-recently-used' + CANNOT_REMOVE_PAYMENT_METHOD = 'cannot-remove-payment-method' + CANNOT_REMOVE_PRICING_INFO = 'cannot-remove-pricing-info' + CANNOT_REMOVE_RUNNING_RUN = 'cannot-remove-running-run' + CANNOT_REMOVE_USER_WITH_PUBLIC_ACTORS = 'cannot-remove-user-with-public-actors' + CANNOT_REMOVE_USER_WITH_SUBSCRIPTION = 'cannot-remove-user-with-subscription' + CANNOT_REMOVE_USER_WITH_UNPAID_INVOICE = 'cannot-remove-user-with-unpaid-invoice' + CANNOT_RENAME_ENV_VAR = 'cannot-rename-env-var' + CANNOT_RENT_PAID_ACTOR = 'cannot-rent-paid-actor' + CANNOT_REVIEW_OWN_ACTOR = 'cannot-review-own-actor' + CANNOT_SET_ACCESS_RIGHTS_FOR_OWNER = 'cannot-set-access-rights-for-owner' + CANNOT_SET_IS_STATUS_MESSAGE_TERMINAL = 'cannot-set-is-status-message-terminal' + CANNOT_UNPUBLISH_CRITICAL_ACTOR = 'cannot-unpublish-critical-actor' + CANNOT_UNPUBLISH_PAID_ACTOR = 'cannot-unpublish-paid-actor' + CANNOT_UNPUBLISH_PROFILE = 'cannot-unpublish-profile' + CANNOT_UPDATE_INVOICE_FIELD = 'cannot-update-invoice-field' + CONCURRENT_RUNS_LIMIT_EXCEEDED = 'concurrent-runs-limit-exceeded' + CONCURRENT_UPDATE_DETECTED = 'concurrent-update-detected' + CONFERENCE_TOKEN_NOT_FOUND = 'conference-token-not-found' + CONTENT_ENCODING_FORBIDDEN_FOR_HTML = 'content-encoding-forbidden-for-html' + COUPON_ALREADY_REDEEMED = 'coupon-already-redeemed' + COUPON_EXPIRED = 'coupon-expired' + COUPON_FOR_NEW_CUSTOMERS = 'coupon-for-new-customers' + COUPON_FOR_SUBSCRIBED_USERS = 'coupon-for-subscribed-users' + COUPON_LIMITS_ARE_IN_CONFLICT_WITH_CURRENT_LIMITS = 'coupon-limits-are-in-conflict-with-current-limits' + COUPON_MAX_NUMBER_OF_REDEMPTIONS_REACHED = 'coupon-max-number-of-redemptions-reached' + COUPON_NOT_FOUND = 'coupon-not-found' + COUPON_NOT_UNIQUE = 'coupon-not-unique' + COUPONS_DISABLED = 'coupons-disabled' + CREATE_GITHUB_ISSUE_NOT_ALLOWED = 'create-github-issue-not-allowed' + CREATOR_PLAN_NOT_AVAILABLE = 'creator-plan-not-available' + CRON_EXPRESSION_INVALID = 'cron-expression-invalid' + DAILY_AI_TOKEN_LIMIT_EXCEEDED = 'daily-ai-token-limit-exceeded' + DAILY_PUBLICATION_LIMIT_EXCEEDED = 'daily-publication-limit-exceeded' + DATASET_DOES_NOT_HAVE_FIELDS_SCHEMA = 'dataset-does-not-have-fields-schema' + DATASET_DOES_NOT_HAVE_SCHEMA = 'dataset-does-not-have-schema' + DATASET_LOCKED = 'dataset-locked' + DATASET_SCHEMA_INVALID = 'dataset-schema-invalid' + DCR_NOT_SUPPORTED = 'dcr-not-supported' + DEFAULT_DATASET_NOT_FOUND = 'default-dataset-not-found' + DELETING_DEFAULT_BUILD = 'deleting-default-build' + DELETING_UNFINISHED_BUILD = 'deleting-unfinished-build' + EMAIL_ALREADY_TAKEN = 'email-already-taken' + EMAIL_ALREADY_TAKEN_REMOVED_USER = 'email-already-taken-removed-user' + EMAIL_DOMAIN_NOT_ALLOWED_FOR_COUPON = 'email-domain-not-allowed-for-coupon' + EMAIL_INVALID = 'email-invalid' + EMAIL_NOT_ALLOWED = 'email-not-allowed' + EMAIL_NOT_VALID = 'email-not-valid' + EMAIL_UPDATE_TOO_SOON = 'email-update-too-soon' + ELEVATED_PERMISSIONS_NEEDED = 'elevated-permissions-needed' + ENV_VAR_ALREADY_EXISTS = 'env-var-already-exists' + EXCHANGE_RATE_FETCH_FAILED = 'exchange-rate-fetch-failed' + EXPIRED_CONFERENCE_TOKEN = 'expired-conference-token' + FAILED_TO_CHARGE_USER = 'failed-to-charge-user' + FINAL_INVOICE_NEGATIVE = 'final-invoice-negative' + GITHUB_BRANCH_EMPTY = 'github-branch-empty' + GITHUB_ISSUE_ALREADY_EXISTS = 'github-issue-already-exists' + GITHUB_PUBLIC_KEY_NOT_FOUND = 'github-public-key-not-found' + GITHUB_REPOSITORY_NOT_FOUND = 'github-repository-not-found' + GITHUB_SIGNATURE_DOES_NOT_MATCH_PAYLOAD = 'github-signature-does-not-match-payload' + GITHUB_USER_NOT_AUTHORIZED_FOR_ISSUES = 'github-user-not-authorized-for-issues' + GMAIL_NOT_ALLOWED = 'gmail-not-allowed' + ID_DOES_NOT_MATCH = 'id-does-not-match' + INCOMPATIBLE_BILLING_INTERVAL = 'incompatible-billing-interval' + INCOMPLETE_PAYOUT_BILLING_INFO = 'incomplete-payout-billing-info' + INCONSISTENT_CURRENCIES = 'inconsistent-currencies' + INCORRECT_PRICING_MODIFIER_PREFIX = 'incorrect-pricing-modifier-prefix' + INPUT_JSON_INVALID_CHARACTERS = 'input-json-invalid-characters' + INPUT_JSON_NOT_OBJECT = 'input-json-not-object' + INPUT_JSON_TOO_LONG = 'input-json-too-long' + INPUT_UPDATE_COLLISION = 'input-update-collision' + INSUFFICIENT_PERMISSIONS = 'insufficient-permissions' + INSUFFICIENT_PERMISSIONS_TO_CHANGE_FIELD = 'insufficient-permissions-to-change-field' + INSUFFICIENT_SECURITY_MEASURES = 'insufficient-security-measures' + INSUFFICIENT_TAX_COUNTRY_EVIDENCE = 'insufficient-tax-country-evidence' + INTEGRATION_AUTH_ERROR = 'integration-auth-error' + INTERNAL_SERVER_ERROR = 'internal-server-error' + INVALID_BILLING_INFO = 'invalid-billing-info' + INVALID_BILLING_PERIOD_FOR_PAYOUT = 'invalid-billing-period-for-payout' + INVALID_BUILD = 'invalid-build' + INVALID_CLIENT_KEY = 'invalid-client-key' + INVALID_COLLECTION = 'invalid-collection' + INVALID_CONFERENCE_LOGIN_PASSWORD = 'invalid-conference-login-password' + INVALID_CONTENT_TYPE_HEADER = 'invalid-content-type-header' + INVALID_CREDENTIALS = 'invalid-credentials' + INVALID_GIT_AUTH_TOKEN = 'invalid-git-auth-token' + INVALID_GITHUB_ISSUE_URL = 'invalid-github-issue-url' + INVALID_HEADER = 'invalid-header' + INVALID_ID = 'invalid-id' + INVALID_IDEMPOTENCY_KEY = 'invalid-idempotency-key' + INVALID_INPUT = 'invalid-input' + INVALID_INPUT_SCHEMA = 'invalid-input-schema' + INVALID_INVOICE = 'invalid-invoice' + INVALID_INVOICE_TYPE = 'invalid-invoice-type' + INVALID_ISSUE_DATE = 'invalid-issue-date' + INVALID_LABEL_PARAMS = 'invalid-label-params' + INVALID_MAIN_ACCOUNT_USER_ID = 'invalid-main-account-user-id' + INVALID_OAUTH_APP = 'invalid-oauth-app' + INVALID_OAUTH_SCOPE = 'invalid-oauth-scope' + INVALID_ONE_TIME_INVOICE = 'invalid-one-time-invoice' + INVALID_PARAMETER = 'invalid-parameter' + INVALID_PAYOUT_STATUS = 'invalid-payout-status' + INVALID_PICTURE_URL = 'invalid-picture-url' + INVALID_RECORD_KEY = 'invalid-record-key' + INVALID_REQUEST = 'invalid-request' + INVALID_RESOURCE_TYPE = 'invalid-resource-type' + INVALID_SIGNATURE = 'invalid-signature' + INVALID_SUBSCRIPTION_PLAN = 'invalid-subscription-plan' + INVALID_TAX_NUMBER = 'invalid-tax-number' + INVALID_TAX_NUMBER_FORMAT = 'invalid-tax-number-format' + INVALID_TOKEN = 'invalid-token' + INVALID_TOKEN_TYPE = 'invalid-token-type' + INVALID_TWO_FACTOR_CODE = 'invalid-two-factor-code' + INVALID_TWO_FACTOR_CODE_OR_RECOVERY_CODE = 'invalid-two-factor-code-or-recovery-code' + INVALID_TWO_FACTOR_RECOVERY_CODE = 'invalid-two-factor-recovery-code' + INVALID_USERNAME = 'invalid-username' + INVALID_VALUE = 'invalid-value' + INVITATION_INVALID_RESOURCE_TYPE = 'invitation-invalid-resource-type' + INVITATION_NO_LONGER_VALID = 'invitation-no-longer-valid' + INVOICE_CANCELED = 'invoice-canceled' + INVOICE_CANNOT_BE_REFUNDED_DUE_TO_TOO_HIGH_AMOUNT = 'invoice-cannot-be-refunded-due-to-too-high-amount' + INVOICE_INCOMPLETE = 'invoice-incomplete' + INVOICE_IS_DRAFT = 'invoice-is-draft' + INVOICE_LOCKED = 'invoice-locked' + INVOICE_MUST_BE_BUFFER = 'invoice-must-be-buffer' + INVOICE_NOT_CANCELED = 'invoice-not-canceled' + INVOICE_NOT_DRAFT = 'invoice-not-draft' + INVOICE_NOT_FOUND = 'invoice-not-found' + INVOICE_OUTDATED = 'invoice-outdated' + INVOICE_PAID_ALREADY = 'invoice-paid-already' + ISSUE_ALREADY_CONNECTED_TO_GITHUB = 'issue-already-connected-to-github' + ISSUE_NOT_FOUND = 'issue-not-found' + ISSUES_BAD_REQUEST = 'issues-bad-request' + ISSUER_NOT_REGISTERED = 'issuer-not-registered' + JOB_FINISHED = 'job-finished' + LABEL_ALREADY_LINKED = 'label-already-linked' + LAST_API_TOKEN = 'last-api-token' + LIMIT_REACHED = 'limit-reached' + MAX_ITEMS_MUST_BE_GREATER_THAN_ZERO = 'max-items-must-be-greater-than-zero' + MAX_METAMORPHS_EXCEEDED = 'max-metamorphs-exceeded' + MAX_TOTAL_CHARGE_USD_BELOW_MINIMUM = 'max-total-charge-usd-below-minimum' + MAX_TOTAL_CHARGE_USD_MUST_BE_GREATER_THAN_ZERO = 'max-total-charge-usd-must-be-greater-than-zero' + METHOD_NOT_ALLOWED = 'method-not-allowed' + MIGRATION_DISABLED = 'migration-disabled' + MISSING_ACTOR_RIGHTS = 'missing-actor-rights' + MISSING_API_TOKEN = 'missing-api-token' + MISSING_BILLING_INFO = 'missing-billing-info' + MISSING_LINE_ITEMS = 'missing-line-items' + MISSING_PAYMENT_DATE = 'missing-payment-date' + MISSING_PAYOUT_BILLING_INFO = 'missing-payout-billing-info' + MISSING_PROXY_PASSWORD = 'missing-proxy-password' + MISSING_REPORTING_FIELDS = 'missing-reporting-fields' + MISSING_RESOURCE_NAME = 'missing-resource-name' + MISSING_SETTINGS = 'missing-settings' + MISSING_USERNAME = 'missing-username' + MONTHLY_USAGE_LIMIT_TOO_LOW = 'monthly-usage-limit-too-low' + MORE_THAN_ONE_UPDATE_NOT_ALLOWED = 'more-than-one-update-not-allowed' + MULTIPLE_RECORDS_FOUND = 'multiple-records-found' + MUST_BE_ADMIN = 'must-be-admin' + NAME_NOT_UNIQUE = 'name-not-unique' + NEXT_RUNTIME_COMPUTATION_FAILED = 'next-runtime-computation-failed' + NO_COLUMNS_IN_EXPORTED_DATASET = 'no-columns-in-exported-dataset' + NO_PAYMENT_ATTEMPT_FOR_REFUND_FOUND = 'no-payment-attempt-for-refund-found' + NO_PAYMENT_METHOD_AVAILABLE = 'no-payment-method-available' + NO_TEAM_ACCOUNT_SEATS_AVAILABLE = 'no-team-account-seats-available' + NON_TEMPORARY_EMAIL = 'non-temporary-email' + NOT_ENOUGH_USAGE_TO_RUN_PAID_ACTOR = 'not-enough-usage-to-run-paid-actor' + NOT_IMPLEMENTED = 'not-implemented' + NOT_SUPPORTED_CURRENCIES = 'not-supported-currencies' + O_AUTH_SERVICE_ALREADY_CONNECTED = 'o-auth-service-already-connected' + O_AUTH_SERVICE_NOT_CONNECTED = 'o-auth-service-not-connected' + OAUTH_RESOURCE_ACCESS_FAILED = 'oauth-resource-access-failed' + ONE_TIME_INVOICE_ALREADY_MARKED_PAID = 'one-time-invoice-already-marked-paid' + ONLY_DRAFTS_CAN_BE_DELETED = 'only-drafts-can-be-deleted' + OPERATION_CANCELED = 'operation-canceled' + OPERATION_NOT_ALLOWED = 'operation-not-allowed' + OPERATION_TIMED_OUT = 'operation-timed-out' + ORGANIZATION_CANNOT_OWN_ITSELF = 'organization-cannot-own-itself' + ORGANIZATION_ROLE_NOT_FOUND = 'organization-role-not-found' + OVERLAPPING_PAYOUT_BILLING_PERIODS = 'overlapping-payout-billing-periods' + OWN_TOKEN_REQUIRED = 'own-token-required' + PAGE_NOT_FOUND = 'page-not-found' + PARAM_NOT_ONE_OF = 'param-not-one-of' + PARAMETER_REQUIRED = 'parameter-required' + PARAMETERS_MISMATCHED = 'parameters-mismatched' + PASSWORD_RESET_EMAIL_ALREADY_SENT = 'password-reset-email-already-sent' + PASSWORD_RESET_TOKEN_EXPIRED = 'password-reset-token-expired' + PAY_AS_YOU_GO_WITHOUT_MONTHLY_INTERVAL = 'pay-as-you-go-without-monthly-interval' + PAYMENT_ATTEMPT_STATUS_MESSAGE_REQUIRED = 'payment-attempt-status-message-required' + PAYOUT_ALREADY_PAID = 'payout-already-paid' + PAYOUT_CANCELED = 'payout-canceled' + PAYOUT_INVALID_STATE = 'payout-invalid-state' + PAYOUT_MUST_BE_APPROVED_TO_BE_MARKED_PAID = 'payout-must-be-approved-to-be-marked-paid' + PAYOUT_NOT_FOUND = 'payout-not-found' + PAYOUT_NUMBER_ALREADY_EXISTS = 'payout-number-already-exists' + PHONE_NUMBER_INVALID = 'phone-number-invalid' + PHONE_NUMBER_LANDLINE = 'phone-number-landline' + PHONE_NUMBER_OPTED_OUT = 'phone-number-opted-out' + PHONE_VERIFICATION_DISABLED = 'phone-verification-disabled' + PLATFORM_FEATURE_DISABLED = 'platform-feature-disabled' + PRICE_OVERRIDES_VALIDATION_FAILED = 'price-overrides-validation-failed' + PRICING_MODEL_NOT_SUPPORTED = 'pricing-model-not-supported' + PROMOTIONAL_PLAN_NOT_AVAILABLE = 'promotional-plan-not-available' + PROXY_AUTH_IP_NOT_UNIQUE = 'proxy-auth-ip-not-unique' + PUBLIC_ACTOR_DISABLED = 'public-actor-disabled' + QUERY_TIMEOUT = 'query-timeout' + QUOTED_PRICE_OUTDATED = 'quoted-price-outdated' + RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded' + RECAPTCHA_INVALID = 'recaptcha-invalid' + RECAPTCHA_REQUIRED = 'recaptcha-required' + RECORD_NOT_FOUND = 'record-not-found' + RECORD_NOT_PUBLIC = 'record-not-public' + RECORD_OR_TOKEN_NOT_FOUND = 'record-or-token-not-found' + RECORD_TOO_LARGE = 'record-too-large' + REDIRECT_URI_MISMATCH = 'redirect-uri-mismatch' + REDUCED_PLAN_NOT_AVAILABLE = 'reduced-plan-not-available' + RENTAL_CHARGE_ALREADY_REIMBURSED = 'rental-charge-already-reimbursed' + RENTAL_NOT_ALLOWED = 'rental-not-allowed' + REQUEST_ABORTED_PREMATURELY = 'request-aborted-prematurely' + REQUEST_HANDLED_OR_LOCKED = 'request-handled-or-locked' + REQUEST_ID_INVALID = 'request-id-invalid' + REQUEST_QUEUE_DUPLICATE_REQUESTS = 'request-queue-duplicate-requests' + REQUEST_TOO_LARGE = 'request-too-large' + REQUESTED_DATASET_VIEW_DOES_NOT_EXIST = 'requested-dataset-view-does-not-exist' + RESUME_TOKEN_EXPIRED = 'resume-token-expired' + RUN_FAILED = 'run-failed' + RUN_TIMEOUT_EXCEEDED = 'run-timeout-exceeded' + RUSSIA_IS_EVIL = 'russia-is-evil' + SAME_USER = 'same-user' + SCHEDULE_ACTOR_NOT_FOUND = 'schedule-actor-not-found' + SCHEDULE_ACTOR_TASK_NOT_FOUND = 'schedule-actor-task-not-found' + SCHEDULE_NAME_NOT_UNIQUE = 'schedule-name-not-unique' + SCHEMA_VALIDATION = 'schema-validation' + SCHEMA_VALIDATION_ERROR = 'schema-validation-error' + SCHEMA_VALIDATION_FAILED = 'schema-validation-failed' + SIGN_UP_METHOD_NOT_ALLOWED = 'sign-up-method-not-allowed' + SLACK_INTEGRATION_NOT_CUSTOM = 'slack-integration-not-custom' + SOCKET_CLOSED = 'socket-closed' + SOCKET_DESTROYED = 'socket-destroyed' + STORE_SCHEMA_INVALID = 'store-schema-invalid' + STORE_TERMS_NOT_ACCEPTED = 'store-terms-not-accepted' + STRIPE_ENABLED = 'stripe-enabled' + STRIPE_GENERIC_DECLINE = 'stripe-generic-decline' + STRIPE_NOT_ENABLED = 'stripe-not-enabled' + STRIPE_NOT_ENABLED_FOR_USER = 'stripe-not-enabled-for-user' + TAGGED_BUILD_REQUIRED = 'tagged-build-required' + TAX_COUNTRY_INVALID = 'tax-country-invalid' + TAX_NUMBER_INVALID = 'tax-number-invalid' + TAX_NUMBER_VALIDATION_FAILED = 'tax-number-validation-failed' + TAXAMO_CALL_FAILED = 'taxamo-call-failed' + TAXAMO_REQUEST_FAILED = 'taxamo-request-failed' + TESTING_ERROR = 'testing-error' + TOKEN_NOT_PROVIDED = 'token-not-provided' + TOO_FEW_VERSIONS = 'too-few-versions' + TOO_MANY_ACTOR_TASKS = 'too-many-actor-tasks' + TOO_MANY_ACTORS = 'too-many-actors' + TOO_MANY_LABELS_ON_RESOURCE = 'too-many-labels-on-resource' + TOO_MANY_MCP_CONNECTORS = 'too-many-mcp-connectors' + TOO_MANY_O_AUTH_APPS = 'too-many-o-auth-apps' + TOO_MANY_ORGANIZATIONS = 'too-many-organizations' + TOO_MANY_REQUESTS = 'too-many-requests' + TOO_MANY_SCHEDULES = 'too-many-schedules' + TOO_MANY_UI_ACCESS_KEYS = 'too-many-ui-access-keys' + TOO_MANY_USER_LABELS = 'too-many-user-labels' + TOO_MANY_VALUES = 'too-many-values' + TOO_MANY_VERSIONS = 'too-many-versions' + TOO_MANY_WEBHOOKS = 'too-many-webhooks' + UNEXPECTED_ROUTE = 'unexpected-route' + UNKNOWN_BUILD_TAG = 'unknown-build-tag' + UNKNOWN_PAYMENT_PROVIDER = 'unknown-payment-provider' + UNSUBSCRIBE_TOKEN_INVALID = 'unsubscribe-token-invalid' + UNSUPPORTED_ACTOR_PRICING_MODEL_FOR_AGENTIC_PAYMENTS = 'unsupported-actor-pricing-model-for-agentic-payments' + UNSUPPORTED_CONTENT_ENCODING = 'unsupported-content-encoding' + UNSUPPORTED_FILE_TYPE_FOR_ISSUE = 'unsupported-file-type-for-issue' + UNSUPPORTED_FILE_TYPE_IMAGE_EXPECTED = 'unsupported-file-type-image-expected' + UNSUPPORTED_FILE_TYPE_TEXT_OR_JSON_EXPECTED = 'unsupported-file-type-text-or-json-expected' + UNSUPPORTED_PERMISSION = 'unsupported-permission' + UPCOMING_SUBSCRIPTION_BILL_NOT_UP_TO_DATE = 'upcoming-subscription-bill-not-up-to-date' + USER_ALREADY_EXISTS = 'user-already-exists' + USER_ALREADY_VERIFIED = 'user-already-verified' + USER_CREATES_ORGANIZATIONS_TOO_FAST = 'user-creates-organizations-too-fast' + USER_DISABLED = 'user-disabled' + USER_EMAIL_IS_DISPOSABLE = 'user-email-is-disposable' + USER_EMAIL_NOT_SET = 'user-email-not-set' + USER_EMAIL_NOT_VERIFIED = 'user-email-not-verified' + USER_HAS_NO_SUBSCRIPTION = 'user-has-no-subscription' + USER_INTEGRATION_NOT_FOUND = 'user-integration-not-found' + USER_IS_ALREADY_INVITED = 'user-is-already-invited' + USER_IS_ALREADY_ORGANIZATION_MEMBER = 'user-is-already-organization-member' + USER_IS_NOT_MEMBER_OF_ORGANIZATION = 'user-is-not-member-of-organization' + USER_IS_NOT_ORGANIZATION = 'user-is-not-organization' + USER_IS_ORGANIZATION = 'user-is-organization' + USER_IS_ORGANIZATION_OWNER = 'user-is-organization-owner' + USER_IS_REMOVED = 'user-is-removed' + USER_NOT_FOUND = 'user-not-found' + USER_NOT_LOGGED_IN = 'user-not-logged-in' + USER_NOT_VERIFIED = 'user-not-verified' + USER_OR_TOKEN_NOT_FOUND = 'user-or-token-not-found' + USER_PLAN_NOT_ALLOWED_FOR_COUPON = 'user-plan-not-allowed-for-coupon' + USER_PROBLEM_WITH_CARD = 'user-problem-with-card' + USER_RECORD_NOT_FOUND = 'user-record-not-found' + USERNAME_ALREADY_TAKEN = 'username-already-taken' + USERNAME_MISSING = 'username-missing' + USERNAME_NOT_ALLOWED = 'username-not-allowed' + USERNAME_REMOVAL_FORBIDDEN = 'username-removal-forbidden' + USERNAME_REQUIRED = 'username-required' + VERIFICATION_EMAIL_ALREADY_SENT = 'verification-email-already-sent' + VERIFICATION_TOKEN_EXPIRED = 'verification-token-expired' + VERSION_ALREADY_EXISTS = 'version-already-exists' + VERSIONS_SIZE_EXCEEDED = 'versions-size-exceeded' + WEAK_PASSWORD = 'weak-password' + X402_AGENTIC_PAYMENT_ALREADY_FINALIZED = 'x402-agentic-payment-already-finalized' + X402_AGENTIC_PAYMENT_INSUFFICIENT_AMOUNT = 'x402-agentic-payment-insufficient-amount' + X402_AGENTIC_PAYMENT_MALFORMED_TOKEN = 'x402-agentic-payment-malformed-token' + X402_AGENTIC_PAYMENT_SETTLEMENT_FAILED = 'x402-agentic-payment-settlement-failed' + X402_AGENTIC_PAYMENT_SETTLEMENT_IN_PROGRESS = 'x402-agentic-payment-settlement-in-progress' + X402_AGENTIC_PAYMENT_SETTLEMENT_STUCK = 'x402-agentic-payment-settlement-stuck' + X402_AGENTIC_PAYMENT_UNAUTHORIZED = 'x402-agentic-payment-unauthorized' + X402_PAYMENT_REQUIRED = 'x402-payment-required' + ZERO_INVOICE = 'zero-invoice' + + +@docs_group('Models') +class EventData(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_id: Annotated[str, Field(alias='actorId', examples=['vvE7iMKuMc5qTHHsR'])] + actor_run_id: Annotated[str, Field(alias='actorRunId', examples=['JgwXN9BdwxGcu9MMF'])] + + +@docs_group('Models') +class ExampleRunInput(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + body: Annotated[str | None, Field(examples=['{ "helloWorld": 123 }'])] = None + content_type: Annotated[str | None, Field(alias='contentType', examples=['application/json; charset=utf-8'])] = None + + +@docs_group('Models') +class ExampleWebhookDispatch(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + status: WebhookDispatchStatus + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-13T08:36:13.202Z'])] = ( + None + ) + + +@docs_group('Models') +class FlatPricePerMonthActorPricingInfo(CommonActorPricingInfo): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + pricing_model: Annotated[Literal['FLAT_PRICE_PER_MONTH'], Field(alias='pricingModel')] + trial_minutes: Annotated[int, Field(alias='trialMinutes')] + """ + For how long this Actor can be used for free in trial period + """ + price_per_unit_usd: Annotated[float, Field(alias='pricePerUnitUsd')] + """ + Monthly flat price in USD + """ + + +@docs_group('Models') +class FreeActorPricingInfo(CommonActorPricingInfo): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + pricing_model: Annotated[Literal['FREE'], Field(alias='pricingModel')] + + +@docs_group('Models') +class GeneralAccess(StrEnum): + """Defines the general access level for the resource.""" + + ANYONE_WITH_ID_CAN_READ = 'ANYONE_WITH_ID_CAN_READ' + ANYONE_WITH_NAME_CAN_READ = 'ANYONE_WITH_NAME_CAN_READ' + FOLLOW_USER_SETTING = 'FOLLOW_USER_SETTING' + RESTRICTED = 'RESTRICTED' + + +@docs_group('Models') +class HeadAndLockResponse(BaseModel): + """Response containing locked requests from the request queue head.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: LockedRequestQueueHead + + +@docs_group('Models') +class HeadRequest(BaseModel): + """A request from the request queue head without lock information.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + url: Annotated[str, Field(examples=['https://apify.com'])] + """ + The URL of the request. + """ + method: HttpMethod | None = None + retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None + """ + The number of times this request has been retried. + """ + + +@docs_group('Models') +class HeadResponse(BaseModel): + """Response containing requests from the request queue head without locking.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: RequestQueueHead + + +@docs_group('Models') +class HttpMethod(StrEnum): + GET = 'GET' + HEAD = 'HEAD' + POST = 'POST' + PUT = 'PUT' + DELETE = 'DELETE' + CONNECT = 'CONNECT' + OPTIONS = 'OPTIONS' + TRACE = 'TRACE' + PATCH = 'PATCH' + + +@docs_group('Models') +class InvalidItem(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + item_position: Annotated[int | None, Field(alias='itemPosition', examples=[2])] = None + """ + The position of the invalid item in the array. + """ + validation_errors: Annotated[list[ValidationError] | None, Field(alias='validationErrors')] = None + """ + A complete list of AJV validation error objects for the invalid item. + """ + + +@docs_group('Models') +class KeyValueStore(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] + name: Annotated[str | None, Field(examples=['d7b9MDYsbtX5L7XAj'])] = None + user_id: Annotated[str | None, Field(alias='userId', examples=['BPWDBd7Z9c746JAnF'])] = None + username: Annotated[str | None, Field(examples=['janedoe'])] = None + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] + act_id: Annotated[str | None, Field(alias='actId', examples=[None])] = None + act_run_id: Annotated[str | None, Field(alias='actRunId', examples=[None])] = None + console_url: Annotated[ + AnyUrl | None, + Field(alias='consoleUrl', examples=['https://console.apify.com/storage/key-value-stores/27TmTznX9YPeAYhkC']), + ] = None + keys_public_url: Annotated[ + AnyUrl | None, + Field( + alias='keysPublicUrl', + examples=['https://api.apify.com/v2/key-value-stores/WkzbQMuFYuamGv3YF/keys?signature=abc123'], + ), + ] = None + """ + A public link to access keys of the key-value store directly. + """ + url_signing_secret_key: Annotated[str | None, Field(alias='urlSigningSecretKey')] = None + """ + A secret key for generating signed public URLs. It is only provided to clients with WRITE permission for the key-value store. + """ + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + stats: KeyValueStoreStats | None = None + + +@docs_group('Models') +class KeyValueStoreKey(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + key: Annotated[str, Field(examples=['second-key'])] + size: Annotated[int, Field(examples=[36])] + record_public_url: Annotated[ + AnyUrl, + Field( + alias='recordPublicUrl', + examples=['https://api.apify.com/v2/key-value-stores/WkzbQMuFYuamGv3YF/records/some-key?signature=abc123'], + ), + ] + """ + A public link to access this record directly. + """ + + +@docs_group('Models') +class KeyValueStoreResponse(BaseModel): + """Response containing key-value store data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: KeyValueStore + + +@docs_group('Models') +class KeyValueStoreStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + read_count: Annotated[int, Field(alias='readCount', examples=[9])] + write_count: Annotated[int, Field(alias='writeCount', examples=[3])] + delete_count: Annotated[int, Field(alias='deleteCount', examples=[6])] + list_count: Annotated[int, Field(alias='listCount', examples=[2])] + s3_storage_bytes: Annotated[int | None, Field(alias='s3StorageBytes', examples=[18])] = None + + +@docs_group('Models') +class KeyValueStores(BaseModel): + """Aliased key-value store IDs for this run.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + default: Annotated[str | None, Field(examples=['eJNzqsbPiopwJcgGQ'])] = None + """ + ID of the default key-value store for this run. + """ + + +@docs_group('Models') +class Limits(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + max_monthly_usage_usd: Annotated[float, Field(alias='maxMonthlyUsageUsd', examples=[300])] + max_monthly_actor_compute_units: Annotated[float, Field(alias='maxMonthlyActorComputeUnits', examples=[1000])] + max_monthly_external_data_transfer_gbytes: Annotated[ + float, Field(alias='maxMonthlyExternalDataTransferGbytes', examples=[7]) + ] + max_monthly_proxy_serps: Annotated[int, Field(alias='maxMonthlyProxySerps', examples=[50])] + max_monthly_residential_proxy_gbytes: Annotated[ + float, Field(alias='maxMonthlyResidentialProxyGbytes', examples=[0.5]) + ] + max_actor_memory_gbytes: Annotated[float, Field(alias='maxActorMemoryGbytes', examples=[16])] + max_actor_count: Annotated[int, Field(alias='maxActorCount', examples=[100])] + max_actor_task_count: Annotated[int, Field(alias='maxActorTaskCount', examples=[1000])] + max_concurrent_actor_jobs: Annotated[int, Field(alias='maxConcurrentActorJobs', examples=[256])] + max_team_account_seat_count: Annotated[int, Field(alias='maxTeamAccountSeatCount', examples=[9])] + data_retention_days: Annotated[int, Field(alias='dataRetentionDays', examples=[90])] + + +@docs_group('Models') +class LimitsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: AccountLimits + + +@docs_group('Models') +class ListOfActorsInStoreResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfStoreActors + + +@docs_group('Models') +class ListOfActorsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfActors + + +@docs_group('Models') +class ListOfBuildsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfBuilds + + +@docs_group('Models') +class ListOfDatasetsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfDatasets + + +@docs_group('Models') +class ListOfEnvVars(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total: Annotated[int, Field(examples=[5])] + items: list[EnvVar] + + +@docs_group('Models') +class ListOfEnvVarsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfEnvVars + + +@docs_group('Models') +class ListOfKeyValueStoresResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfKeyValueStores + + +@docs_group('Models') +class ListOfKeys(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[KeyValueStoreKey] + count: Annotated[int, Field(examples=[2])] + limit: Annotated[int, Field(examples=[2])] + exclusive_start_key: Annotated[str | None, Field(alias='exclusiveStartKey', examples=['some-key'])] = None + is_truncated: Annotated[bool, Field(alias='isTruncated', examples=[True])] + next_exclusive_start_key: Annotated[str | None, Field(alias='nextExclusiveStartKey', examples=['third-key'])] = None + + +@docs_group('Models') +class ListOfKeysResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfKeys + + +@docs_group('Models') +class ListOfRequestQueuesResponse(BaseModel): + """Response containing a list of request queues.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfRequestQueues + + +@docs_group('Models') +class ListOfRequests(BaseModel): + """A paginated list of requests from the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[Request] + """ + The array of requests. + """ + count: Annotated[int | None, Field(examples=[2])] = None + """ + The total number of requests matching the query. + """ + limit: Annotated[int, Field(examples=[2])] + """ + The maximum number of requests returned in this response. + """ + exclusive_start_id: Annotated[ + str | None, Field(alias='exclusiveStartId', deprecated=True, examples=['Ihnsp8YrvJ8102Kj']) + ] = None + """ + The ID of the last request from the previous page, used for pagination. + """ + cursor: Annotated[str | None, Field(examples=['eyJyZXF1ZXN0SWQiOiI0SVlLUWFXZ2FKUUlWNlMifQ'])] = None + """ + A cursor string used for current page of results. + """ + next_cursor: Annotated[ + str | None, Field(alias='nextCursor', examples=['eyJyZXF1ZXN0SWQiOiI5eFNNc1BrN1J6VUxTNXoifQ']) + ] = None + """ + A cursor string to be used to continue pagination. + """ + + +@docs_group('Models') +class ListOfRequestsResponse(BaseModel): + """Response containing a list of requests from the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfRequests + + +@docs_group('Models') +class ListOfRunsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfRuns + + +@docs_group('Models') +class ListOfSchedulesResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfSchedules + + +@docs_group('Models') +class ListOfTasksResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfTasks + + +@docs_group('Models') +class ListOfVersions(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total: Annotated[int, Field(examples=[5])] + items: list[Version] + + +@docs_group('Models') +class ListOfVersionsResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfVersions + + +@docs_group('Models') +class ListOfWebhooksResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfWebhooks + + +@docs_group('Models') +class LockedHeadRequest(BaseModel): + """A request from the request queue head that has been locked for processing.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + url: Annotated[str, Field(examples=['https://apify.com'])] + """ + The URL of the request. + """ + method: HttpMethod | None = None + retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None + """ + The number of times this request has been retried. + """ + lock_expires_at: Annotated[AwareDatetime, Field(alias='lockExpiresAt', examples=['2022-06-14T23:00:00.000Z'])] + """ + The timestamp when the lock on this request expires. + """ + + +@docs_group('Models') +class LockedRequestQueueHead(BaseModel): + """A batch of locked requests from the request queue head.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + limit: Annotated[int, Field(examples=[1000])] + """ + The maximum number of requests returned. + """ + queue_modified_at: Annotated[AwareDatetime, Field(alias='queueModifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + """ + The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. + """ + queue_has_locked_requests: Annotated[bool | None, Field(alias='queueHasLockedRequests', examples=[True])] = None + """ + Whether the request queue contains requests locked by any client (either the one calling the endpoint or a different one). + """ + client_key: Annotated[str | None, Field(alias='clientKey', examples=['client-one'])] = None + """ + The client key used for locking the requests. + """ + had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] + """ + Whether the request queue has been accessed by multiple different clients. + """ + lock_secs: Annotated[int, Field(alias='lockSecs', examples=[60])] + """ + The number of seconds the locks will be held. + """ + items: list[LockedHeadRequest] + """ + The array of locked requests from the request queue head. + """ + + +@docs_group('Models') +class Metamorph(BaseModel): + """Information about a metamorph event that occurred during the run.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-11-30T07:39:24.202Z'])] + """ + Time when the metamorph occurred. + """ + actor_id: Annotated[str, Field(alias='actorId', examples=['nspoEjklmnsF2oosD'])] + """ + ID of the Actor that the run was metamorphed to. + """ + build_id: Annotated[str, Field(alias='buildId', examples=['ME6oKecqy5kXDS4KQ'])] + """ + ID of the build used for the metamorphed Actor. + """ + input_key: Annotated[str | None, Field(alias='inputKey', examples=['INPUT-METAMORPH-1'])] = None + """ + Key of the input record in the key-value store. + """ + + +@docs_group('Models') +class MonthlyUsage(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + usage_cycle: Annotated[UsageCycle, Field(alias='usageCycle')] + monthly_service_usage: Annotated[dict[str, UsageItem], Field(alias='monthlyServiceUsage')] + daily_service_usages: Annotated[list[DailyServiceUsages], Field(alias='dailyServiceUsages')] + total_usage_credits_usd_before_volume_discount: Annotated[ + float, Field(alias='totalUsageCreditsUsdBeforeVolumeDiscount', examples=[0.786143673840067]) + ] + total_usage_credits_usd_after_volume_discount: Annotated[ + float, Field(alias='totalUsageCreditsUsdAfterVolumeDiscount', examples=[0.786143673840067]) + ] + + +@docs_group('Models') +class MonthlyUsageResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: MonthlyUsage + + +@docs_group('Models') +class PaginationResponse(BaseModel): + """Common pagination fields for list responses.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total: Annotated[int, Field(examples=[1], ge=0)] + """ + The total number of items available across all pages. + """ + offset: Annotated[int, Field(examples=[0], ge=0)] + """ + The starting position for this page of results. + """ + limit: Annotated[int, Field(examples=[1000], ge=1)] + """ + The maximum number of items returned per page. + """ + desc: Annotated[bool, Field(examples=[False])] + """ + Whether the results are sorted in descending order. + """ + count: Annotated[int, Field(examples=[1], ge=0)] + """ + The number of items returned in this response. + """ + + +@docs_group('Models') +class ListOfActors(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[ActorShort] + + +@docs_group('Models') +class ListOfBuilds(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[BuildShort] + + +@docs_group('Models') +class ListOfDatasets(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[DatasetListItem] + + +@docs_group('Models') +class ListOfKeyValueStores(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[KeyValueStore] + + +@docs_group('Models') +class ListOfRequestQueues(PaginationResponse): + """A paginated list of request queues.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[RequestQueueShort] + """ + The array of request queues. + """ + + +@docs_group('Models') +class ListOfRuns(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[RunShort] + + +@docs_group('Models') +class ListOfSchedules(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[ScheduleShort] + + +@docs_group('Models') +class ListOfStoreActors(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[StoreListActor] + + +@docs_group('Models') +class ListOfTasks(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[TaskShort] + + +@docs_group('Models') +class ListOfWebhookDispatches(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[WebhookDispatch] + + +@docs_group('Models') +class ListOfWebhooks(PaginationResponse): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + items: list[WebhookShort] + + +@docs_group('Models') +class PayPerEventActorPricingInfo(CommonActorPricingInfo): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + pricing_model: Annotated[Literal['PAY_PER_EVENT'], Field(alias='pricingModel')] + pricing_per_event: Annotated[PricingPerEvent, Field(alias='pricingPerEvent')] + minimal_max_total_charge_usd: Annotated[float | None, Field(alias='minimalMaxTotalChargeUsd')] = None + + +@docs_group('Models') +class Plan(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['Personal'])] + description: Annotated[str, Field(examples=['Cost-effective plan for freelancers, developers and students.'])] + is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] + monthly_base_price_usd: Annotated[float, Field(alias='monthlyBasePriceUsd', examples=[49])] + monthly_usage_credits_usd: Annotated[float, Field(alias='monthlyUsageCreditsUsd', examples=[49])] + usage_discount_percent: Annotated[float | None, Field(alias='usageDiscountPercent', examples=[0])] = None + enabled_platform_features: Annotated[ + list[str], + Field( + alias='enabledPlatformFeatures', examples=[['ACTORS', 'STORAGE', 'PROXY_SERPS', 'SCHEDULER', 'WEBHOOKS']] + ), + ] + max_monthly_usage_usd: Annotated[float, Field(alias='maxMonthlyUsageUsd', examples=[9999])] + max_actor_memory_gbytes: Annotated[float, Field(alias='maxActorMemoryGbytes', examples=[32])] + max_monthly_actor_compute_units: Annotated[float, Field(alias='maxMonthlyActorComputeUnits', examples=[1000])] + max_monthly_residential_proxy_gbytes: Annotated[ + float, Field(alias='maxMonthlyResidentialProxyGbytes', examples=[10]) + ] + max_monthly_proxy_serps: Annotated[int, Field(alias='maxMonthlyProxySerps', examples=[30000])] + max_monthly_external_data_transfer_gbytes: Annotated[ + float, Field(alias='maxMonthlyExternalDataTransferGbytes', examples=[1000]) + ] + max_actor_count: Annotated[int, Field(alias='maxActorCount', examples=[100])] + max_actor_task_count: Annotated[int, Field(alias='maxActorTaskCount', examples=[1000])] + data_retention_days: Annotated[int, Field(alias='dataRetentionDays', examples=[14])] + available_proxy_groups: Annotated[dict[str, int], Field(alias='availableProxyGroups')] + """ + The number of available proxies in this group. + """ + team_account_seat_count: Annotated[int, Field(alias='teamAccountSeatCount', examples=[1])] + support_level: Annotated[str, Field(alias='supportLevel', examples=['COMMUNITY'])] + available_add_ons: Annotated[list[str], Field(alias='availableAddOns', examples=[[]])] + + +@docs_group('Models') +class PricePerDatasetItemActorPricingInfo(CommonActorPricingInfo): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + pricing_model: Annotated[Literal['PRICE_PER_DATASET_ITEM'], Field(alias='pricingModel')] + unit_name: Annotated[str, Field(alias='unitName')] + """ + Name of the unit that is being charged + """ + price_per_unit_usd: Annotated[float, Field(alias='pricePerUnitUsd')] + + +@docs_group('Models') +class PriceTiers(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + quantity_above: Annotated[float, Field(alias='quantityAbove', examples=[0])] + discount_percent: Annotated[float, Field(alias='discountPercent', examples=[100])] + tier_quantity: Annotated[float, Field(alias='tierQuantity', examples=[0.39])] + unit_price_usd: Annotated[float, Field(alias='unitPriceUsd', examples=[0])] + price_usd: Annotated[float, Field(alias='priceUsd', examples=[0])] + + +@docs_group('Models') +class PricingPerEvent(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_charge_events: Annotated[dict[str, ActorChargeEvent] | None, Field(alias='actorChargeEvents')] = None + + +@docs_group('Models') +class PrivateUserDataResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: UserPrivateInfo + + +@docs_group('Models') +class Profile(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + bio: Annotated[str | None, Field(examples=['I started web scraping in 1985 using Altair BASIC.'])] = None + name: Annotated[str | None, Field(examples=['Jane Doe'])] = None + picture_url: Annotated[ + AnyUrl | None, Field(alias='pictureUrl', examples=['https://apify.com/img/anonymous_user_picture.png']) + ] = None + github_username: Annotated[str | None, Field(alias='githubUsername', examples=['torvalds.'])] = None + website_url: Annotated[AnyUrl | None, Field(alias='websiteUrl', examples=['http://www.example.com'])] = None + twitter_username: Annotated[str | None, Field(alias='twitterUsername', examples=['@BillGates'])] = None + + +@docs_group('Models') +class ProlongRequestLockResponse(BaseModel): + """Response containing updated lock information after prolonging a request lock.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: RequestLockInfo + + +@docs_group('Models') +class Proxy(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + password: Annotated[str, Field(examples=['ad78knd9Jkjd86'])] + groups: list[ProxyGroup] + + +@docs_group('Models') +class ProxyGroup(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str, Field(examples=['Group1'])] + description: Annotated[str, Field(examples=['Group1 description'])] + available_count: Annotated[int, Field(alias='availableCount', examples=[10])] + + +@docs_group('Models') +class PublicUserDataResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: UserPublicInfo + + +@docs_group('Models') +class PutItemResponseError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + error: DatasetSchemaValidationError + + +@docs_group('Models') +class PutItemsRequest(BaseModel): + """The request body containing the item(s) to add to the dataset. Can be a single + object or an array of objects. Each object represents one dataset item. + + """ + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class PutRecordRequest(BaseModel): + """The request body contains the value to store in the record. The content type + should be specified in the Content-Type header. + + """ + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class RecordResponse(BaseModel): + """The response body contains the value of the record. The content type of the response + is determined by the Content-Type header stored with the record. + + """ + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class RequestBase(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + unique_key: Annotated[ + str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) + ] = None + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + url: Annotated[str | None, Field(examples=['https://apify.com'])] = None + """ + The URL of the request. + """ + method: HttpMethod | None = None + retry_count: Annotated[int | None, Field(alias='retryCount', examples=[0])] = None + """ + The number of times this request has been retried. + """ + loaded_url: Annotated[str | None, Field(alias='loadedUrl', examples=['https://apify.com/jobs'])] = None + """ + The final URL that was loaded, after redirects (if any). + """ + payload: Annotated[str | dict[str, Any] | None, Field(examples=[None])] = None + """ + The request payload, typically used with POST or PUT requests. + """ + headers: Annotated[dict[str, Any] | None, Field(examples=[None])] = None + """ + HTTP headers sent with the request. + """ + user_data: Annotated[RequestUserData | None, Field(alias='userData')] = None + no_retry: Annotated[bool | None, Field(alias='noRetry', examples=[False])] = None + """ + Indicates whether the request should not be retried if processing fails. + """ + error_messages: Annotated[list[str] | None, Field(alias='errorMessages', examples=[None])] = None + """ + Error messages recorded from failed processing attempts. + """ + handled_at: Annotated[AwareDatetime | None, Field(alias='handledAt', examples=['2019-06-16T10:23:31.607Z'])] = None + """ + The timestamp when the request was marked as handled, if applicable. + """ + + +@docs_group('Models') +class Request(RequestBase): + """A request stored in the request queue, including its metadata and processing state.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """ + A unique identifier assigned to the request. + """ + + +@docs_group('Models') +class RequestDraft(BaseModel): + """A request that failed to be processed during a request queue operation and can be retried.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + url: Annotated[str, Field(examples=['https://apify.com'])] + """ + The URL of the request. + """ + method: HttpMethod | None = None + + +@docs_group('Models') +class RequestDraftDeleteById(BaseModel): + """A request that should be deleted, identified by its ID.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[ + str | None, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']) + ] = None + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + + +@docs_group('Models') +class RequestDraftDeleteByUniqueKey(BaseModel): + """A request that should be deleted, identified by its unique key.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None + """ + A unique identifier assigned to the request. + """ + unique_key: Annotated[str, Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com'])] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + + +@docs_group('Models') +class RequestDraftDelete(RootModel[RequestDraftDeleteById | RequestDraftDeleteByUniqueKey]): + root: Annotated[RequestDraftDeleteById | RequestDraftDeleteByUniqueKey, Field(title='RequestDraftDelete')] + """ + A request that should be deleted. + """ + + +@docs_group('Models') +class RequestLockInfo(BaseModel): + """Information about a request lock.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + lock_expires_at: Annotated[AwareDatetime, Field(alias='lockExpiresAt', examples=['2022-06-14T23:00:00.000Z'])] + """ + The timestamp when the lock on this request expires. + """ + + +@docs_group('Models') +class RequestQueue(BaseModel): + """A request queue object containing metadata and statistics.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] + """ + A unique identifier assigned to the request queue. + """ + name: Annotated[str | None, Field(examples=['some-name'])] = None + """ + The name of the request queue. + """ + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + """ + The ID of the user who owns the request queue. + """ + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + """ + The timestamp when the request queue was created. + """ + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + """ + The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. + """ + accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] + """ + The timestamp when the request queue was last accessed. + """ + total_request_count: Annotated[int, Field(alias='totalRequestCount', examples=[870], ge=0)] + """ + The total number of requests in the request queue. + """ + handled_request_count: Annotated[int, Field(alias='handledRequestCount', examples=[100], ge=0)] + """ + The number of requests that have been handled. + """ + pending_request_count: Annotated[int, Field(alias='pendingRequestCount', examples=[670], ge=0)] + """ + The number of requests that are pending and have not been handled yet. + """ + had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] + """ + Whether the request queue has been accessed by multiple different clients. + """ + console_url: Annotated[ + AnyUrl, Field(alias='consoleUrl', examples=['https://api.apify.com/v2/request-queues/27TmTznX9YPeAYhkC']) + ] + """ + The URL to view the request queue in the Apify console. + """ + stats: RequestQueueStats | None = None + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + + +@docs_group('Models') +class RequestQueueHead(BaseModel): + """A batch of requests from the request queue head without locking.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + limit: Annotated[int, Field(examples=[1000])] + """ + The maximum number of requests returned. + """ + queue_modified_at: Annotated[AwareDatetime, Field(alias='queueModifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + """ + The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. + """ + had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] + """ + Whether the request queue has been accessed by multiple different clients. + """ + items: list[HeadRequest] + """ + The array of requests from the request queue head. + """ + + +@docs_group('Models') +class RequestQueueResponse(BaseModel): + """Response containing request queue data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: RequestQueue + + +@docs_group('Models') +class RequestQueueShort(BaseModel): + """A shortened request queue object for list responses.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['WkzbQMuFYuamGv3YF'])] + """ + A unique identifier assigned to the request queue. + """ + name: Annotated[str, Field(examples=['some-name'])] + """ + The name of the request queue. + """ + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + """ + The ID of the user who owns the request queue. + """ + username: Annotated[str, Field(examples=['janedoe'])] + """ + The username of the user who owns the request queue. + """ + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + """ + The timestamp when the request queue was created. + """ + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + """ + The timestamp when the request queue was last modified. Modifications include adding, updating, or removing requests, as well as locking or unlocking requests in the request queue. + """ + accessed_at: Annotated[AwareDatetime, Field(alias='accessedAt', examples=['2019-12-14T08:36:13.202Z'])] + """ + The timestamp when the request queue was last accessed. + """ + expire_at: Annotated[AwareDatetime | None, Field(alias='expireAt', examples=['2019-06-02T17:15:06.751Z'])] = None + """ + The timestamp when the request queue will expire and be deleted. + """ + total_request_count: Annotated[int, Field(alias='totalRequestCount', examples=[870], ge=0)] + """ + The total number of requests in the request queue. + """ + handled_request_count: Annotated[int, Field(alias='handledRequestCount', examples=[100], ge=0)] + """ + The number of requests that have been handled. + """ + pending_request_count: Annotated[int, Field(alias='pendingRequestCount', examples=[670], ge=0)] + """ + The number of requests that are pending and have not been handled yet. + """ + act_id: Annotated[str | None, Field(alias='actId')] = None + """ + The ID of the Actor that created this request queue. + """ + act_run_id: Annotated[str | None, Field(alias='actRunId')] = None + """ + The ID of the Actor run that created this request queue. + """ + had_multiple_clients: Annotated[bool, Field(alias='hadMultipleClients', examples=[True])] + """ + Whether the request queue has been accessed by multiple different clients. + """ + + +@docs_group('Models') +class RequestQueueStats(BaseModel): + """Statistics about request queue operations and storage.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + delete_count: Annotated[int | None, Field(alias='deleteCount', examples=[0])] = None + """ + The number of delete operations performed on the request queue. + """ + head_item_read_count: Annotated[int | None, Field(alias='headItemReadCount', examples=[5])] = None + """ + The number of times requests from the head were read. + """ + read_count: Annotated[int | None, Field(alias='readCount', examples=[100])] = None + """ + The total number of read operations performed on the request queue. + """ + storage_bytes: Annotated[int | None, Field(alias='storageBytes', examples=[1024])] = None + """ + The total storage size in bytes used by the request queue. + """ + write_count: Annotated[int | None, Field(alias='writeCount', examples=[10])] = None + """ + The total number of write operations performed on the request queue. + """ + + +@docs_group('Models') +class RequestQueues(BaseModel): + """Aliased request queue IDs for this run.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + default: Annotated[str | None, Field(examples=['FL35cSF7jrxr3BY39'])] = None + """ + ID of the default request queue for this run. + """ + + +@docs_group('Models') +class RequestRegistration(BaseModel): + """Result of registering a request in the request queue, either by adding a new request or updating an existing one.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + request_id: Annotated[str, Field(alias='requestId', examples=['sbJ7klsdf7ujN9l'])] + """ + A unique identifier assigned to the request. + """ + was_already_present: Annotated[bool, Field(alias='wasAlreadyPresent', examples=[False])] + """ + Indicates whether a request with the same unique key already existed in the request queue. If true, no new request was created. + """ + was_already_handled: Annotated[bool, Field(alias='wasAlreadyHandled', examples=[False])] + """ + Indicates whether a request with the same unique key has already been processed by the request queue. + """ + + +@docs_group('Models') +class RequestResponse(BaseModel): + """Response containing a single request from the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Request + + +@docs_group('Models') +class RequestUserData(BaseModel): + """Custom user data attached to the request. Can contain arbitrary fields.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class Run(BaseModel): + """Represents an Actor run and its associated data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] + """ + Unique identifier of the Actor run. + """ + act_id: Annotated[str, Field(alias='actId', examples=['HDSasDasz78YcAPEB'])] + """ + ID of the Actor that was run. + """ + user_id: Annotated[str, Field(alias='userId', examples=['7sT5jcggjjA9fNcxF'])] + """ + ID of the user who started the run. + """ + actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['KJHSKHausidyaJKHs'])] = None + """ + ID of the Actor task, if the run was started from a task. + """ + started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] + """ + Time when the Actor run started. + """ + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( + None + ) + """ + Time when the Actor run finished. + """ + status: ActorJobStatus + """ + Current status of the Actor run. + """ + status_message: Annotated[str | None, Field(alias='statusMessage', examples=['Actor is running'])] = None + """ + Detailed message about the run status. + """ + is_status_message_terminal: Annotated[bool | None, Field(alias='isStatusMessageTerminal', examples=[False])] = None + """ + Whether the status message is terminal (final). + """ + meta: RunMeta + """ + Metadata about the Actor run. + """ + pricing_info: Annotated[ + PayPerEventActorPricingInfo + | PricePerDatasetItemActorPricingInfo + | FlatPricePerMonthActorPricingInfo + | FreeActorPricingInfo + | None, + Field(alias='pricingInfo', discriminator='pricing_model', title='ActorRunPricingInfo'), + ] = None + """ + Pricing information for the Actor. + """ + stats: RunStats + """ + Statistics of the Actor run. + """ + charged_event_counts: Annotated[ + dict[str, int] | None, + Field(alias='chargedEventCounts', examples=[{'actor-start': 1, 'page-crawled': 150, 'data-extracted': 75}]), + ] = None + """ + A map of charged event types to their counts. The keys are event type identifiers defined by the Actor's pricing model (pay-per-event), and the values are the number of times each event was charged during this run. + """ + options: RunOptions + """ + Configuration options for the Actor run. + """ + build_id: Annotated[str, Field(alias='buildId', examples=['7sT5jcggjjA9fNcxF'])] + """ + ID of the Actor build used for this run. + """ + exit_code: Annotated[int | None, Field(alias='exitCode', examples=[0])] = None + """ + Exit code of the Actor run process. + """ + general_access: Annotated[GeneralAccess, Field(alias='generalAccess')] + """ + General access level for the Actor run. + """ + default_key_value_store_id: Annotated[str, Field(alias='defaultKeyValueStoreId', examples=['eJNzqsbPiopwJcgGQ'])] + """ + ID of the default key-value store for this run. + """ + default_dataset_id: Annotated[str, Field(alias='defaultDatasetId', examples=['wmKPijuyDnPZAPRMk'])] + """ + ID of the default dataset for this run. + """ + default_request_queue_id: Annotated[str, Field(alias='defaultRequestQueueId', examples=['FL35cSF7jrxr3BY39'])] + """ + ID of the default request queue for this run. + """ + storage_ids: Annotated[StorageIds | None, Field(alias='storageIds')] = None + """ + A map of aliased storage IDs associated with this run, grouped by storage type. + """ + build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.36'])] = None + """ + Build number of the Actor build used for this run. + """ + container_url: Annotated[ + AnyUrl | None, Field(alias='containerUrl', examples=['https://g8kd8kbc5ge8.runs.apify.net']) + ] = None + """ + URL of the container running the Actor. + """ + is_container_server_ready: Annotated[bool | None, Field(alias='isContainerServerReady', examples=[True])] = None + """ + Whether the container's HTTP server is ready to accept requests. + """ + git_branch_name: Annotated[str | None, Field(alias='gitBranchName', examples=['master'])] = None + """ + Name of the git branch used for the Actor build. + """ + usage: RunUsage | None = None + """ + Resource usage statistics for the run. + """ + usage_total_usd: Annotated[float | None, Field(alias='usageTotalUsd', examples=[0.2654])] = None + """ + Total cost in USD for this run. Represents what you actually pay. For run owners: includes platform usage (compute units) and/or event costs depending on the Actor's pricing model. For run non-owners: only available for Pay-Per-Event Actors (event costs only). Requires authentication token to access. + """ + usage_usd: Annotated[RunUsageUsd | None, Field(alias='usageUsd')] = None + """ + Platform usage costs breakdown in USD. Only present if you own the run AND are paying for platform usage (Pay-Per-Usage, Rental, or Pay-Per-Event with usage costs like standby Actors). Not available for standard Pay-Per-Event Actors. Requires authentication token to access. + """ + metamorphs: list[Metamorph] | None = None + """ + List of metamorph events that occurred during the run. + """ + + +@docs_group('Models') +class RunFailedErrorDetail(ErrorDetail): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Annotated[Literal['run-failed'], Field(title='ErrorType')] = 'run-failed' + """ + Machine-processable error type identifier. + """ + + +@docs_group('Models') +class RunMeta(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + origin: RunOrigin + client_ip: Annotated[str | None, Field(alias='clientIp')] = None + """ + IP address of the client that started the run. + """ + user_agent: Annotated[str | None, Field(alias='userAgent')] = None + """ + User agent of the client that started the run. + """ + schedule_id: Annotated[str | None, Field(alias='scheduleId')] = None + """ + ID of the schedule that triggered the run. + """ + scheduled_at: Annotated[AwareDatetime | None, Field(alias='scheduledAt')] = None + """ + Time when the run was scheduled. + """ + + +@docs_group('Models') +class RunOptions(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + build: Annotated[str, Field(examples=['latest'])] + timeout_secs: Annotated[int, Field(alias='timeoutSecs', examples=[300], ge=0)] + memory_mbytes: Annotated[int, Field(alias='memoryMbytes', examples=[1024], ge=128, le=32768)] + disk_mbytes: Annotated[int, Field(alias='diskMbytes', examples=[2048], ge=0)] + max_items: Annotated[int | None, Field(alias='maxItems', examples=[1000], ge=1)] = None + max_total_charge_usd: Annotated[float | None, Field(alias='maxTotalChargeUsd', examples=[5], ge=0.0)] = None + + +@docs_group('Models') +class RunOrigin(StrEnum): + DEVELOPMENT = 'DEVELOPMENT' + WEB = 'WEB' + API = 'API' + SCHEDULER = 'SCHEDULER' + TEST = 'TEST' + WEBHOOK = 'WEBHOOK' + ACTOR = 'ACTOR' + CLI = 'CLI' + STANDBY = 'STANDBY' + + +@docs_group('Models') +class RunResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Run + + +@docs_group('Models') +class RunShort(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['HG7ML7M8z78YcAPEB'])] + act_id: Annotated[str, Field(alias='actId', examples=['HDSasDasz78YcAPEB'])] + actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['KJHSKHausidyaJKHs'])] = None + status: ActorJobStatus + started_at: Annotated[AwareDatetime, Field(alias='startedAt', examples=['2019-11-30T07:34:24.202Z'])] + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-12-12T09:30:12.202Z'])] = ( + None + ) + build_id: Annotated[str, Field(alias='buildId', examples=['HG7ML7M8z78YcAPEB'])] + build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.2'])] = None + meta: RunMeta + usage_total_usd: Annotated[float, Field(alias='usageTotalUsd', examples=[0.2])] + default_key_value_store_id: Annotated[str, Field(alias='defaultKeyValueStoreId', examples=['sfAjeR4QmeJCQzTfe'])] + default_dataset_id: Annotated[str, Field(alias='defaultDatasetId', examples=['3ZojQDdFTsyE7Moy4'])] + default_request_queue_id: Annotated[str, Field(alias='defaultRequestQueueId', examples=['so93g2shcDzK3pA85'])] + + +@docs_group('Models') +class RunStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + input_body_len: Annotated[int | None, Field(alias='inputBodyLen', examples=[240], ge=0)] = None + migration_count: Annotated[int | None, Field(alias='migrationCount', examples=[0], ge=0)] = None + reboot_count: Annotated[int | None, Field(alias='rebootCount', examples=[0], ge=0)] = None + restart_count: Annotated[int, Field(alias='restartCount', examples=[0], ge=0)] + resurrect_count: Annotated[int, Field(alias='resurrectCount', examples=[2], ge=0)] + mem_avg_bytes: Annotated[float | None, Field(alias='memAvgBytes', examples=[267874071.9])] = None + mem_max_bytes: Annotated[int | None, Field(alias='memMaxBytes', examples=[404713472], ge=0)] = None + mem_current_bytes: Annotated[int | None, Field(alias='memCurrentBytes', examples=[0], ge=0)] = None + cpu_avg_usage: Annotated[float | None, Field(alias='cpuAvgUsage', examples=[33.7532101107538])] = None + cpu_max_usage: Annotated[float | None, Field(alias='cpuMaxUsage', examples=[169.650735534941])] = None + cpu_current_usage: Annotated[float | None, Field(alias='cpuCurrentUsage', examples=[0])] = None + net_rx_bytes: Annotated[int | None, Field(alias='netRxBytes', examples=[103508042], ge=0)] = None + net_tx_bytes: Annotated[int | None, Field(alias='netTxBytes', examples=[4854600], ge=0)] = None + duration_millis: Annotated[int | None, Field(alias='durationMillis', examples=[248472], ge=0)] = None + run_time_secs: Annotated[float | None, Field(alias='runTimeSecs', examples=[248.472], ge=0.0)] = None + metamorph: Annotated[int | None, Field(examples=[0], ge=0)] = None + compute_units: Annotated[float, Field(alias='computeUnits', examples=[0.13804], ge=0.0)] + + +@docs_group('Models') +class RunTimeoutExceededErrorDetail(ErrorDetail): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Annotated[Literal['run-timeout-exceeded'], Field(title='ErrorType')] = 'run-timeout-exceeded' + """ + Machine-processable error type identifier. + """ + + +@docs_group('Models') +class RunUsage(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[3])] = None + dataset_reads: Annotated[int | None, Field(alias='DATASET_READS', examples=[4])] = None + dataset_writes: Annotated[int | None, Field(alias='DATASET_WRITES', examples=[4])] = None + key_value_store_reads: Annotated[int | None, Field(alias='KEY_VALUE_STORE_READS', examples=[5])] = None + key_value_store_writes: Annotated[int | None, Field(alias='KEY_VALUE_STORE_WRITES', examples=[3])] = None + key_value_store_lists: Annotated[int | None, Field(alias='KEY_VALUE_STORE_LISTS', examples=[5])] = None + request_queue_reads: Annotated[int | None, Field(alias='REQUEST_QUEUE_READS', examples=[2])] = None + request_queue_writes: Annotated[int | None, Field(alias='REQUEST_QUEUE_WRITES', examples=[1])] = None + data_transfer_internal_gbytes: Annotated[ + float | None, Field(alias='DATA_TRANSFER_INTERNAL_GBYTES', examples=[1]) + ] = None + data_transfer_external_gbytes: Annotated[ + float | None, Field(alias='DATA_TRANSFER_EXTERNAL_GBYTES', examples=[3]) + ] = None + proxy_residential_transfer_gbytes: Annotated[ + float | None, Field(alias='PROXY_RESIDENTIAL_TRANSFER_GBYTES', examples=[34]) + ] = None + proxy_serps: Annotated[int | None, Field(alias='PROXY_SERPS', examples=[3])] = None + + +@docs_group('Models') +class RunUsageUsd(BaseModel): + """Resource usage costs in USD. All values are monetary amounts in US dollars.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_compute_units: Annotated[float | None, Field(alias='ACTOR_COMPUTE_UNITS', examples=[0.0003])] = None + dataset_reads: Annotated[float | None, Field(alias='DATASET_READS', examples=[0.0001])] = None + dataset_writes: Annotated[float | None, Field(alias='DATASET_WRITES', examples=[0.0001])] = None + key_value_store_reads: Annotated[float | None, Field(alias='KEY_VALUE_STORE_READS', examples=[0.0001])] = None + key_value_store_writes: Annotated[float | None, Field(alias='KEY_VALUE_STORE_WRITES', examples=[5e-05])] = None + key_value_store_lists: Annotated[float | None, Field(alias='KEY_VALUE_STORE_LISTS', examples=[0.0001])] = None + request_queue_reads: Annotated[float | None, Field(alias='REQUEST_QUEUE_READS', examples=[0.0001])] = None + request_queue_writes: Annotated[float | None, Field(alias='REQUEST_QUEUE_WRITES', examples=[0.0001])] = None + data_transfer_internal_gbytes: Annotated[ + float | None, Field(alias='DATA_TRANSFER_INTERNAL_GBYTES', examples=[0.001]) + ] = None + data_transfer_external_gbytes: Annotated[ + float | None, Field(alias='DATA_TRANSFER_EXTERNAL_GBYTES', examples=[0.003]) + ] = None + proxy_residential_transfer_gbytes: Annotated[ + float | None, Field(alias='PROXY_RESIDENTIAL_TRANSFER_GBYTES', examples=[0.034]) + ] = None + proxy_serps: Annotated[float | None, Field(alias='PROXY_SERPS', examples=[0.003])] = None + + +@docs_group('Models') +class ScheduleActionRunActor(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['c6KfSgoQzFhMk3etc'])] + type: Literal['RUN_ACTOR'] + actor_id: Annotated[str, Field(alias='actorId', examples=['jF8GGEvbEg4Au3NLA'])] + run_input: Annotated[ScheduleActionRunInput | None, Field(alias='runInput')] = None + run_options: Annotated[TaskOptions | None, Field(alias='runOptions')] = None + + +@docs_group('Models') +class ScheduleActionRunActorTask(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['c6KfSgoQzFhMk3etc'])] + type: Literal['RUN_ACTOR_TASK'] + actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['jF8GGEvbEg4Au3NLA'])] + input: dict[str, Any] | None = None + + +@docs_group('Models') +class ScheduleActionRunInput(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + body: Annotated[str | None, Field(examples=['{\\n "foo": "actor"\\n}'])] = None + content_type: Annotated[str | None, Field(alias='contentType', examples=['application/json; charset=utf-8'])] = None + + +@docs_group('Models') +class ScheduleActionShortRunActor(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['ZReCs7hkdieq8ZUki'])] + type: Literal['RUN_ACTOR'] + actor_id: Annotated[str, Field(alias='actorId', examples=['HKhKmiCMrDgu9eXeE'])] + + +@docs_group('Models') +class ScheduleActionShortRunActorTask(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['ZReCs7hkdieq8ZUki'])] + type: Literal['RUN_ACTOR_TASK'] + actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['HKhKmiCMrDgu9eXeE'])] + + +@docs_group('Models') +class ScheduleBase(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['asdLZtadYvn4mBZmm'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + name: Annotated[str, Field(examples=['my-schedule'])] + cron_expression: Annotated[str, Field(alias='cronExpression', examples=['* * * * *'])] + timezone: Annotated[str, Field(examples=['UTC'])] + is_enabled: Annotated[bool, Field(alias='isEnabled', examples=[True])] + is_exclusive: Annotated[bool, Field(alias='isExclusive', examples=[True])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-20T06:33:11.202Z'])] + next_run_at: Annotated[AwareDatetime | None, Field(alias='nextRunAt', examples=['2019-04-12T07:34:10.202Z'])] = None + last_run_at: Annotated[AwareDatetime | None, Field(alias='lastRunAt', examples=['2019-04-12T07:33:10.202Z'])] = None + + +@docs_group('Models') +class Schedule(ScheduleBase): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + description: Annotated[str | None, Field(examples=['Schedule of actor ...'])] = None + title: str | None = None + actions: list[Annotated[ScheduleActionRunActor | ScheduleActionRunActorTask, Field(discriminator='type')]] + + +@docs_group('Models') +class ScheduleCreate(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str | None, Field(examples=['my-schedule'])] = None + is_enabled: Annotated[bool | None, Field(alias='isEnabled', examples=[True])] = None + is_exclusive: Annotated[bool | None, Field(alias='isExclusive', examples=[True])] = None + cron_expression: Annotated[str | None, Field(alias='cronExpression', examples=['* * * * *'])] = None + timezone: Annotated[str | None, Field(examples=['UTC'])] = None + description: Annotated[str | None, Field(examples=['Schedule of actor ...'])] = None + title: str | None = None + actions: ( + list[Annotated[ScheduleCreateActionRunActor | ScheduleCreateActionRunActorTask, Field(discriminator='type')]] + | None + ) = None + + +@docs_group('Models') +class ScheduleCreateActionRunActor(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Literal['RUN_ACTOR'] + actor_id: Annotated[str, Field(alias='actorId', examples=['jF8GGEvbEg4Au3NLA'])] + run_input: Annotated[ScheduleActionRunInput | None, Field(alias='runInput')] = None + run_options: Annotated[TaskOptions | None, Field(alias='runOptions')] = None + + +@docs_group('Models') +class ScheduleCreateActionRunActorTask(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Literal['RUN_ACTOR_TASK'] + actor_task_id: Annotated[str, Field(alias='actorTaskId', examples=['jF8GGEvbEg4Au3NLA'])] + input: dict[str, Any] | None = None + + +@docs_group('Models') +class ScheduleInvoked(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + message: Annotated[str, Field(examples=['Schedule invoked'])] + level: Annotated[str, Field(examples=['INFO'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-03-26T12:28:00.370Z'])] + + +@docs_group('Models') +class ScheduleLogResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: list[ScheduleInvoked] + + +@docs_group('Models') +class ScheduleResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Schedule + + +@docs_group('Models') +class ScheduleShort(ScheduleBase): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actions: list[Annotated[ScheduleActionShortRunActor | ScheduleActionShortRunActorTask, Field(discriminator='type')]] + + +@docs_group('Models') +class SchemaValidationErrorData(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + invalid_items: Annotated[list[InvalidItem], Field(alias='invalidItems')] + """ + A list of invalid items in the received array of items. + """ + + +@docs_group('Models') +class SourceCodeFile(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + format: SourceCodeFileFormat | None = None + content: Annotated[str | None, Field(examples=["console.log('This is the main.js file');"])] = None + name: Annotated[str, Field(examples=['src/main.js'])] + + +@docs_group('Models') +class SourceCodeFileFormat(StrEnum): + BASE64 = 'BASE64' + TEXT = 'TEXT' + + +@docs_group('Models') +class SourceCodeFolder(BaseModel): + """Represents a folder in the Actor's source code structure. Distinguished from + SourceCodeFile by the presence of the `folder` property set to `true`. + + """ + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str, Field(examples=['src/utils'])] + """ + The folder path relative to the Actor's root directory. + """ + folder: Annotated[bool, Field(examples=[True])] + """ + Always `true` for folders. Used to distinguish folders from files. + """ + + +@docs_group('Models') +class StorageIds(BaseModel): + """A map of aliased storage IDs associated with this run, grouped by storage type.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + datasets: Datasets | None = None + """ + Aliased dataset IDs for this run. + """ + key_value_stores: Annotated[KeyValueStores | None, Field(alias='keyValueStores')] = None + """ + Aliased key-value store IDs for this run. + """ + request_queues: Annotated[RequestQueues | None, Field(alias='requestQueues')] = None + """ + Aliased request queue IDs for this run. + """ + + +@docs_group('Models') +class StorageOwnership(StrEnum): + OWNED_BY_ME = 'ownedByMe' + SHARED_WITH_ME = 'sharedWithMe' + + +@docs_group('Models') +class Storages(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + dataset: dict[str, Any] | None = None + """ + Defines the schema of items in your dataset, the full specification can be found in [Apify docs](https://docs.apify.com/platform/actors/development/actor-definition/dataset-schema) + """ + + +@docs_group('Models') +class StoreListActor(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] + title: Annotated[str, Field(examples=['My Public Actor'])] + name: Annotated[str, Field(examples=['my-public-actor'])] + username: Annotated[str, Field(examples=['jane35'])] + user_full_name: Annotated[str, Field(alias='userFullName', examples=['Jane H. Doe'])] + description: Annotated[str, Field(examples=['My public actor!'])] + categories: Annotated[list[str] | None, Field(examples=[['MARKETING', 'LEAD_GENERATION']])] = None + notice: str | None = None + picture_url: Annotated[AnyUrl | None, Field(alias='pictureUrl', examples=['https://...'])] = None + user_picture_url: Annotated[AnyUrl | None, Field(alias='userPictureUrl', examples=['https://...'])] = None + url: Annotated[AnyUrl | None, Field(examples=['https://...'])] = None + stats: ActorStats + current_pricing_info: Annotated[CurrentPricingInfo, Field(alias='currentPricingInfo')] + is_white_listed_for_agentic_payment: Annotated[bool | None, Field(alias='isWhiteListedForAgenticPayment')] = None + """ + Whether the Actor is whitelisted for agentic payment processing. + """ + readme_summary: Annotated[str | None, Field(alias='readmeSummary')] = None + """ + A brief, LLM-generated readme summary + """ + + +@docs_group('Models') +class TaggedBuildInfo(BaseModel): + """Information about a tagged build.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + build_id: Annotated[str | None, Field(alias='buildId', examples=['z2EryhbfhgSyqj6Hn'])] = None + """ + The ID of the build associated with this tag. + """ + build_number: Annotated[str | None, Field(alias='buildNumber', examples=['0.0.2'])] = None + """ + The build number/version string. + """ + finished_at: Annotated[AwareDatetime | None, Field(alias='finishedAt', examples=['2019-06-10T11:15:49.286Z'])] = ( + None + ) + """ + The timestamp when the build finished. + """ + + +@docs_group('Models') +class Task(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] + name: Annotated[str, Field(examples=['my-task'])] + username: Annotated[str | None, Field(examples=['janedoe'])] = None + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2018-10-26T07:23:14.855Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2018-10-26T13:30:49.578Z'])] + removed_at: Annotated[AwareDatetime | None, Field(alias='removedAt')] = None + stats: TaskStats | None = None + options: TaskOptions | None = None + input: TaskInput | None = None + title: str | None = None + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + standby_url: Annotated[AnyUrl | None, Field(alias='standbyUrl')] = None + + +@docs_group('Models') +class TaskInput(BaseModel): + """The input configuration for the Actor task. This is a user-defined JSON object + that will be passed to the Actor when the task is run. + + """ + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + + +@docs_group('Models') +class TaskOptions(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + build: Annotated[str | None, Field(examples=['latest'])] = None + timeout_secs: Annotated[int | None, Field(alias='timeoutSecs', examples=[300])] = None + memory_mbytes: Annotated[int | None, Field(alias='memoryMbytes', examples=[1024])] = None + max_items: Annotated[int | None, Field(alias='maxItems', examples=[1000])] = None + max_total_charge_usd: Annotated[float | None, Field(alias='maxTotalChargeUsd', examples=[5])] = None + restart_on_error: Annotated[bool | None, Field(alias='restartOnError', examples=[False])] = None + + +@docs_group('Models') +class TaskResponse(BaseModel): + """Response containing Actor task data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Task + + +@docs_group('Models') +class TaskShort(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['zdc3Pyhyz3m8vjDeM'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + act_id: Annotated[str, Field(alias='actId', examples=['asADASadYvn4mBZmm'])] + act_name: Annotated[str | None, Field(alias='actName', examples=['my-actor'])] = None + name: Annotated[str, Field(examples=['my-task'])] + username: Annotated[str | None, Field(examples=['janedoe'])] = None + act_username: Annotated[str | None, Field(alias='actUsername', examples=['janedoe'])] = None + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2018-10-26T07:23:14.855Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2018-10-26T13:30:49.578Z'])] + stats: TaskStats | None = None + + +@docs_group('Models') +class TaskStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total_runs: Annotated[int | None, Field(alias='totalRuns', examples=[15])] = None + + +@docs_group('Models') +class TestWebhookResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: WebhookDispatch + + +@docs_group('Models') +class UnknownBuildTagError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + error: UnknownBuildTagErrorDetail | None = None + + +@docs_group('Models') +class UnknownBuildTagErrorDetail(ErrorDetail): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + type: Annotated[Literal['unknown-build-tag'], Field(title='ErrorType')] = 'unknown-build-tag' + """ + Machine-processable error type identifier. + """ + + +@docs_group('Models') +class UnlockRequestsResponse(BaseModel): + """Response containing the result of unlocking requests.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: UnlockRequestsResult + + +@docs_group('Models') +class UnlockRequestsResult(BaseModel): + """Result of unlocking requests in the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + unlocked_count: Annotated[int, Field(alias='unlockedCount', examples=[10])] + """ + Number of requests that were successfully unlocked. + """ + + +@docs_group('Models') +class UpdateActorRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str | None, Field(examples=['MyActor'])] = None + description: Annotated[str | None, Field(examples=['My favourite actor!'])] = None + is_public: Annotated[bool | None, Field(alias='isPublic', examples=[False])] = None + actor_permission_level: Annotated[ActorPermissionLevel | None, Field(alias='actorPermissionLevel')] = None + seo_title: Annotated[str | None, Field(alias='seoTitle', examples=['My actor'])] = None + seo_description: Annotated[str | None, Field(alias='seoDescription', examples=['My actor is the best'])] = None + title: Annotated[str | None, Field(examples=['My Actor'])] = None + restart_on_error: Annotated[bool | None, Field(alias='restartOnError', deprecated=True, examples=[False])] = None + versions: list[CreateOrUpdateVersionRequest] | None = None + pricing_infos: Annotated[ + list[ + Annotated[ + PayPerEventActorPricingInfo + | PricePerDatasetItemActorPricingInfo + | FlatPricePerMonthActorPricingInfo + | FreeActorPricingInfo, + Field(discriminator='pricing_model'), + ] + ] + | None, + Field(alias='pricingInfos'), + ] = None + categories: list[str] | None = None + default_run_options: Annotated[DefaultRunOptions | None, Field(alias='defaultRunOptions')] = None + tagged_builds: Annotated[ + dict[str, Any] | None, + Field(alias='taggedBuilds', examples=[{'latest': {'buildId': 'z2EryhbfhgSyqj6Hn'}, 'beta': None}]), + ] = None + """ + An object to modify tags on the Actor's builds. The key is the tag name (e.g., _latest_), and the value is either an object with a `buildId` or `null`. + + This operation is a patch; any existing tags that you omit from this object will be preserved. + + - **To create or reassign a tag**, provide the tag name with a `buildId`. e.g., to assign the _latest_ tag: + +   + + ```json + { + "latest": { + "buildId": "z2EryhbfhgSyqj6Hn" + } + } + ``` + + - **To remove a tag**, provide the tag name with a `null` value. e.g., to remove the _beta_ tag: + +   + + ```json + { + "beta": null + } + ``` + + - **To perform multiple operations**, combine them. The following reassigns _latest_ and removes _beta_, while preserving any other existing tags. + +   + + ```json + { + "latest": { + "buildId": "z2EryhbfhgSyqj6Hn" + }, + "beta": null + } + ``` + + """ + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + example_run_input: Annotated[ExampleRunInput | None, Field(alias='exampleRunInput')] = None + is_deprecated: Annotated[bool | None, Field(alias='isDeprecated')] = None + + +@docs_group('Models') +class UpdateDatasetRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: str | None = None + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + + +@docs_group('Models') +class UpdateLimitsRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + max_monthly_usage_usd: Annotated[float | None, Field(alias='maxMonthlyUsageUsd', examples=[300])] = None + """ + If your platform usage in the billing period exceeds the prepaid usage, you will be charged extra. Setting this property you can update your hard limit on monthly platform usage to prevent accidental overage or to limit the extra charges. + + """ + data_retention_days: Annotated[int | None, Field(alias='dataRetentionDays', examples=[90])] = None + """ + Apify securely stores your ten most recent Actor runs indefinitely, ensuring they are always accessible. Unnamed storages and other Actor runs are automatically deleted after the retention period. If you're subscribed, you can change it to keep data for longer or to limit your usage. [Lear more](https://docs.apify.com/platform/storage/usage#data-retention). + + """ + + +@docs_group('Models') +class UpdateRequestQueueRequest(BaseModel): + """Request object for updating a request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: str | None = None + """ + The new name for the request queue. + """ + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + + +@docs_group('Models') +class UpdateRequestResponse(BaseModel): + """Response containing the result of updating a request in the request queue.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: RequestRegistration + + +@docs_group('Models') +class UpdateRunRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + run_id: Annotated[str | None, Field(alias='runId', examples=['3KH8gEpp4d8uQSe8T'])] = None + status_message: Annotated[str | None, Field(alias='statusMessage', examples=['Actor has finished'])] = None + is_status_message_terminal: Annotated[bool | None, Field(alias='isStatusMessageTerminal', examples=[True])] = None + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + + +@docs_group('Models') +class UpdateStoreRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: str | None = None + general_access: Annotated[GeneralAccess | None, Field(alias='generalAccess')] = None + + +@docs_group('Models') +class UpdateTaskRequest(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + name: Annotated[str | None, Field(examples=['my-task'])] = None + options: TaskOptions | None = None + input: TaskInput | None = None + title: str | None = None + actor_standby: Annotated[ActorStandby | None, Field(alias='actorStandby')] = None + + +@docs_group('Models') +class UsageCycle(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + start_at: Annotated[AwareDatetime, Field(alias='startAt', examples=['2022-10-02T00:00:00.000Z'])] + end_at: Annotated[AwareDatetime, Field(alias='endAt', examples=['2022-11-01T23:59:59.999Z'])] + + +@docs_group('Models') +class UsageItem(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + quantity: Annotated[float, Field(examples=[2.784475])] + base_amount_usd: Annotated[float, Field(alias='baseAmountUsd', examples=[0.69611875])] + base_unit_price_usd: Annotated[float | None, Field(alias='baseUnitPriceUsd', examples=[0.25])] = None + amount_after_volume_discount_usd: Annotated[ + float | None, Field(alias='amountAfterVolumeDiscountUsd', examples=[0.69611875]) + ] = None + price_tiers: Annotated[list[PriceTiers] | None, Field(alias='priceTiers')] = None + + +@docs_group('Models') +class UserPrivateInfo(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] + username: Annotated[str, Field(examples=['myusername'])] + profile: Profile + email: Annotated[EmailStr, Field(examples=['bob@example.com'])] + proxy: Proxy + plan: Plan + effective_platform_features: Annotated[EffectivePlatformFeatures, Field(alias='effectivePlatformFeatures')] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2022-11-29T14:48:29.381Z'])] + is_paying: Annotated[bool, Field(alias='isPaying', examples=[True])] + + +@docs_group('Models') +class UserPublicInfo(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + username: Annotated[str, Field(examples=['d7b9MDYsbtX5L7XAj'])] + profile: Profile | None = None + + +@docs_group('Models') +class ValidationError(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + instance_path: Annotated[str | None, Field(alias='instancePath')] = None + """ + The path to the instance being validated. + """ + schema_path: Annotated[str | None, Field(alias='schemaPath')] = None + """ + The path to the schema that failed the validation. + """ + keyword: str | None = None + """ + The validation keyword that caused the error. + """ + message: str | None = None + """ + A message describing the validation error. + """ + params: dict[str, Any] | None = None + """ + Additional parameters specific to the validation error. + """ + + +@docs_group('Models') +class Version(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + version_number: Annotated[str, Field(alias='versionNumber', examples=['0.0'])] + source_type: Annotated[VersionSourceType | None, Field(alias='sourceType')] + env_vars: Annotated[list[EnvVar] | None, Field(alias='envVars')] = None + apply_env_vars_to_build: Annotated[bool | None, Field(alias='applyEnvVarsToBuild', examples=[False])] = None + build_tag: Annotated[str | None, Field(alias='buildTag', examples=['latest'])] = None + source_files: Annotated[ + list[SourceCodeFile | SourceCodeFolder] | None, Field(alias='sourceFiles', title='VersionSourceFiles') + ] = None + git_repo_url: Annotated[str | None, Field(alias='gitRepoUrl')] = None + """ + URL of the Git repository when sourceType is GIT_REPO. + """ + tarball_url: Annotated[str | None, Field(alias='tarballUrl')] = None + """ + URL of the tarball when sourceType is TARBALL. + """ + github_gist_url: Annotated[str | None, Field(alias='gitHubGistUrl')] = None + """ + URL of the GitHub Gist when sourceType is GITHUB_GIST. + """ + + +@docs_group('Models') +class VersionResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Version + + +@docs_group('Models') +class VersionSourceType(StrEnum): + SOURCE_FILES = 'SOURCE_FILES' + GIT_REPO = 'GIT_REPO' + TARBALL = 'TARBALL' + GITHUB_GIST = 'GITHUB_GIST' + + +@docs_group('Models') +class Webhook(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None + should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None + event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] + condition: WebhookCondition + ignore_ssl_errors: Annotated[bool, Field(alias='ignoreSslErrors', examples=[False])] + do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None + request_url: Annotated[AnyUrl, Field(alias='requestUrl', examples=['http://example.com/'])] + payload_template: Annotated[ + str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) + ] = None + headers_template: Annotated[ + str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) + ] = None + description: Annotated[str | None, Field(examples=['this is webhook description'])] = None + last_dispatch: Annotated[ExampleWebhookDispatch | None, Field(alias='lastDispatch')] = None + stats: WebhookStats | None = None + + +@docs_group('Models') +class WebhookCondition(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + actor_id: Annotated[str | None, Field(alias='actorId', examples=['hksJZtadYvn4mBuin'])] = None + actor_task_id: Annotated[str | None, Field(alias='actorTaskId', examples=['asdLZtadYvn4mBZmm'])] = None + actor_run_id: Annotated[str | None, Field(alias='actorRunId', examples=['hgdKZtadYvn4mBpoi'])] = None + + +@docs_group('Models') +class WebhookCreate(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None + event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] + condition: WebhookCondition + idempotency_key: Annotated[str | None, Field(alias='idempotencyKey', examples=['fdSJmdP3nfs7sfk3y'])] = None + ignore_ssl_errors: Annotated[bool | None, Field(alias='ignoreSslErrors', examples=[False])] = None + do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None + request_url: Annotated[str, Field(alias='requestUrl', examples=['http://example.com/'])] + payload_template: Annotated[ + str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) + ] = None + headers_template: Annotated[ + str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) + ] = None + description: Annotated[str | None, Field(examples=['this is webhook description'])] = None + should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None + + +@docs_group('Models') +class WebhookDispatch(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['asdLZtadYvn4mBZmm'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + webhook_id: Annotated[str, Field(alias='webhookId', examples=['asdLZtadYvn4mBZmm'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + status: WebhookDispatchStatus + event_type: Annotated[WebhookEventType, Field(alias='eventType')] + event_data: Annotated[EventData | None, Field(alias='eventData', title='eventData')] = None + calls: Annotated[list[Call] | None, Field(title='calls')] = None + + +@docs_group('Models') +class WebhookDispatchList(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: ListOfWebhookDispatches | None = None + + +@docs_group('Models') +class WebhookDispatchResponse(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: WebhookDispatch + + +@docs_group('Models') +class WebhookDispatchStatus(StrEnum): + """Status of the webhook dispatch indicating whether the HTTP request was successful.""" + + ACTIVE = 'ACTIVE' + SUCCEEDED = 'SUCCEEDED' + FAILED = 'FAILED' + + +@docs_group('Models') +class WebhookEventType(StrEnum): + """Type of event that triggers the webhook.""" + + ACTOR_BUILD_ABORTED = 'ACTOR.BUILD.ABORTED' + ACTOR_BUILD_CREATED = 'ACTOR.BUILD.CREATED' + ACTOR_BUILD_FAILED = 'ACTOR.BUILD.FAILED' + ACTOR_BUILD_SUCCEEDED = 'ACTOR.BUILD.SUCCEEDED' + ACTOR_BUILD_TIMED_OUT = 'ACTOR.BUILD.TIMED_OUT' + ACTOR_RUN_ABORTED = 'ACTOR.RUN.ABORTED' + ACTOR_RUN_CREATED = 'ACTOR.RUN.CREATED' + ACTOR_RUN_FAILED = 'ACTOR.RUN.FAILED' + ACTOR_RUN_RESURRECTED = 'ACTOR.RUN.RESURRECTED' + ACTOR_RUN_SUCCEEDED = 'ACTOR.RUN.SUCCEEDED' + ACTOR_RUN_TIMED_OUT = 'ACTOR.RUN.TIMED_OUT' + TEST = 'TEST' + + +@docs_group('Models') +class WebhookResponse(BaseModel): + """Response containing webhook data.""" + + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + data: Webhook + + +@docs_group('Models') +class WebhookShort(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + id: Annotated[str, Field(examples=['YiKoxjkaS9gjGTqhF'])] + created_at: Annotated[AwareDatetime, Field(alias='createdAt', examples=['2019-12-12T07:34:14.202Z'])] + modified_at: Annotated[AwareDatetime, Field(alias='modifiedAt', examples=['2019-12-13T08:36:13.202Z'])] + user_id: Annotated[str, Field(alias='userId', examples=['wRsJZtadYvn4mBZmm'])] + is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None + should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None + event_types: Annotated[list[WebhookEventType], Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']])] + condition: WebhookCondition + ignore_ssl_errors: Annotated[bool, Field(alias='ignoreSslErrors', examples=[False])] + do_not_retry: Annotated[bool, Field(alias='doNotRetry', examples=[False])] + request_url: Annotated[AnyUrl, Field(alias='requestUrl', examples=['http://example.com/'])] + last_dispatch: Annotated[ExampleWebhookDispatch | None, Field(alias='lastDispatch')] = None + stats: WebhookStats | None = None + + +@docs_group('Models') +class WebhookStats(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + total_dispatches: Annotated[int, Field(alias='totalDispatches', examples=[1])] + + +@docs_group('Models') +class WebhookUpdate(BaseModel): + model_config = ConfigDict( + extra='allow', + populate_by_name=True, + ) + is_ad_hoc: Annotated[bool | None, Field(alias='isAdHoc', examples=[False])] = None + event_types: Annotated[ + list[WebhookEventType] | None, Field(alias='eventTypes', examples=[['ACTOR.RUN.SUCCEEDED']]) + ] = None + condition: WebhookCondition | None = None + ignore_ssl_errors: Annotated[bool | None, Field(alias='ignoreSslErrors', examples=[False])] = None + do_not_retry: Annotated[bool | None, Field(alias='doNotRetry', examples=[False])] = None + request_url: Annotated[AnyUrl | None, Field(alias='requestUrl', examples=['http://example.com/'])] = None + payload_template: Annotated[ + str | None, Field(alias='payloadTemplate', examples=['{\\n "userId": {{userId}}...']) + ] = None + headers_template: Annotated[ + str | None, Field(alias='headersTemplate', examples=['{\\n "Authorization": "Bearer ..."}']) + ] = None + description: Annotated[str | None, Field(examples=['this is webhook description'])] = None + should_interpolate_strings: Annotated[bool | None, Field(alias='shouldInterpolateStrings', examples=[False])] = None diff --git a/src/apify_client/_resource_clients/_resource_client.py b/src/apify_client/_resource_clients/_resource_client.py index df72207d..7a2f84bf 100644 --- a/src/apify_client/_resource_clients/_resource_client.py +++ b/src/apify_client/_resource_clients/_resource_client.py @@ -9,7 +9,7 @@ from apify_client._consts import DEFAULT_WAIT_FOR_FINISH, DEFAULT_WAIT_WHEN_JOB_NOT_EXIST, TERMINAL_STATUSES from apify_client._docs import docs_group from apify_client._logging import WithLogDetailsClient -from apify_client._types import ActorJobResponse +from apify_client._models import ActorJobResponse from apify_client._utils import ( catch_not_found_for_resource_or_throw, catch_not_found_or_throw, diff --git a/src/apify_client/_resource_clients/actor.py b/src/apify_client/_resource_clients/actor.py index 889dfdee..c4463427 100644 --- a/src/apify_client/_resource_clients/actor.py +++ b/src/apify_client/_resource_clients/actor.py @@ -5,7 +5,8 @@ from pydantic import TypeAdapter from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models import WebhookRepresentationList +from apify_client._models_generated import ( Actor, ActorPermissionLevel, ActorResponse, @@ -23,10 +24,8 @@ RunOrigin, RunResponse, UpdateActorRequest, - WebhookCreate, ) from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync -from apify_client._types import WebhookRepresentationList from apify_client._utils import encode_key_value_store_record_value, response_to_dict, to_seconds if TYPE_CHECKING: @@ -34,6 +33,7 @@ from decimal import Decimal from logging import Logger + from apify_client._models_generated import ActorJobStatus from apify_client._resource_clients import ( ActorVersionClient, ActorVersionClientAsync, @@ -50,7 +50,7 @@ WebhookCollectionClient, WebhookCollectionClientAsync, ) - from apify_client._types import ActorJobStatus, Timeout + from apify_client._types import Timeout, WebhooksList _PricingInfo = ( PayPerEventActorPricingInfo @@ -229,7 +229,7 @@ def start( run_timeout: timedelta | None = None, force_permission_level: ActorPermissionLevel | None = None, wait_for_finish: int | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, timeout: Timeout = 'medium', ) -> Run: """Start the Actor and immediately return the Run object. @@ -303,7 +303,7 @@ def call( restart_on_error: bool | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, force_permission_level: ActorPermissionLevel | None = None, wait_duration: timedelta | None = None, logger: Logger | None | Literal['default'] = 'default', @@ -725,7 +725,7 @@ async def start( run_timeout: timedelta | None = None, force_permission_level: ActorPermissionLevel | None = None, wait_for_finish: int | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, timeout: Timeout = 'medium', ) -> Run: """Start the Actor and immediately return the Run object. @@ -799,7 +799,7 @@ async def call( restart_on_error: bool | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, force_permission_level: ActorPermissionLevel | None = None, wait_duration: timedelta | None = None, logger: Logger | None | Literal['default'] = 'default', diff --git a/src/apify_client/_resource_clients/actor_collection.py b/src/apify_client/_resource_clients/actor_collection.py index 21f8b19b..63a780df 100644 --- a/src/apify_client/_resource_clients/actor_collection.py +++ b/src/apify_client/_resource_clients/actor_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any, Literal from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( Actor, ActorResponse, ActorStandby, diff --git a/src/apify_client/_resource_clients/actor_env_var.py b/src/apify_client/_resource_clients/actor_env_var.py index 58e0ac8b..ffb3b571 100644 --- a/src/apify_client/_resource_clients/actor_env_var.py +++ b/src/apify_client/_resource_clients/actor_env_var.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import EnvVar, EnvVarResponse +from apify_client._models_generated import EnvVar, EnvVarResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/actor_env_var_collection.py b/src/apify_client/_resource_clients/actor_env_var_collection.py index 788745b4..d4eb2af5 100644 --- a/src/apify_client/_resource_clients/actor_env_var_collection.py +++ b/src/apify_client/_resource_clients/actor_env_var_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import EnvVar, EnvVarResponse, ListOfEnvVars, ListOfEnvVarsResponse +from apify_client._models_generated import EnvVar, EnvVarResponse, ListOfEnvVars, ListOfEnvVarsResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/actor_version.py b/src/apify_client/_resource_clients/actor_version.py index ba34454d..825803e4 100644 --- a/src/apify_client/_resource_clients/actor_version.py +++ b/src/apify_client/_resource_clients/actor_version.py @@ -5,7 +5,7 @@ from pydantic import TypeAdapter from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( CreateOrUpdateVersionRequest, EnvVarRequest, SourceCodeFile, diff --git a/src/apify_client/_resource_clients/actor_version_collection.py b/src/apify_client/_resource_clients/actor_version_collection.py index a6239f26..aac5e4c3 100644 --- a/src/apify_client/_resource_clients/actor_version_collection.py +++ b/src/apify_client/_resource_clients/actor_version_collection.py @@ -5,7 +5,7 @@ from pydantic import TypeAdapter from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( CreateOrUpdateVersionRequest, EnvVarRequest, ListOfVersions, diff --git a/src/apify_client/_resource_clients/build.py b/src/apify_client/_resource_clients/build.py index 1ae73de1..9b255351 100644 --- a/src/apify_client/_resource_clients/build.py +++ b/src/apify_client/_resource_clients/build.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import Build, BuildResponse +from apify_client._models_generated import Build, BuildResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync from apify_client._utils import response_to_dict diff --git a/src/apify_client/_resource_clients/build_collection.py b/src/apify_client/_resource_clients/build_collection.py index a55ee6c2..6ead2a67 100644 --- a/src/apify_client/_resource_clients/build_collection.py +++ b/src/apify_client/_resource_clients/build_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ListOfBuilds, ListOfBuildsResponse +from apify_client._models_generated import ListOfBuilds, ListOfBuildsResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/dataset.py b/src/apify_client/_resource_clients/dataset.py index 378bd6eb..1ae7e945 100644 --- a/src/apify_client/_resource_clients/dataset.py +++ b/src/apify_client/_resource_clients/dataset.py @@ -7,7 +7,7 @@ from urllib.parse import urlencode, urlparse, urlunparse from apify_client._docs import docs_group -from apify_client._models import Dataset, DatasetResponse, DatasetStatistics, DatasetStatisticsResponse +from apify_client._models_generated import Dataset, DatasetResponse, DatasetStatistics, DatasetStatisticsResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync from apify_client._utils import ( create_storage_content_signature, @@ -20,7 +20,7 @@ from datetime import timedelta from apify_client._http_clients import HttpResponse - from apify_client._models import GeneralAccess + from apify_client._models_generated import GeneralAccess from apify_client._types import JsonSerializable, Timeout diff --git a/src/apify_client/_resource_clients/dataset_collection.py b/src/apify_client/_resource_clients/dataset_collection.py index 698fa31e..2ffb71d6 100644 --- a/src/apify_client/_resource_clients/dataset_collection.py +++ b/src/apify_client/_resource_clients/dataset_collection.py @@ -3,7 +3,13 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import Dataset, DatasetResponse, ListOfDatasets, ListOfDatasetsResponse, StorageOwnership +from apify_client._models_generated import ( + Dataset, + DatasetResponse, + ListOfDatasets, + ListOfDatasetsResponse, + StorageOwnership, +) from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/key_value_store.py b/src/apify_client/_resource_clients/key_value_store.py index 2c099bca..6c388b49 100644 --- a/src/apify_client/_resource_clients/key_value_store.py +++ b/src/apify_client/_resource_clients/key_value_store.py @@ -7,7 +7,7 @@ from urllib.parse import urlencode, urlparse, urlunparse from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( KeyValueStore, KeyValueStoreKey, KeyValueStoreResponse, @@ -29,7 +29,7 @@ from datetime import timedelta from apify_client._http_clients import HttpResponse - from apify_client._models import GeneralAccess + from apify_client._models_generated import GeneralAccess from apify_client._types import Timeout diff --git a/src/apify_client/_resource_clients/key_value_store_collection.py b/src/apify_client/_resource_clients/key_value_store_collection.py index 0b792360..f221a192 100644 --- a/src/apify_client/_resource_clients/key_value_store_collection.py +++ b/src/apify_client/_resource_clients/key_value_store_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( KeyValueStore, KeyValueStoreResponse, ListOfKeyValueStores, diff --git a/src/apify_client/_resource_clients/request_queue.py b/src/apify_client/_resource_clients/request_queue.py index 784792fd..90aa746d 100644 --- a/src/apify_client/_resource_clients/request_queue.py +++ b/src/apify_client/_resource_clients/request_queue.py @@ -10,7 +10,8 @@ from more_itertools import constrained_batches from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models import RequestDeleteInput, RequestInput +from apify_client._models_generated import ( AddedRequest, AddRequestResponse, BatchAddResponse, @@ -35,14 +36,15 @@ UnlockRequestsResult, ) from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync -from apify_client._types import RequestDeleteInput, RequestInput from apify_client._utils import catch_not_found_or_throw, response_to_dict, to_seconds from apify_client.errors import ApifyApiError if TYPE_CHECKING: from datetime import timedelta - from apify_client._models import GeneralAccess + from apify_client._models_generated import GeneralAccess + from apify_client._typeddicts import RequestDeleteInputDict, RequestInputDict + from apify_client._typeddicts_generated import RequestDict from apify_client._types import Timeout _RQ_MAX_REQUESTS_PER_BATCH = 25 @@ -187,7 +189,7 @@ def list_and_lock_head( def add_request( self, - request: dict | RequestInput, + request: RequestInputDict | RequestInput, *, forefront: bool | None = None, timeout: Timeout = 'short', @@ -204,7 +206,7 @@ def add_request( Returns: The added request. """ - if isinstance(request, dict): + if not isinstance(request, RequestInput): request = RequestInput.model_validate(request) request_params = self._build_params(forefront=forefront, clientKey=self.client_key) @@ -249,7 +251,7 @@ def get_request(self, request_id: str, *, timeout: Timeout = 'short') -> Request def update_request( self, - request: dict | Request, + request: RequestDict | Request, *, forefront: bool | None = None, timeout: Timeout = 'medium', @@ -266,7 +268,7 @@ def update_request( Returns: The updated request. """ - if isinstance(request, dict): + if not isinstance(request, Request): request = Request.model_validate(request) request_params = self._build_params(forefront=forefront, clientKey=self.client_key) @@ -363,7 +365,7 @@ def delete_request_lock( def batch_add_requests( self, - requests: list[RequestInput] | list[dict], + requests: list[RequestInput] | list[RequestInputDict], *, forefront: bool = False, max_parallel: int = 1, @@ -407,7 +409,9 @@ def batch_add_requests( raise NotImplementedError('max_parallel is only supported in async client') requests_as_dicts = [ - (RequestInput.model_validate(r) if isinstance(r, dict) else r).model_dump(by_alias=True, exclude_none=True) + (r if isinstance(r, RequestInput) else RequestInput.model_validate(r)).model_dump( + by_alias=True, exclude_none=True + ) for r in requests ] @@ -459,7 +463,7 @@ def batch_add_requests( def batch_delete_requests( self, - requests: list[RequestDeleteInput] | list[dict], + requests: list[RequestDeleteInput] | list[RequestDeleteInputDict], *, timeout: Timeout = 'short', ) -> BatchDeleteResult: @@ -472,7 +476,7 @@ def batch_delete_requests( timeout: Timeout for the API HTTP request. """ requests_as_dicts = [ - (RequestDeleteInput.model_validate(r) if isinstance(r, dict) else r).model_dump( + (r if isinstance(r, RequestDeleteInput) else RequestDeleteInput.model_validate(r)).model_dump( by_alias=True, exclude_none=True ) for r in requests @@ -700,7 +704,7 @@ async def list_and_lock_head( async def add_request( self, - request: dict | RequestInput, + request: RequestInputDict | RequestInput, *, forefront: bool | None = None, timeout: Timeout = 'short', @@ -717,7 +721,7 @@ async def add_request( Returns: The added request. """ - if isinstance(request, dict): + if not isinstance(request, RequestInput): request = RequestInput.model_validate(request) request_params = self._build_params(forefront=forefront, clientKey=self.client_key) @@ -760,7 +764,7 @@ async def get_request(self, request_id: str, *, timeout: Timeout = 'short') -> R async def update_request( self, - request: dict | Request, + request: RequestDict | Request, *, forefront: bool | None = None, timeout: Timeout = 'medium', @@ -777,7 +781,7 @@ async def update_request( Returns: The updated request. """ - if isinstance(request, dict): + if not isinstance(request, Request): request = Request.model_validate(request) request_params = self._build_params(forefront=forefront, clientKey=self.client_key) @@ -920,7 +924,7 @@ async def _batch_add_requests_worker( async def batch_add_requests( self, - requests: list[RequestInput] | list[dict], + requests: list[RequestInput] | list[RequestInputDict], *, forefront: bool = False, max_parallel: int = 5, @@ -961,7 +965,9 @@ async def batch_add_requests( ) requests_as_dicts = [ - (RequestInput.model_validate(r) if isinstance(r, dict) else r).model_dump(by_alias=True, exclude_none=True) + (r if isinstance(r, RequestInput) else RequestInput.model_validate(r)).model_dump( + by_alias=True, exclude_none=True + ) for r in requests ] @@ -1018,7 +1024,7 @@ async def batch_add_requests( async def batch_delete_requests( self, - requests: list[RequestDeleteInput] | list[dict], + requests: list[RequestDeleteInput] | list[RequestDeleteInputDict], *, timeout: Timeout = 'short', ) -> BatchDeleteResult: @@ -1031,7 +1037,7 @@ async def batch_delete_requests( timeout: Timeout for the API HTTP request. """ requests_as_dicts = [ - (RequestDeleteInput.model_validate(r) if isinstance(r, dict) else r).model_dump( + (r if isinstance(r, RequestDeleteInput) else RequestDeleteInput.model_validate(r)).model_dump( by_alias=True, exclude_none=True ) for r in requests diff --git a/src/apify_client/_resource_clients/request_queue_collection.py b/src/apify_client/_resource_clients/request_queue_collection.py index c328303a..1d06fcbc 100644 --- a/src/apify_client/_resource_clients/request_queue_collection.py +++ b/src/apify_client/_resource_clients/request_queue_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( ListOfRequestQueues, ListOfRequestQueuesResponse, RequestQueue, diff --git a/src/apify_client/_resource_clients/run.py b/src/apify_client/_resource_clients/run.py index 9f8a69c4..1d0dc49d 100644 --- a/src/apify_client/_resource_clients/run.py +++ b/src/apify_client/_resource_clients/run.py @@ -9,7 +9,7 @@ from apify_client._docs import docs_group from apify_client._logging import create_redirect_logger -from apify_client._models import Run, RunResponse +from apify_client._models_generated import Run, RunResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync from apify_client._status_message_watcher import StatusMessageWatcher, StatusMessageWatcherAsync from apify_client._streamed_log import StreamedLog, StreamedLogAsync @@ -19,7 +19,7 @@ import logging from decimal import Decimal - from apify_client._models import GeneralAccess + from apify_client._models_generated import GeneralAccess from apify_client._resource_clients import ( DatasetClient, DatasetClientAsync, diff --git a/src/apify_client/_resource_clients/run_collection.py b/src/apify_client/_resource_clients/run_collection.py index be68121e..b63b3fc9 100644 --- a/src/apify_client/_resource_clients/run_collection.py +++ b/src/apify_client/_resource_clients/run_collection.py @@ -3,13 +3,14 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ListOfRuns, ListOfRunsResponse +from apify_client._models_generated import ListOfRuns, ListOfRunsResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: from datetime import datetime - from apify_client._types import ActorJobStatus, Timeout + from apify_client._models_generated import ActorJobStatus + from apify_client._types import Timeout @docs_group('Resource clients') diff --git a/src/apify_client/_resource_clients/schedule.py b/src/apify_client/_resource_clients/schedule.py index 8eee629b..a3cd192f 100644 --- a/src/apify_client/_resource_clients/schedule.py +++ b/src/apify_client/_resource_clients/schedule.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( Schedule, ScheduleCreate, ScheduleInvoked, diff --git a/src/apify_client/_resource_clients/schedule_collection.py b/src/apify_client/_resource_clients/schedule_collection.py index 94725724..1421d257 100644 --- a/src/apify_client/_resource_clients/schedule_collection.py +++ b/src/apify_client/_resource_clients/schedule_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( ListOfSchedules, ListOfSchedulesResponse, Schedule, diff --git a/src/apify_client/_resource_clients/store_collection.py b/src/apify_client/_resource_clients/store_collection.py index ca6b0921..9c80ad31 100644 --- a/src/apify_client/_resource_clients/store_collection.py +++ b/src/apify_client/_resource_clients/store_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ListOfActorsInStoreResponse, ListOfStoreActors +from apify_client._models_generated import ListOfActorsInStoreResponse, ListOfStoreActors from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/task.py b/src/apify_client/_resource_clients/task.py index 17920fbd..77479b10 100644 --- a/src/apify_client/_resource_clients/task.py +++ b/src/apify_client/_resource_clients/task.py @@ -3,7 +3,8 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models import WebhookRepresentationList +from apify_client._models_generated import ( ActorStandby, Run, RunOrigin, @@ -13,15 +14,14 @@ TaskOptions, TaskResponse, UpdateTaskRequest, - WebhookCreate, ) from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync -from apify_client._types import WebhookRepresentationList from apify_client._utils import response_to_dict, to_seconds if TYPE_CHECKING: from datetime import timedelta + from apify_client._models_generated import ActorJobStatus from apify_client._resource_clients import ( RunClient, RunClientAsync, @@ -30,7 +30,8 @@ WebhookCollectionClient, WebhookCollectionClientAsync, ) - from apify_client._types import ActorJobStatus, Timeout + from apify_client._typeddicts_generated import TaskInputDict + from apify_client._types import Timeout, WebhooksList @docs_group('Resource clients') @@ -70,7 +71,7 @@ def update( self, *, name: str | None = None, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, @@ -115,7 +116,7 @@ def update( Returns: The updated task. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) task_fields = UpdateTaskRequest( @@ -153,14 +154,14 @@ def delete(self, *, timeout: Timeout = 'short') -> None: def start( self, *, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, restart_on_error: bool | None = None, wait_for_finish: int | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, timeout: Timeout = 'medium', ) -> Run: """Start the task and immediately return the Run object. @@ -193,7 +194,7 @@ def start( Returns: The run object. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) request_params = self._build_params( @@ -221,13 +222,13 @@ def start( def call( self, *, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, restart_on_error: bool | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, wait_duration: timedelta | None = None, timeout: Timeout = 'no_timeout', ) -> Run | None: @@ -301,7 +302,7 @@ def get_input(self, *, timeout: Timeout = 'short') -> dict: ) return response_to_dict(response) - def update_input(self, *, task_input: dict | TaskInput, timeout: Timeout = 'short') -> dict: + def update_input(self, *, task_input: TaskInputDict | TaskInput, timeout: Timeout = 'short') -> dict: """Update the default input for this task. https://docs.apify.com/api/v2#/reference/actor-tasks/task-input-object/update-task-input @@ -313,7 +314,7 @@ def update_input(self, *, task_input: dict | TaskInput, timeout: Timeout = 'shor Returns: The updated task input. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) response = self._http_client.call( @@ -393,7 +394,7 @@ async def update( self, *, name: str | None = None, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, @@ -438,7 +439,7 @@ async def update( Returns: The updated task. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) task_fields = UpdateTaskRequest( @@ -476,14 +477,14 @@ async def delete(self, *, timeout: Timeout = 'short') -> None: async def start( self, *, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, restart_on_error: bool | None = None, wait_for_finish: int | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, timeout: Timeout = 'medium', ) -> Run: """Start the task and immediately return the Run object. @@ -516,7 +517,7 @@ async def start( Returns: The run object. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) request_params = self._build_params( @@ -544,13 +545,13 @@ async def start( async def call( self, *, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, build: str | None = None, max_items: int | None = None, memory_mbytes: int | None = None, run_timeout: timedelta | None = None, restart_on_error: bool | None = None, - webhooks: list[WebhookCreate] | list[dict] | None = None, + webhooks: WebhooksList | None = None, wait_duration: timedelta | None = None, timeout: Timeout = 'no_timeout', ) -> Run | None: @@ -623,7 +624,7 @@ async def get_input(self, *, timeout: Timeout = 'short') -> dict: ) return response_to_dict(response) - async def update_input(self, *, task_input: dict | TaskInput, timeout: Timeout = 'short') -> dict: + async def update_input(self, *, task_input: TaskInputDict | TaskInput, timeout: Timeout = 'short') -> dict: """Update the default input for this task. https://docs.apify.com/api/v2#/reference/actor-tasks/task-input-object/update-task-input @@ -635,7 +636,7 @@ async def update_input(self, *, task_input: dict | TaskInput, timeout: Timeout = Returns: The updated task input. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) response = await self._http_client.call( diff --git a/src/apify_client/_resource_clients/task_collection.py b/src/apify_client/_resource_clients/task_collection.py index cca56bf1..44c46c9b 100644 --- a/src/apify_client/_resource_clients/task_collection.py +++ b/src/apify_client/_resource_clients/task_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( ActorStandby, CreateTaskRequest, ListOfTasks, @@ -19,6 +19,7 @@ if TYPE_CHECKING: from datetime import timedelta + from apify_client._typeddicts_generated import TaskInputDict from apify_client._types import Timeout @@ -75,7 +76,7 @@ def create( memory_mbytes: int | None = None, max_items: int | None = None, restart_on_error: bool | None = None, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, title: str | None = None, actor_standby_desired_requests_per_actor_run: int | None = None, actor_standby_max_requests_per_actor_run: int | None = None, @@ -116,7 +117,7 @@ def create( Returns: The created task. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) task_fields = CreateTaskRequest( @@ -196,7 +197,7 @@ async def create( memory_mbytes: int | None = None, max_items: int | None = None, restart_on_error: bool | None = None, - task_input: dict | TaskInput | None = None, + task_input: TaskInputDict | TaskInput | None = None, title: str | None = None, actor_standby_desired_requests_per_actor_run: int | None = None, actor_standby_max_requests_per_actor_run: int | None = None, @@ -237,7 +238,7 @@ async def create( Returns: The created task. """ - if isinstance(task_input, dict): + if task_input is not None and not isinstance(task_input, TaskInput): task_input = TaskInput.model_validate(task_input) task_fields = CreateTaskRequest( diff --git a/src/apify_client/_resource_clients/user.py b/src/apify_client/_resource_clients/user.py index 6703000f..18325671 100644 --- a/src/apify_client/_resource_clients/user.py +++ b/src/apify_client/_resource_clients/user.py @@ -5,7 +5,7 @@ from pydantic import ValidationError from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( AccountLimits, LimitsResponse, MonthlyUsage, diff --git a/src/apify_client/_resource_clients/webhook.py b/src/apify_client/_resource_clients/webhook.py index 171364b6..a22b0064 100644 --- a/src/apify_client/_resource_clients/webhook.py +++ b/src/apify_client/_resource_clients/webhook.py @@ -5,7 +5,7 @@ from pydantic import AnyUrl from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( TestWebhookResponse, Webhook, WebhookCondition, @@ -17,7 +17,7 @@ from apify_client._utils import response_to_dict if TYPE_CHECKING: - from apify_client._models import WebhookEventType + from apify_client._models_generated import WebhookEventType from apify_client._resource_clients import WebhookDispatchCollectionClient, WebhookDispatchCollectionClientAsync from apify_client._types import Timeout diff --git a/src/apify_client/_resource_clients/webhook_collection.py b/src/apify_client/_resource_clients/webhook_collection.py index d1c579f9..12834ce1 100644 --- a/src/apify_client/_resource_clients/webhook_collection.py +++ b/src/apify_client/_resource_clients/webhook_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ( +from apify_client._models_generated import ( ListOfWebhooks, ListOfWebhooksResponse, WebhookCondition, @@ -13,7 +13,7 @@ from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: - from apify_client._models import Webhook, WebhookEventType + from apify_client._models_generated import Webhook, WebhookEventType from apify_client._types import Timeout diff --git a/src/apify_client/_resource_clients/webhook_dispatch.py b/src/apify_client/_resource_clients/webhook_dispatch.py index c94e965e..a8405a87 100644 --- a/src/apify_client/_resource_clients/webhook_dispatch.py +++ b/src/apify_client/_resource_clients/webhook_dispatch.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import WebhookDispatch, WebhookDispatchResponse +from apify_client._models_generated import WebhookDispatch, WebhookDispatchResponse from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_resource_clients/webhook_dispatch_collection.py b/src/apify_client/_resource_clients/webhook_dispatch_collection.py index 17d17a0d..dbea43aa 100644 --- a/src/apify_client/_resource_clients/webhook_dispatch_collection.py +++ b/src/apify_client/_resource_clients/webhook_dispatch_collection.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Any from apify_client._docs import docs_group -from apify_client._models import ListOfWebhookDispatches, WebhookDispatchList +from apify_client._models_generated import ListOfWebhookDispatches, WebhookDispatchList from apify_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync if TYPE_CHECKING: diff --git a/src/apify_client/_status_message_watcher.py b/src/apify_client/_status_message_watcher.py index d1ccd8d2..5bdac9e7 100644 --- a/src/apify_client/_status_message_watcher.py +++ b/src/apify_client/_status_message_watcher.py @@ -15,7 +15,7 @@ import logging from types import TracebackType - from apify_client._models import Run + from apify_client._models_generated import Run from apify_client._resource_clients import RunClient, RunClientAsync diff --git a/src/apify_client/_typeddicts.py b/src/apify_client/_typeddicts.py new file mode 100644 index 00000000..f17aac43 --- /dev/null +++ b/src/apify_client/_typeddicts.py @@ -0,0 +1,64 @@ +"""Hand-written TypedDicts for resource-client method inputs not exposed by the OpenAPI spec. + +Generated TypedDicts live in `apify_client._typeddicts_generated`; import from there directly. +""" + +from __future__ import annotations + +from typing import NotRequired, TypedDict + +from apify_client._docs import docs_group + + +@docs_group('Typed dicts') +class RequestInputDict(TypedDict): + """TypedDict counterpart of `RequestInput` for adding requests to a request queue.""" + + unique_key: str + """A unique key used for request de-duplication.""" + + url: str + """The URL of the request.""" + + id: NotRequired[str | None] + """A unique identifier assigned to the request.""" + + method: NotRequired[str | None] + """The HTTP method of the request. Defaults to `GET` on the API side if not provided.""" + + +@docs_group('Typed dicts') +class RequestDeleteInputDict(TypedDict): + """TypedDict counterpart of `RequestDeleteInput` for deleting requests from a request queue. + + The TypedDict cannot enforce "at least one of id/unique_key" — that check still happens at the Pydantic-model + level when dicts are validated at call time. + """ + + id: NotRequired[str | None] + """A unique identifier assigned to the request.""" + + unique_key: NotRequired[str | None] + """A unique key used for request de-duplication.""" + + +@docs_group('Typed dicts') +class WebhookRepresentationDict(TypedDict): + """TypedDict counterpart of `WebhookRepresentation` for ad-hoc webhooks. + + Captures the minimal shape the Apify API actually requires when attaching ad-hoc webhooks to a run: + only `event_types` and `request_url` are mandatory. Unlike `WebhookCreateDict`, there is no `condition` + field — the API does not use it for ad-hoc webhooks. + """ + + event_types: list[str] + """The list of Actor events that trigger this webhook.""" + + request_url: str + """The URL to which the webhook sends its payload.""" + + payload_template: NotRequired[str | None] + """Optional template for the JSON payload sent by the webhook.""" + + headers_template: NotRequired[str | None] + """Optional template for the HTTP headers sent by the webhook.""" diff --git a/src/apify_client/_typeddicts_generated.py b/src/apify_client/_typeddicts_generated.py new file mode 100644 index 00000000..5ece14a8 --- /dev/null +++ b/src/apify_client/_typeddicts_generated.py @@ -0,0 +1,102 @@ +# generated by datamodel-codegen + +from __future__ import annotations + +from typing import Any, Literal, NotRequired, TypeAlias, TypedDict + +from apify_client._docs import docs_group + + +@docs_group('Typed dicts') +class RequestBaseDict(TypedDict): + unique_key: NotRequired[str] + """ + A unique key used for request de-duplication. Requests with the same unique key are considered identical. + """ + url: NotRequired[str] + """ + The URL of the request. + """ + method: NotRequired[Literal['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']] + retry_count: NotRequired[int] + """ + The number of times this request has been retried. + """ + loaded_url: NotRequired[str | None] + """ + The final URL that was loaded, after redirects (if any). + """ + payload: NotRequired[str | dict[str, Any] | None] + """ + The request payload, typically used with POST or PUT requests. + """ + headers: NotRequired[dict[str, Any] | None] + """ + HTTP headers sent with the request. + """ + user_data: NotRequired[RequestUserDataDict] + no_retry: NotRequired[bool | None] + """ + Indicates whether the request should not be retried if processing fails. + """ + error_messages: NotRequired[list[str]] + """ + Error messages recorded from failed processing attempts. + """ + handled_at: NotRequired[str | None] + """ + The timestamp when the request was marked as handled, if applicable. + """ + + +@docs_group('Typed dicts') +class RequestDict(RequestBaseDict): + """A request stored in the request queue, including its metadata and processing state.""" + + id: NotRequired[str] + """ + A unique identifier assigned to the request. + """ + + +RequestUserDataDict: TypeAlias = dict[str, Any] + + +TaskInputDict: TypeAlias = dict[str, Any] + + +@docs_group('Typed dicts') +class WebhookConditionDict(TypedDict): + actor_id: NotRequired[str | None] + actor_task_id: NotRequired[str | None] + actor_run_id: NotRequired[str | None] + + +@docs_group('Typed dicts') +class WebhookCreateDict(TypedDict): + is_ad_hoc: NotRequired[bool | None] + event_types: list[ + Literal[ + 'ACTOR.BUILD.ABORTED', + 'ACTOR.BUILD.CREATED', + 'ACTOR.BUILD.FAILED', + 'ACTOR.BUILD.SUCCEEDED', + 'ACTOR.BUILD.TIMED_OUT', + 'ACTOR.RUN.ABORTED', + 'ACTOR.RUN.CREATED', + 'ACTOR.RUN.FAILED', + 'ACTOR.RUN.RESURRECTED', + 'ACTOR.RUN.SUCCEEDED', + 'ACTOR.RUN.TIMED_OUT', + 'TEST', + ] + ] + condition: WebhookConditionDict + idempotency_key: NotRequired[str | None] + ignore_ssl_errors: NotRequired[bool | None] + do_not_retry: NotRequired[bool | None] + request_url: str + payload_template: NotRequired[str | None] + headers_template: NotRequired[str | None] + description: NotRequired[str | None] + should_interpolate_strings: NotRequired[bool | None] diff --git a/src/apify_client/_types.py b/src/apify_client/_types.py index f9af89e6..d3a272e8 100644 --- a/src/apify_client/_types.py +++ b/src/apify_client/_types.py @@ -1,13 +1,23 @@ from __future__ import annotations -import json -from base64 import b64encode from datetime import timedelta -from typing import Annotated, Literal - -from pydantic import AnyUrl, BaseModel, ConfigDict, Field, RootModel, model_validator - -from apify_client._models import ActorJobStatus, WebhookCreate # noqa: TC001 +from typing import Literal + +from apify_client._models import WebhookRepresentation +from apify_client._models_generated import WebhookCreate +from apify_client._typeddicts import WebhookRepresentationDict +from apify_client._typeddicts_generated import WebhookCreateDict + +WebhooksList = ( + list[WebhookCreate] | list[WebhookCreateDict] | list[WebhookRepresentation] | list[WebhookRepresentationDict] +) +"""Type for the `webhooks` parameter on resource-client `start`/`call` methods and `from_webhooks`. + +`WebhookRepresentation` / `WebhookRepresentationDict` are the minimal ad-hoc webhook shape (only +`event_types` and `request_url` required). `WebhookCreate` / `WebhookCreateDict` are accepted so a +persistent-webhook definition can be reused; their fields not relevant to ad-hoc webhooks (e.g. +`condition`) are ignored at runtime. +""" Timeout = timedelta | Literal['no_timeout', 'short', 'medium', 'long'] """Type for the `timeout` parameter on resource client methods. @@ -21,127 +31,3 @@ Based on the definition discussed in https://github.com/python/typing/issues/182. """ - - -class ActorJob(BaseModel): - """Minimal model for an Actor job (run or build) with status. - - Used for validation during polling operations. Allows extra fields so the full response data is preserved. - """ - - model_config = ConfigDict(extra='allow', populate_by_name=True) - - status: ActorJobStatus - - -class ActorJobResponse(BaseModel): - """Response wrapper for an Actor job (run or build). - - Used for minimal validation during polling operations. Allows extra fields so the full response data is preserved. - """ - - model_config = ConfigDict(extra='allow', populate_by_name=True) - - data: ActorJob - - -class WebhookRepresentation(BaseModel): - """Representation of a webhook for base64-encoded API transmission. - - Contains only the fields needed for the webhook payload sent via query parameters. - """ - - model_config = ConfigDict(populate_by_name=True, extra='ignore') - - event_types: Annotated[list[str], Field(alias='eventTypes')] - request_url: Annotated[str, Field(alias='requestUrl')] - payload_template: Annotated[str | None, Field(alias='payloadTemplate')] = None - headers_template: Annotated[str | None, Field(alias='headersTemplate')] = None - - -class WebhookRepresentationList(RootModel[list[WebhookRepresentation]]): - """List of webhook representations with base64 encoding support.""" - - @classmethod - def from_webhooks(cls, webhooks: list[WebhookCreate] | list[dict]) -> WebhookRepresentationList: - """Construct from a list of `WebhookCreate` models or plain dicts. - - Dicts are validated directly as `WebhookRepresentation`, so only the minimal ad-hoc webhook fields - (`event_types`, `request_url`, and optionally `payload_template`/`headers_template`) are required. - """ - representations = list[WebhookRepresentation]() - - for webhook in webhooks: - if isinstance(webhook, dict): - representations.append(WebhookRepresentation.model_validate(webhook)) - else: - webhook_dict = webhook.model_dump(mode='json', exclude_none=True) - representations.append(WebhookRepresentation.model_validate(webhook_dict)) - - return cls(representations) - - def to_base64(self) -> str | None: - """Encode this list of webhook representations to a base64 string. - - Returns `None` if the list is empty, so that the query parameter is omitted. - """ - if not self.root: - return None - - data = [r.model_dump(by_alias=True, exclude_none=True) for r in self.root] - json_string = json.dumps(data).encode(encoding='utf-8') - return b64encode(json_string).decode(encoding='ascii') - - -class RequestInput(BaseModel): - """Input model for adding requests to a request queue. - - Both `url` and `unique_key` are required. The API defaults `method` to `GET` when not provided. - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """A unique identifier assigned to the request.""" - - unique_key: Annotated[ - str, - Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']), - ] - """A unique key used for request de-duplication.""" - - url: Annotated[AnyUrl, Field(examples=['https://apify.com'])] - """The URL of the request.""" - - method: Annotated[str | None, Field(examples=['GET'])] = None - """The HTTP method of the request. Defaults to `GET` on the API side if not provided.""" - - -class RequestDeleteInput(BaseModel): - """Input model for deleting requests from a request queue. - - Requests are identified by `id` or `unique_key`. At least one must be provided. - """ - - model_config = ConfigDict( - extra='allow', - populate_by_name=True, - ) - - id: Annotated[str | None, Field(examples=['sbJ7klsdf7ujN9l'])] = None - """A unique identifier assigned to the request.""" - - unique_key: Annotated[ - str | None, - Field(alias='uniqueKey', examples=['GET|60d83e70|e3b0c442|https://apify.com']), - ] = None - """A unique key used for request de-duplication.""" - - @model_validator(mode='after') - def _check_at_least_one_identifier(self) -> RequestDeleteInput: - if self.id is None and self.unique_key is None: - raise ValueError('At least one of `id` or `unique_key` must be provided') - return self diff --git a/tests/integration/test_actor.py b/tests/integration/test_actor.py index 480e4477..4797c664 100644 --- a/tests/integration/test_actor.py +++ b/tests/integration/test_actor.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Actor, Build, ListOfActors, Run + from apify_client._models_generated import Actor, Build, ListOfActors, Run from apify_client._resource_clients import BuildClient, BuildClientAsync diff --git a/tests/integration/test_actor_env_var.py b/tests/integration/test_actor_env_var.py index 97011b9c..e5d9663e 100644 --- a/tests/integration/test_actor_env_var.py +++ b/tests/integration/test_actor_env_var.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Actor, EnvVar, ListOfEnvVars + from apify_client._models_generated import Actor, EnvVar, ListOfEnvVars from ._utils import get_random_resource_name, maybe_await diff --git a/tests/integration/test_actor_version.py b/tests/integration/test_actor_version.py index 9fb09023..b8ff31c3 100644 --- a/tests/integration/test_actor_version.py +++ b/tests/integration/test_actor_version.py @@ -6,11 +6,11 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Actor, ListOfVersions, Version + from apify_client._models_generated import Actor, ListOfVersions, Version from ._utils import get_random_resource_name, maybe_await -from apify_client._models import VersionSourceType +from apify_client._models_generated import VersionSourceType async def test_actor_version_list(client: ApifyClient | ApifyClientAsync) -> None: diff --git a/tests/integration/test_apify_client.py b/tests/integration/test_apify_client.py index 6bd1bf92..3fa22264 100644 --- a/tests/integration/test_apify_client.py +++ b/tests/integration/test_apify_client.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import UserPrivateInfo, UserPublicInfo + from apify_client._models_generated import UserPrivateInfo, UserPublicInfo from ._utils import maybe_await diff --git a/tests/integration/test_build.py b/tests/integration/test_build.py index bcf5cfe1..ef8ac662 100644 --- a/tests/integration/test_build.py +++ b/tests/integration/test_build.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Actor, Build, ListOfBuilds + from apify_client._models_generated import Actor, Build, ListOfBuilds from datetime import timedelta diff --git a/tests/integration/test_dataset.py b/tests/integration/test_dataset.py index 6ded3519..149a504c 100644 --- a/tests/integration/test_dataset.py +++ b/tests/integration/test_dataset.py @@ -11,7 +11,7 @@ from impit import Response from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Dataset, ListOfDatasets + from apify_client._models_generated import Dataset, ListOfDatasets from apify_client._resource_clients.dataset import DatasetItemsPage import json diff --git a/tests/integration/test_key_value_store.py b/tests/integration/test_key_value_store.py index fbe9834b..952fc0cf 100644 --- a/tests/integration/test_key_value_store.py +++ b/tests/integration/test_key_value_store.py @@ -8,7 +8,7 @@ from collections.abc import AsyncIterator, Iterator from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import KeyValueStore, KeyValueStoreKey, ListOfKeys, ListOfKeyValueStores + from apify_client._models_generated import KeyValueStore, KeyValueStoreKey, ListOfKeys, ListOfKeyValueStores import json from datetime import timedelta diff --git a/tests/integration/test_log.py b/tests/integration/test_log.py index 4f49bc39..85800682 100644 --- a/tests/integration/test_log.py +++ b/tests/integration/test_log.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import ListOfBuilds, Run + from apify_client._models_generated import ListOfBuilds, Run from ._utils import maybe_await diff --git a/tests/integration/test_request_queue.py b/tests/integration/test_request_queue.py index 4b6a4221..a08e7fb8 100644 --- a/tests/integration/test_request_queue.py +++ b/tests/integration/test_request_queue.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import ( + from apify_client._models_generated import ( BatchAddResult, BatchDeleteResult, ListOfRequestQueues, @@ -19,6 +19,8 @@ RequestRegistration, UnlockRequestsResult, ) + from apify_client._typeddicts import RequestDeleteInputDict, RequestInputDict + from apify_client._typeddicts_generated import RequestDict from datetime import timedelta @@ -75,7 +77,7 @@ async def test_request_queue_lock(client: ApifyClient | ApifyClientAsync, *, is_ # Add requests and check if correct number of requests was locked for i in range(15): await maybe_await( - rq.add_request({'url': f'http://test-lock.com/{i}', 'uniqueKey': f'http://test-lock.com/{i}'}) + rq.add_request({'url': f'http://test-lock.com/{i}', 'unique_key': f'http://test-lock.com/{i}'}) ) # Poll until all requests are available for locking (eventual consistency) @@ -184,9 +186,9 @@ async def test_request_queue_add_and_get_request(client: ApifyClient | ApifyClie try: # Add a request - request_data = { + request_data: RequestInputDict = { 'url': 'https://example.com/test', - 'uniqueKey': 'test-key-1', + 'unique_key': 'test-key-1', 'method': 'GET', } result = await maybe_await(rq_client.add_request(request_data)) @@ -220,12 +222,7 @@ async def test_request_queue_list_head(client: ApifyClient | ApifyClientAsync, * # Add multiple requests for i in range(5): await maybe_await( - rq_client.add_request( - { - 'url': f'https://example.com/page-{i}', - 'uniqueKey': f'page-{i}', - } - ) + rq_client.add_request({'url': f'https://example.com/page-{i}', 'unique_key': f'page-{i}'}) ) # Poll until requests are available (eventual consistency) @@ -255,12 +252,7 @@ async def test_request_queue_list_requests(client: ApifyClient | ApifyClientAsyn # Add multiple requests for i in range(5): await maybe_await( - rq_client.add_request( - { - 'url': f'https://example.com/item-{i}', - 'uniqueKey': f'item-{i}', - } - ) + rq_client.add_request({'url': f'https://example.com/item-{i}', 'unique_key': f'item-{i}'}) ) # Poll until all requests are available (eventual consistency) @@ -289,12 +281,7 @@ async def test_request_queue_delete_request(client: ApifyClient | ApifyClientAsy try: # Add a request result = await maybe_await( - rq_client.add_request( - { - 'url': 'https://example.com/to-delete', - 'uniqueKey': 'delete-me', - } - ) + rq_client.add_request({'url': 'https://example.com/to-delete', 'unique_key': 'delete-me'}) ) add_result = cast('RequestRegistration', result) @@ -328,7 +315,9 @@ async def test_request_queue_batch_add_requests(client: ApifyClient | ApifyClien try: # Batch add requests - requests_to_add = [{'url': f'https://example.com/batch-{i}', 'uniqueKey': f'batch-{i}'} for i in range(10)] + requests_to_add: list[RequestInputDict] = [ + {'url': f'https://example.com/batch-{i}', 'unique_key': f'batch-{i}'} for i in range(10) + ] result = await maybe_await(rq_client.batch_add_requests(requests_to_add)) batch_response = cast('BatchAddResult', result) assert batch_response is not None @@ -362,12 +351,7 @@ async def test_request_queue_batch_delete_requests(client: ApifyClient | ApifyCl # Add requests for i in range(10): await maybe_await( - rq_client.add_request( - { - 'url': f'https://example.com/delete-{i}', - 'uniqueKey': f'delete-{i}', - } - ) + rq_client.add_request({'url': f'https://example.com/delete-{i}', 'unique_key': f'delete-{i}'}) ) # Poll until all requests are available (eventual consistency) @@ -381,7 +365,9 @@ async def test_request_queue_batch_delete_requests(client: ApifyClient | ApifyCl assert list_response is not None assert len(list_response.items) == 10 - requests_to_delete = [{'uniqueKey': item.unique_key} for item in list_response.items[:5]] + requests_to_delete: list[RequestDeleteInputDict] = [ + {'unique_key': item.unique_key} for item in list_response.items[:5] + ] # Batch delete result = await maybe_await(rq_client.batch_delete_requests(requests_to_delete)) @@ -431,7 +417,9 @@ async def test_request_queue_list_and_lock_head(client: ApifyClient | ApifyClien try: # Add multiple requests for i in range(5): - await maybe_await(rq_client.add_request({'url': f'https://example.com/lock-{i}', 'uniqueKey': f'lock-{i}'})) + await maybe_await( + rq_client.add_request({'url': f'https://example.com/lock-{i}', 'unique_key': f'lock-{i}'}) + ) # Poll until requests are available for locking (eventual consistency) lock_response: LockedRequestQueueHead | None = None @@ -463,7 +451,7 @@ async def test_request_queue_prolong_request_lock(client: ApifyClient | ApifyCli try: # Add a request - await maybe_await(rq_client.add_request({'url': 'https://example.com/prolong', 'uniqueKey': 'prolong-test'})) + await maybe_await(rq_client.add_request({'url': 'https://example.com/prolong', 'unique_key': 'prolong-test'})) # Poll until the request is available for locking (eventual consistency) lock_response: LockedRequestQueueHead | None = None @@ -501,7 +489,7 @@ async def test_request_queue_delete_request_lock(client: ApifyClient | ApifyClie try: # Add a request - await maybe_await(rq_client.add_request({'url': 'https://example.com/unlock', 'uniqueKey': 'unlock-test'})) + await maybe_await(rq_client.add_request({'url': 'https://example.com/unlock', 'unique_key': 'unlock-test'})) # Poll until the request is available for locking (eventual consistency) lock_response: LockedRequestQueueHead | None = None @@ -539,7 +527,7 @@ async def test_request_queue_unlock_requests(client: ApifyClient | ApifyClientAs # Add multiple requests for i in range(5): await maybe_await( - rq_client.add_request({'url': f'https://example.com/unlock-{i}', 'uniqueKey': f'unlock-{i}'}) + rq_client.add_request({'url': f'https://example.com/unlock-{i}', 'unique_key': f'unlock-{i}'}) ) # Poll until requests are available for locking (eventual consistency) @@ -573,9 +561,9 @@ async def test_request_queue_update_request(client: ApifyClient | ApifyClientAsy try: # Add a request - request_data = { + request_data: RequestInputDict = { 'url': 'https://example.com/original', - 'uniqueKey': 'update-test', + 'unique_key': 'update-test', 'method': 'GET', } result = await maybe_await(rq_client.add_request(request_data)) @@ -591,13 +579,14 @@ async def test_request_queue_update_request(client: ApifyClient | ApifyClientAsy original_request = cast('Request', result) assert original_request is not None + assert original_request.unique_key is not None # Update the request (change method and add user data) - updated_request_data = { + updated_request_data: RequestDict = { 'id': add_result.request_id, 'url': str(original_request.url), - 'uniqueKey': original_request.unique_key, + 'unique_key': original_request.unique_key, 'method': 'POST', - 'userData': {'updated': True}, + 'user_data': {'updated': True}, } result = await maybe_await(rq_client.update_request(updated_request_data)) update_result = cast('RequestRegistration', result) diff --git a/tests/integration/test_run.py b/tests/integration/test_run.py index 774a227f..3416fe85 100644 --- a/tests/integration/test_run.py +++ b/tests/integration/test_run.py @@ -6,13 +6,13 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Dataset, KeyValueStore, ListOfRuns, RequestQueue, Run + from apify_client._models_generated import Dataset, KeyValueStore, ListOfRuns, RequestQueue, Run from datetime import UTC, datetime, timedelta from ._utils import maybe_await, maybe_sleep -from apify_client._models import ActorJobStatus, Run +from apify_client._models_generated import ActorJobStatus, Run from apify_client.errors import ApifyApiError HELLO_WORLD_ACTOR = 'apify/hello-world' diff --git a/tests/integration/test_schedule.py b/tests/integration/test_schedule.py index 0c2bc8a0..2337116f 100644 --- a/tests/integration/test_schedule.py +++ b/tests/integration/test_schedule.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import ListOfSchedules, Schedule + from apify_client._models_generated import ListOfSchedules, Schedule from ._utils import get_random_resource_name, maybe_await diff --git a/tests/integration/test_store.py b/tests/integration/test_store.py index 44959e1c..69a3e8fc 100644 --- a/tests/integration/test_store.py +++ b/tests/integration/test_store.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import ListOfStoreActors + from apify_client._models_generated import ListOfStoreActors from ._utils import maybe_await diff --git a/tests/integration/test_task.py b/tests/integration/test_task.py index 055d4a01..322185a2 100644 --- a/tests/integration/test_task.py +++ b/tests/integration/test_task.py @@ -9,7 +9,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import Actor, ListOfRuns, ListOfTasks, ListOfWebhooks, Run, Task + from apify_client._models_generated import Actor, ListOfRuns, ListOfTasks, ListOfWebhooks, Run, Task # Use a simple, fast public actor for testing HELLO_WORLD_ACTOR = 'apify/hello-world' diff --git a/tests/integration/test_user.py b/tests/integration/test_user.py index 4b632faf..682f3a32 100644 --- a/tests/integration/test_user.py +++ b/tests/integration/test_user.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import AccountLimits, MonthlyUsage, UserPrivateInfo, UserPublicInfo + from apify_client._models_generated import AccountLimits, MonthlyUsage, UserPrivateInfo, UserPublicInfo from ._utils import maybe_await diff --git a/tests/integration/test_webhook.py b/tests/integration/test_webhook.py index b5fae924..a011aaa7 100644 --- a/tests/integration/test_webhook.py +++ b/tests/integration/test_webhook.py @@ -9,7 +9,7 @@ from ._utils import maybe_await -from apify_client._models import ( +from apify_client._models_generated import ( ActorJobStatus, ListOfRuns, ListOfWebhookDispatches, diff --git a/tests/integration/test_webhook_dispatch.py b/tests/integration/test_webhook_dispatch.py index 81840094..5bfc106d 100644 --- a/tests/integration/test_webhook_dispatch.py +++ b/tests/integration/test_webhook_dispatch.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from apify_client import ApifyClient, ApifyClientAsync - from apify_client._models import ListOfWebhookDispatches, WebhookDispatch + from apify_client._models_generated import ListOfWebhookDispatches, WebhookDispatch from ._utils import maybe_await diff --git a/tests/unit/test_actor_start_params.py b/tests/unit/test_actor_start_params.py index 87d65fb2..b58f465b 100644 --- a/tests/unit/test_actor_start_params.py +++ b/tests/unit/test_actor_start_params.py @@ -8,7 +8,7 @@ from werkzeug import Request, Response from apify_client import ApifyClient, ApifyClientAsync -from apify_client._models import ActorJobStatus +from apify_client._models_generated import ActorJobStatus if TYPE_CHECKING: from pytest_httpserver import HTTPServer diff --git a/tests/unit/test_client_request_queue.py b/tests/unit/test_client_request_queue.py index 3f0d2e13..aedb0f90 100644 --- a/tests/unit/test_client_request_queue.py +++ b/tests/unit/test_client_request_queue.py @@ -11,6 +11,8 @@ if TYPE_CHECKING: from pytest_httpserver import HTTPServer + from apify_client._typeddicts import RequestInputDict + _PARTIALLY_ADDED_BATCH_RESPONSE_CONTENT = """{ "data": { "processedRequests": [ @@ -41,9 +43,9 @@ async def test_batch_not_processed_raises_exception_async(httpserver: HTTPServer api_public_url=server_url, ) httpserver.expect_oneshot_request(re.compile(r'.*'), method='POST').respond_with_data(status=401) - requests = [ - {'uniqueKey': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, - {'uniqueKey': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, + requests: list[RequestInputDict] = [ + {'unique_key': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, + {'unique_key': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, ] rq_client = client.request_queue(request_queue_id='whatever') @@ -62,16 +64,16 @@ async def test_batch_processed_partially_async(httpserver: HTTPServer) -> None: httpserver.expect_oneshot_request(re.compile(r'.*'), method='POST').respond_with_data( status=200, response_data=_PARTIALLY_ADDED_BATCH_RESPONSE_CONTENT ) - requests = [ - {'uniqueKey': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, - {'uniqueKey': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, + requests: list[RequestInputDict] = [ + {'unique_key': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, + {'unique_key': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, ] rq_client = client.request_queue(request_queue_id='whatever') batch_response = await rq_client.batch_add_requests(requests=requests) - assert requests[0]['uniqueKey'] in {request.unique_key for request in batch_response.processed_requests} + assert requests[0]['unique_key'] in {request.unique_key for request in batch_response.processed_requests} assert len(batch_response.unprocessed_requests) == 1 - assert batch_response.unprocessed_requests[0].unique_key == requests[1]['uniqueKey'] + assert batch_response.unprocessed_requests[0].unique_key == requests[1]['unique_key'] def test_batch_not_processed_raises_exception_sync(httpserver: HTTPServer) -> None: @@ -84,9 +86,9 @@ def test_batch_not_processed_raises_exception_sync(httpserver: HTTPServer) -> No ) httpserver.expect_oneshot_request(re.compile(r'.*'), method='POST').respond_with_data(status=401) - requests = [ - {'uniqueKey': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, - {'uniqueKey': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, + requests: list[RequestInputDict] = [ + {'unique_key': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, + {'unique_key': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, ] rq_client = client.request_queue(request_queue_id='whatever') @@ -105,13 +107,13 @@ def test_batch_processed_partially_sync(httpserver: HTTPServer) -> None: httpserver.expect_oneshot_request(re.compile(r'.*'), method='POST').respond_with_data( status=200, response_data=_PARTIALLY_ADDED_BATCH_RESPONSE_CONTENT ) - requests = [ - {'uniqueKey': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, - {'uniqueKey': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, + requests: list[RequestInputDict] = [ + {'unique_key': 'http://example.com/1', 'url': 'http://example.com/1', 'method': 'GET'}, + {'unique_key': 'http://example.com/2', 'url': 'http://example.com/2', 'method': 'GET'}, ] rq_client = client.request_queue(request_queue_id='whatever') batch_response = rq_client.batch_add_requests(requests=requests) - assert requests[0]['uniqueKey'] in {request.unique_key for request in batch_response.processed_requests} + assert requests[0]['unique_key'] in {request.unique_key for request in batch_response.processed_requests} assert len(batch_response.unprocessed_requests) == 1 - assert batch_response.unprocessed_requests[0].unique_key == requests[1]['uniqueKey'] + assert batch_response.unprocessed_requests[0].unique_key == requests[1]['unique_key'] diff --git a/tests/unit/test_logging.py b/tests/unit/test_logging.py index cf537795..2c1fed2d 100644 --- a/tests/unit/test_logging.py +++ b/tests/unit/test_logging.py @@ -13,7 +13,7 @@ from apify_client import ApifyClient, ApifyClientAsync from apify_client._logging import RedirectLogFormatter -from apify_client._models import ActorJobStatus +from apify_client._models_generated import ActorJobStatus from apify_client._status_message_watcher import StatusMessageWatcherBase from apify_client._streamed_log import StreamedLogBase diff --git a/tests/unit/test_postprocess_generated_models.py b/tests/unit/test_postprocess_generated_models.py index d48c4121..5ce35fb1 100644 --- a/tests/unit/test_postprocess_generated_models.py +++ b/tests/unit/test_postprocess_generated_models.py @@ -156,7 +156,7 @@ class Foo(BaseModel): class Bar(BaseModel): value: int """) - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') assert 'from apify_client._docs import docs_group' in result assert result.count("@docs_group('Models')") == 2 @@ -168,7 +168,7 @@ def test_add_docs_group_decorators_places_import_after_pydantic() -> None: class Foo(BaseModel): pass """) - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') lines = result.split('\n') pydantic_idx = next(i for i, line in enumerate(lines) if 'from pydantic' in line) docs_import_idx = next(i for i, line in enumerate(lines) if 'from apify_client._docs' in line) @@ -184,7 +184,7 @@ def test_add_docs_group_decorators_idempotent_import() -> None: class Foo(BaseModel): pass """) - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') assert result.count('from apify_client._docs import docs_group') == 1 @@ -202,7 +202,7 @@ class Foo(BaseModel): class Bar(BaseModel): pass """) - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') assert result.count("@docs_group('Models')") == 2 @@ -216,7 +216,7 @@ class Alpha(BaseModel): class Beta(BaseModel): pass """) - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') lines = result.split('\n') for i, line in enumerate(lines): if line.startswith('class '): @@ -225,7 +225,7 @@ class Beta(BaseModel): def test_add_docs_group_decorators_no_classes() -> None: content = 'from pydantic import BaseModel\n\nx = 1\n' - result = add_docs_group_decorators(content) + result = add_docs_group_decorators(content, 'Models') assert "@docs_group('Models')" not in result @@ -253,7 +253,7 @@ class Alpha(BaseModel): """) result = fix_discriminators(content) result = deduplicate_error_type_enum(result) - result = add_docs_group_decorators(result) + result = add_docs_group_decorators(result, 'Models') # Discriminator fixed. assert "discriminator='pricing_model'" in result diff --git a/tests/unit/test_storage_collection_listing.py b/tests/unit/test_storage_collection_listing.py index 5f19978a..d698e857 100644 --- a/tests/unit/test_storage_collection_listing.py +++ b/tests/unit/test_storage_collection_listing.py @@ -7,7 +7,7 @@ from werkzeug.wrappers import Response from apify_client import ApifyClient, ApifyClientAsync -from apify_client._models import StorageOwnership +from apify_client._models_generated import StorageOwnership if TYPE_CHECKING: from collections.abc import Callable diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index d4c6f281..ecb41699 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -1,14 +1,17 @@ +from __future__ import annotations + import io from datetime import timedelta from http import HTTPStatus +from typing import TYPE_CHECKING from unittest.mock import Mock import impit import pytest -from apify_client._models import WebhookCondition, WebhookCreate, WebhookEventType +from apify_client._models import WebhookRepresentationList +from apify_client._models_generated import WebhookCondition, WebhookCreate, WebhookEventType from apify_client._resource_clients._resource_client import ResourceClientBase -from apify_client._types import WebhookRepresentationList from apify_client._utils import ( catch_not_found_or_throw, create_hmac_signature, @@ -22,6 +25,9 @@ ) from apify_client.errors import ApifyApiError, InvalidResponseBodyError +if TYPE_CHECKING: + from apify_client._typeddicts import WebhookRepresentationDict + def test_to_safe_id() -> None: assert to_safe_id('abc') == 'abc' @@ -53,20 +59,19 @@ def test_webhook_representation_list_to_base64() -> None: def test_webhook_representation_list_from_dicts() -> None: - """Test that from_webhooks accepts plain dicts with the minimal ad-hoc webhook shape.""" - result = WebhookRepresentationList.from_webhooks( - [ - { - 'event_types': ['ACTOR.RUN.CREATED'], - 'request_url': 'https://example.com/run-created', - }, - { - 'event_types': ['ACTOR.RUN.SUCCEEDED'], - 'request_url': 'https://example.com/run-succeeded', - 'payload_template': '{"hello": "world"}', - }, - ] - ).to_base64() + """Test that from_webhooks accepts plain dicts typed as WebhookRepresentationDict.""" + webhooks: list[WebhookRepresentationDict] = [ + { + 'event_types': ['ACTOR.RUN.CREATED'], + 'request_url': 'https://example.com/run-created', + }, + { + 'event_types': ['ACTOR.RUN.SUCCEEDED'], + 'request_url': 'https://example.com/run-succeeded', + 'payload_template': '{"hello": "world"}', + }, + ] + result = WebhookRepresentationList.from_webhooks(webhooks).to_base64() assert result is not None diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index e704d7f1..9b525f2c 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -11,6 +11,7 @@ const GROUP_ORDER = [ 'Resource clients', 'Errors', 'Models', + 'Typed dicts', 'Other', ];