-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy path11_pydantic.py
More file actions
59 lines (42 loc) · 2.07 KB
/
Copy path11_pydantic.py
File metadata and controls
59 lines (42 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import asyncio
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator
from apify import Actor
class ActorInput(BaseModel):
"""Typed and validated representation of the Actor input."""
# Accept both snake_case and the input schema's camelCase; ignore extras.
model_config = ConfigDict(populate_by_name=True, extra='ignore')
# Required: non-empty list of search terms (normalized below).
search_terms: list[str] = Field(alias='searchTerms', min_length=1)
# Optional: 1-100, defaults to 10.
max_results: int = Field(alias='maxResults', default=10, ge=1, le=100)
# Optional: restricted to a fixed set of choices.
output_format: Literal['json', 'csv'] = Field(alias='outputFormat', default='json')
@field_validator('search_terms')
@classmethod
def _normalize_terms(cls, value: list[str]) -> list[str]:
# Trim whitespace and drop empty terms.
cleaned = [term.strip() for term in value if term.strip()]
if not cleaned:
raise ValueError('searchTerms must contain at least one non-empty term')
return cleaned
async def main() -> None:
async with Actor:
# Read the raw input (a plain dict, not yet validated).
raw_input = await Actor.get_input() or {}
# Validate the raw input against the model.
try:
actor_input = ActorInput.model_validate(raw_input)
except ValidationError as exc:
# Log a per-field summary, then re-raise to fail the run.
Actor.log.error('The Actor input is invalid:\n%s', exc)
raise
# Work with typed attributes from here on.
Actor.log.info('Input passed validation: %s', actor_input.model_dump())
max_results = actor_input.max_results
for term in actor_input.search_terms:
Actor.log.info('Processing %r (max %d results)', term, max_results)
# Store the normalized input as output.
await Actor.set_value('OUTPUT', actor_input.model_dump())
if __name__ == '__main__':
asyncio.run(main())