Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/_checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ jobs:
name: Lint check
uses: apify/workflows/.github/workflows/python_lint_check.yaml@main
with:
python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
python_versions: '["3.11", "3.12", "3.13", "3.14"]'

type_check:
name: Type check
uses: apify/workflows/.github/workflows/python_type_check.yaml@main
with:
python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
python_versions: '["3.11", "3.12", "3.13", "3.14"]'

unit_tests:
name: Unit tests
if: inputs.run_tests
uses: apify/workflows/.github/workflows/python_unit_tests.yaml@main
secrets: inherit
with:
python_versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]'
python_versions: '["3.11", "3.12", "3.13", "3.14"]'
operating_systems: '["ubuntu-latest", "windows-latest"]'
python_version_for_codecov: "3.14"
operating_system_for_codecov: ubuntu-latest
Expand All @@ -80,7 +80,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest"]
python-version: ["3.10", "3.14"]
python-version: ["3.11", "3.14"]

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -140,7 +140,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest"]
python-version: ["3.10", "3.14"]
python-version: ["3.11", "3.14"]

runs-on: ${{ matrix.os }}

Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ description = "Apify SDK for Python"
authors = [{ name = "Apify Technologies s.r.o.", email = "support@apify.com" }]
license = { file = "LICENSE" }
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
Expand Down Expand Up @@ -210,7 +209,7 @@ asyncio_mode = "auto"
timeout = 1800

[tool.ty.environment]
python-version = "3.10"
python-version = "3.11"

[tool.ty.src]
include = ["src", "tests", "scripts", "docs", "website"]
Expand Down
9 changes: 4 additions & 5 deletions src/apify/_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys
import warnings
from contextlib import suppress
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from functools import cached_property
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload

Expand Down Expand Up @@ -44,8 +44,7 @@
from collections.abc import Callable, MutableMapping
from decimal import Decimal
from types import TracebackType

from typing_extensions import Self
from typing import Self

from apify_shared.consts import ActorPermissionLevel
from crawlee._types import JsonSerializable
Expand Down Expand Up @@ -1241,7 +1240,7 @@ async def reboot(
),
timeout=event_listeners_timeout.total_seconds() if event_listeners_timeout else None,
)
except asyncio.TimeoutError:
except TimeoutError:
self.log.warning('Pre-reboot event listeners did not finish within timeout; proceeding with reboot')
results = []

Expand Down Expand Up @@ -1442,7 +1441,7 @@ def _get_default_exit_process(self) -> bool:
def _get_remaining_time(self) -> timedelta | None:
"""Get time remaining from the Actor timeout. Returns `None` if not on an Apify platform."""
if self.is_at_home() and self.configuration.timeout_at:
return max(self.configuration.timeout_at - datetime.now(tz=timezone.utc), timedelta(0))
return max(self.configuration.timeout_at - datetime.now(tz=UTC), timedelta(0))

self.log.warning(
'Using `inherit` or `RemainingTime` argument is only possible when the Actor'
Expand Down
4 changes: 2 additions & 2 deletions src/apify/_charging.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import math
from contextvars import ContextVar
from dataclasses import dataclass
from datetime import datetime, timezone
from datetime import UTC, datetime
from decimal import Decimal
from typing import TYPE_CHECKING, Protocol, TypedDict

Expand Down Expand Up @@ -320,7 +320,7 @@ async def charge(self, event_name: str, count: int = 1) -> ChargeResult:
'event_title': pricing_info.title,
'event_price_usd': float(round(pricing_info.price, 3)),
'charged_count': charged_count,
'timestamp': datetime.now(timezone.utc).isoformat(),
'timestamp': datetime.now(UTC).isoformat(),
}
)

Expand Down
4 changes: 2 additions & 2 deletions src/apify/_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
from decimal import Decimal
from logging import getLogger
from pathlib import Path
from typing import Annotated, Any
from typing import Annotated, Any, Self

from pydantic import AliasChoices, BeforeValidator, Field, model_validator
from typing_extensions import Self, TypedDict, deprecated
from typing_extensions import TypedDict, deprecated

