Skip to content

Commit 6fe9eb3

Browse files
authored
Merge branch 'master' into new-apify-storage-clients
2 parents 3cd7dfe + e1175f6 commit 6fe9eb3

18 files changed

+643
-907
lines changed

.github/workflows/pre_release.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,27 @@ jobs:
3131
lint_check:
3232
name: Lint check
3333
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
34+
with:
35+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
3436

3537
type_check:
3638
name: Type check
3739
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
40+
with:
41+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
3842

3943
unit_tests:
4044
name: Unit tests
4145
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
46+
with:
47+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
4248

4349
integration_tests:
4450
name: Integration tests
4551
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
4652
secrets: inherit
53+
with:
54+
python-versions: '["3.10", "3.13"]'
4755

4856
update_changelog:
4957
name: Update changelog

.github/workflows/release.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,27 @@ jobs:
4242
lint_check:
4343
name: Lint check
4444
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
45+
with:
46+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
4547

4648
type_check:
4749
name: Type check
4850
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
51+
with:
52+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
4953

5054
unit_tests:
5155
name: Unit tests
5256
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
57+
with:
58+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
5359

5460
integration_tests:
5561
name: Integration tests
5662
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
5763
secrets: inherit
64+
with:
65+
python-versions: '["3.10", "3.13"]'
5866

5967
update_changelog:
6068
name: Update changelog

.github/workflows/run_code_checks.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ jobs:
1010
lint_check:
1111
name: Lint check
1212
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
13+
with:
14+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
1315

1416
type_check:
1517
name: Type check
1618
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
19+
with:
20+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
1721

1822
unit_tests:
1923
name: Unit tests
2024
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
25+
with:
26+
python-versions: '["3.10", "3.11", "3.12", "3.13"]'
2127

2228
docs_check:
2329
name: Docs check
@@ -26,5 +32,7 @@ jobs:
2632
integration_tests:
2733
name: Integration tests
2834
needs: [lint_check, type_check, unit_tests]
29-
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@fix-integration-tests-from-forks
35+
uses: apify/workflows/.github/workflows/python_integration_tests.yaml@main
3036
secrets: inherit
37+
with:
38+
python-versions: '["3.10", "3.13"]'

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Here you'll find a contributing guide to get started with development.
44

55
## Environment
66

7-
For local development, it is required to have Python 3.9 (or a later version) installed.
7+
For local development, it is required to have Python 3.10 (or a later version) installed.
88