from crawlee import service_locator
from crawlee._utils.models import timedelta_ms
Expand Down
4 changes: 2 additions & 2 deletions src/apify/events/_apify_event_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import asyncio
import contextlib
from typing import TYPE_CHECKING, Annotated
from typing import TYPE_CHECKING, Annotated, Self

import websockets.asyncio.client
from pydantic import Discriminator, TypeAdapter
from typing_extensions import Self, Unpack, override
from typing_extensions import Unpack, override

from crawlee.events import EventManager
from crawlee.events._types import Event, EventPersistStateData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio
from collections import deque
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from logging import getLogger
from typing import TYPE_CHECKING, Any, Final

Expand Down Expand Up @@ -214,7 +214,7 @@ async def mark_request_as_handled(self, request: Request) -> ProcessedRequest |
request_id = unique_key_to_request_id(request.unique_key)
# Set the handled_at timestamp if not already set
if request.handled_at is None:
request.handled_at = datetime.now(tz=timezone.utc)
request.handled_at = datetime.now(tz=UTC)

if cached_request := self._requests_cache.get(request_id):
cached_request.was_already_handled = request.was_already_handled
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections import deque
from datetime import datetime, timezone
from datetime import UTC, datetime
from logging import getLogger
from typing import TYPE_CHECKING, Final

Expand Down Expand Up @@ -212,7 +212,7 @@ async def mark_request_as_handled(self, request: Request) -> ProcessedRequest |
cached_request.handled_at = request.handled_at

if request.handled_at is None:
request.handled_at = datetime.now(tz=timezone.utc)
request.handled_at = datetime.now(tz=UTC)
self.metadata.handled_request_count += 1
self.metadata.pending_request_count -= 1

Expand Down
4 changes: 2 additions & 2 deletions src/apify/storage_clients/_file_system/_dataset_client.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Self

from typing_extensions import Self, override
from typing_extensions import override

from crawlee.storage_clients._file_system import FileSystemDatasetClient

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import logging
from itertools import chain
from pathlib import Path
from typing import Self

from typing_extensions import Self, override
from typing_extensions import override