99
We use [uv](https://docs.astral.sh/uv/) for project management. Install it and set up your IDE accordingly.
1010

docs/01_overview/02_running_actors_locally.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ In this page, you'll learn how to create and run Apify Actors locally on your co
1111

1212
## Requirements
1313

14-
The Apify SDK requires Python version 3.9 or above to run Python Actors locally.
14+
The Apify SDK requires Python version 3.10 or above to run Python Actors locally.
1515

1616
## Creating your first Actor
1717

pyproject.toml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ description = "Apify SDK for Python"
99
authors = [{ name = "Apify Technologies s.r.o.", email = "[email protected]" }]
1010
license = { file = "LICENSE" }
1111
readme = "README.md"
12-
requires-python = ">=3.9"
12+
requires-python = ">=3.10"
1313
classifiers = [
1414
"Development Status :: 5 - Production/Stable",
15+
"Environment :: Console",
1516
"Intended Audience :: Developers",
1617
"License :: OSI Approved :: Apache Software License",
1718
"Operating System :: OS Independent",
18-
"Programming Language :: Python :: 3.9",
1919
"Programming Language :: Python :: 3.10",
2020
"Programming Language :: Python :: 3.11",
2121
"Programming Language :: Python :: 3.12",
@@ -52,27 +52,30 @@ dependencies = [
5252
scrapy = ["scrapy>=2.11.0"]
5353

5454
[project.urls]
55-
"Homepage" = "https://docs.apify.com/sdk/python/"
56-
"Apify homepage" = "https://apify.com"
55+
"Apify Homepage" = "https://apify.com"
5756
"Changelog" = "https://docs.apify.com/sdk/python/docs/changelog"
58-
"Documentation" = "https://docs.apify.com/sdk/python/"
59-
"Issue tracker" = "https://github.com/apify/apify-sdk-python/issues"
60-
"Repository" = "https://github.com/apify/apify-sdk-python"
57+
"Discord" = "https://discord.com/invite/jyEM2PRvMU"
58+
"Documentation" = "https://docs.apify.com/sdk/python/docs/overview/introduction"
59+
"Homepage" = "https://docs.apify.com/sdk/python/"
60+
"Issue Tracker" = "https://github.com/apify/apify-sdk-python/issues"
61+
"Release Notes" = "https://docs.apify.com/sdk/python/docs/upgrading/upgrading-to-v2"
62+
"Source Code" = "https://github.com/apify/apify-sdk-python"
6163

6264
[dependency-groups]
6365
dev = [
6466
"build~=1.2.0",
67+
"dycw-pytest-only>=2.1.1",
6568
"griffe~=1.7.0",
6669
"mypy~=1.16.0",
6770
"pre-commit~=4.2.0",
6871
"pydoc-markdown~=4.8.0",
6972
"pytest-asyncio~=1.0.0",
7073
"pytest-cov~=6.2.0",
71-
"pytest-only~=2.1.0",
72-
"pytest-xdist~=3.7.0",
74+
"pytest-timeout>=2.4.0",
75+
"pytest-xdist~=3.8.0",
7376
"pytest~=8.4.0",
7477
"respx~=0.22.0",
75-
"ruff~=0.11.0",
78+
"ruff~=0.12.0",
7679
"setuptools", # setuptools are used by pytest but not explicitly required
7780
"types-cachetools>=6.0.0.20250525",
7881
]
@@ -139,6 +142,9 @@ indent-style = "space"
139142
"TRY301", # Abstract `raise` to an inner function
140143
"TID252", # Prefer absolute imports over relative imports from parent modules
141144
]
145+
"**/{tests}/{integration}/*" = [
146+
"PLC0415", # `import` should be at the top-level of a file
147+
]
142148
"**/{docs,website}/**" = [
143149
"D", # Everything from the pydocstyle
144150
"INP001", # File {filename} is part of an implicit namespace package, add an __init__.py
@@ -186,7 +192,7 @@ asyncio_mode = "auto"
186192
timeout = 1200
187193

188194
[tool.mypy]
189-
python_version = "3.9"
195+
python_version = "3.10"
190196
plugins = ["pydantic.mypy"]
191197
files = ["src", "tests", "docs", "website"]
192198
check_untyped_defs = true
@@ -213,7 +219,7 @@ module = [
213219
ignore_missing_imports = true
214220

215221
[tool.basedpyright]
216-
pythonVersion = "3.9"
222+
pythonVersion = "3.10"
217223
typeCheckingMode = "standard"
218224
include = ["src", "tests", "docs", "website"]
219225

src/apify/_actor.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import sys
66
from contextlib import suppress
77
from datetime import datetime, timedelta, timezone
8-
from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, cast, overload
8+
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload
99

1010
from lazy_object_proxy import Proxy
1111
from more_itertools import flatten
@@ -39,6 +39,7 @@
3939

4040
if TYPE_CHECKING:
4141
import logging
42+
from collections.abc import Callable
4243
from types import TracebackType
4344

4445
from typing_extensions import Self
@@ -1187,7 +1188,7 @@ def _get_default_exit_process(self) -> bool:
11871188

11881189
# Check if running in Scrapy by attempting to import it.
11891190
with suppress(ImportError):
1190-
import scrapy # noqa: F401
1191+
import scrapy # noqa: F401 PLC0415
11911192

11921193
self.log.debug('Running in Scrapy, setting default `exit_process` to False.')
11931194
return False

src/apify/_charging.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from dataclasses import dataclass
55
from datetime import datetime, timezone
66
from decimal import Decimal
7-
from typing import TYPE_CHECKING, Protocol, Union
7+
from typing import TYPE_CHECKING, Protocol
88

99
from pydantic import TypeAdapter
1010

@@ -23,8 +23,7 @@
2323

2424
from apify._configuration import Configuration
2525

26-
27-
run_validator: TypeAdapter[ActorRun | None] = TypeAdapter(Union[ActorRun, None])
26+
run_validator = TypeAdapter[ActorRun | None](ActorRun | None)
2827

2928

3029
@docs_group('Interfaces')
@@ -216,9 +215,7 @@ def calculate_chargeable() -> dict[str, int | None]:
216215
PricingInfoItem(
217216
price=Decimal()
218217
if self._is_at_home
219-
else Decimal(
220-
'1'
221-
), # Use a nonzero price for local development so that the maximum budget can be reached,
218+
else Decimal(1), # Use a nonzero price for local development so that the maximum budget can be reached,
222219
title=f"Unknown event '{event_name}'",
223220
),
224221
)
@@ -282,7 +279,7 @@ def calculate_max_event_charge_count_within_limit(self, event_name: str) -> int
282279
if pricing_info is not None:
283280
price = pricing_info.price
284281
elif not self._is_at_home:
285-
price = Decimal('1') # Use a nonzero price for local development so that the maximum budget can be reached
282+
price = Decimal(1) # Use a nonzero price for local development so that the maximum budget can be reached
286283
else:
287284
price = Decimal()
288285

src/apify/_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from apify._utils import docs_group
1414

1515
if TYPE_CHECKING:
16-
from typing_extensions import TypeAlias
16+
from typing import TypeAlias
1717

1818

1919
@docs_group('Data structures')

src/apify/_platform_event_manager.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import asyncio
44
from datetime import datetime
5-
from typing import TYPE_CHECKING, Annotated, Any, Literal, Union
5+
from typing import TYPE_CHECKING, Annotated, Any, Literal
66

77
import websockets.asyncio.client
88
from pydantic import BaseModel, Discriminator, Field, TypeAdapter
@@ -113,25 +113,10 @@ class UnknownEvent(BaseModel):
113113
data: Annotated[dict[str, Any], Field(default_factory=dict)]
114114

115115

116-
EventMessage = Union[
117-
PersistStateEvent,
118-
SystemInfoEvent,
119-
MigratingEvent,
120-
AbortingEvent,
121-
ExitEvent,
122-
EventWithoutData,
123-
]
124-
125-
126-
event_data_adapter: TypeAdapter[EventMessage | DeprecatedEvent | UnknownEvent] = TypeAdapter(
127-
Union[
128-
Annotated[
129-
EventMessage,
130-
Discriminator('name'),
131-
],
132-
DeprecatedEvent,
133-
UnknownEvent,
134-
]
116+
EventMessage = PersistStateEvent | SystemInfoEvent | MigratingEvent | AbortingEvent | ExitEvent | EventWithoutData
117+
118+
event_data_adapter = TypeAdapter[EventMessage | DeprecatedEvent | UnknownEvent](
119+
Annotated[EventMessage, Discriminator('name')] | DeprecatedEvent | UnknownEvent
135120
)
136121

137122

0 commit comments

Comments
 (0)