from crawlee._consts import METADATA_FILENAME
from crawlee._utils.file import atomic_write, infer_mime_type, json_dumps
Expand Down
8 changes: 4 additions & 4 deletions tests/e2e/test_actor_call_timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async def test_actor_start_inherit_timeout(
Timeout should be the remaining time of the first Actor run calculated at the moment of the other Actor start."""

async def main() -> None:
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta

async with Actor:
actor_input = (await Actor.get_input()) or {}
Expand All @@ -42,7 +42,7 @@ async def main() -> None:
assert Actor.configuration.timeout_at is not None
assert Actor.configuration.started_at is not None

remaining_time_after_actor_start = Actor.configuration.timeout_at - datetime.now(tz=timezone.utc)
remaining_time_after_actor_start = Actor.configuration.timeout_at - datetime.now(tz=UTC)

other_timeout = timedelta(seconds=other_run_data.options.timeout_secs)
total_timeout = Actor.configuration.timeout_at - Actor.configuration.started_at
Expand All @@ -69,7 +69,7 @@ async def test_actor_call_inherit_timeout(
Timeout should be the remaining time of the first Actor run calculated at the moment of the other Actor call."""

async def main() -> None:
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta

async with Actor:
actor_input = (await Actor.get_input()) or {}
Expand All @@ -94,7 +94,7 @@ async def main() -> None:
assert Actor.configuration.timeout_at is not None
assert Actor.configuration.started_at is not None

remaining_time_after_actor_start = Actor.configuration.timeout_at - datetime.now(tz=timezone.utc)
remaining_time_after_actor_start = Actor.configuration.timeout_at - datetime.now(tz=UTC)

other_timeout = timedelta(seconds=other_run_data.options.timeout_secs)
total_timeout = Actor.configuration.timeout_at - Actor.configuration.started_at
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/test_fixtures.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import TYPE_CHECKING

from crawlee._utils.crypto import crypto_random_object_id
Expand Down Expand Up @@ -64,7 +64,7 @@ async def test_actor_from_source_files(
make_actor: MakeActorFunction,
run_actor: RunActorFunction,
) -> None:
test_started_at = datetime.now(timezone.utc)
test_started_at = datetime.now(UTC)
actor_source_files = {
'src/utils.py': """
from datetime import datetime, timezone
Expand Down Expand Up @@ -93,7 +93,7 @@ async def main():

output_datetime = datetime.fromisoformat(output_record['value'])
assert output_datetime > test_started_at
assert output_datetime < datetime.now(timezone.utc)
assert output_datetime < datetime.now(UTC)


async def test_apify_client_async_works(apify_client_async: ApifyClientAsync) -> None:
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/test_request_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import asyncio
import logging
from datetime import datetime, timezone
from datetime import UTC, datetime
from typing import TYPE_CHECKING, Any, Literal, cast
from unittest import mock

Expand Down Expand Up @@ -979,7 +979,7 @@ async def test_cache_initialization(apify_token: str, monkeypatch: pytest.Monkey
request_queue_name = generate_unique_resource_name('request_queue')
monkeypatch.setenv(ApifyEnvVars.TOKEN, apify_token)

requests = [Request.from_url(f'http://example.com/{i}', handled_at=datetime.now(timezone.utc)) for i in range(10)]
requests = [Request.from_url(f'http://example.com/{i}', handled_at=datetime.now(UTC)) for i in range(10)]

async with Actor:
rq = await Actor.open_request_queue(name=request_queue_name, force_cloud=True)
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/actor/test_actor_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import asyncio
import logging
import warnings
from datetime import datetime, timedelta, timezone
from datetime import UTC, datetime, timedelta
from typing import TYPE_CHECKING

import pytest
Expand Down Expand Up @@ -328,7 +328,7 @@ async def test_get_remaining_time_clamps_negative_to_zero() -> None:
"""Test that _get_remaining_time returns timedelta(0) instead of a negative value when timeout is in the past."""
async with Actor:
Actor.configuration.is_at_home = True
Actor.configuration.timeout_at = datetime.now(tz=timezone.utc) - timedelta(minutes=5)
Actor.configuration.timeout_at = datetime.now(tz=UTC) - timedelta(minutes=5)

result = Actor._get_remaining_time()
assert result is not None
Expand All @@ -339,7 +339,7 @@ async def test_get_remaining_time_returns_positive_when_timeout_in_future() -> N
"""Test that _get_remaining_time returns a positive timedelta when timeout is in the future."""
async with Actor:
Actor.configuration.is_at_home = True
Actor.configuration.timeout_at = datetime.now(tz=timezone.utc) + timedelta(minutes=5)
Actor.configuration.timeout_at = datetime.now(tz=UTC) + timedelta(minutes=5)

result = Actor._get_remaining_time()
assert result is not None
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/storage_clients/test_apify_request_queue_client.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from datetime import datetime, timezone
from datetime import UTC, datetime
from unittest.mock import AsyncMock

import pytest
Expand All @@ -16,7 +16,7 @@ def _make_single_client(
) -> tuple[ApifyRequestQueueSingleClient, AsyncMock]:
if api_client is None:
api_client = AsyncMock()
now = datetime.now(tz=timezone.utc)
now = datetime.now(tz=UTC)
metadata = RequestQueueMetadata(
id='test-rq-id',
name='test-rq',
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_apify_storages.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
import json
from datetime import datetime, timezone
from datetime import UTC, datetime
from pathlib import Path
from unittest import mock
from unittest.mock import AsyncMock
Expand Down Expand Up @@ -38,7 +38,7 @@ async def test_get_additional_cache_key(
additional cache key."""

def create_metadata(id: str) -> StorageMetadata:
now = datetime.now(tz=timezone.utc)
now = datetime.now(tz=UTC)
return StorageMetadata(id=id, name=None, accessed_at=now, created_at=now, modified_at=now)

storage_ids = iter(['1', '2', '3', '1', '3'])
Expand Down
Loading
Loading