apify 2.7.1b6__py3-none-any.whl → 2.7.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of apify might be problematic. Click here for more details.
- apify/_actor.py +6 -42
- apify/_charging.py +9 -15
- apify/_configuration.py +10 -1
- apify/_crypto.py +6 -0
- apify/_models.py +7 -7
- apify/_platform_event_manager.py +36 -20
- apify/_proxy_configuration.py +5 -2
- apify/_utils.py +2 -17
- apify/apify_storage_client/_apify_storage_client.py +1 -1
- apify/log.py +2 -0
- apify/storages/_request_list.py +3 -3
- {apify-2.7.1b6.dist-info → apify-2.7.3.dist-info}/METADATA +3 -2
- {apify-2.7.1b6.dist-info → apify-2.7.3.dist-info}/RECORD +15 -15
- {apify-2.7.1b6.dist-info → apify-2.7.3.dist-info}/WHEEL +0 -0
- {apify-2.7.1b6.dist-info → apify-2.7.3.dist-info}/licenses/LICENSE +0 -0
apify/_actor.py
CHANGED
|
@@ -5,7 +5,7 @@ import os
|
|
|
5
5
|
import sys
|
|
6
6
|
from contextlib import suppress
|
|
7
7
|
from datetime import datetime, timedelta, timezone
|
|
8
|
-
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast, overload
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Callable, Literal, TypeVar, cast, overload
|
|
9
9
|
|
|
10
10
|
from lazy_object_proxy import Proxy
|
|
11
11
|
from more_itertools import flatten
|
|
@@ -13,7 +13,7 @@ from pydantic import AliasChoices
|
|
|
13
13
|
|
|
14
14
|
from apify_client import ApifyClientAsync
|
|
15
15
|
from apify_shared.consts import ActorEnvVars, ActorExitCodes, ApifyEnvVars
|
|
16
|
-
from apify_shared.utils import maybe_extract_enum_member_value
|
|
16
|
+
from apify_shared.utils import ignore_docs, maybe_extract_enum_member_value
|
|
17
17
|
from crawlee import service_locator
|
|
18
18
|
from crawlee.events import (
|
|
19
19
|
Event,
|
|
@@ -39,7 +39,6 @@ from apify.storages import Dataset, KeyValueStore, RequestQueue
|
|
|
39
39
|
|
|
40
40
|
if TYPE_CHECKING:
|
|
41
41
|
import logging
|
|
42
|
-
from collections.abc import Callable
|
|
43
42
|
from types import TracebackType
|
|
44
43
|
|
|
45
44
|
from typing_extensions import Self
|
|
@@ -54,46 +53,9 @@ MainReturnType = TypeVar('MainReturnType')
|
|
|
54
53
|
|
|
55
54
|
|
|
56
55
|
@docs_name('Actor')
|
|
57
|
-
@docs_group('
|
|
56
|
+
@docs_group('Classes')
|
|
58
57
|
class _ActorType:
|
|
59
|
-
"""The
|
|
60
|
-
|
|
61
|
-
Actors are serverless programs running in the cloud that can perform anything from simple actions
|
|
62
|
-
(such as filling out a web form or sending an email) to complex operations (such as crawling an
|
|
63
|
-
entire website or removing duplicates from a large dataset). They are packaged as Docker containers
|
|
64
|
-
which accept well-defined JSON input, perform an action, and optionally produce well-defined output.
|
|
65
|
-
|
|
66
|
-
### References
|
|
67
|
-
|
|
68
|
-
- Apify platform documentation: https://docs.apify.com/platform/actors
|
|
69
|
-
- Actor whitepaper: https://whitepaper.actor/
|
|
70
|
-
|
|
71
|
-
### Usage
|
|
72
|
-
|
|
73
|
-
```python
|
|
74
|
-
import asyncio
|
|
75
|
-
|
|
76
|
-
import httpx
|
|
77
|
-
from apify import Actor
|
|
78
|
-
from bs4 import BeautifulSoup
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
async def main() -> None:
|
|
82
|
-
async with Actor:
|
|
83
|
-
actor_input = await Actor.get_input()
|
|
84
|
-
async with httpx.AsyncClient() as client:
|
|
85
|
-
response = await client.get(actor_input['url'])
|
|
86
|
-
soup = BeautifulSoup(response.content, 'html.parser')
|
|
87
|
-
data = {
|
|
88
|
-
'url': actor_input['url'],
|
|
89
|
-
'title': soup.title.string if soup.title else None,
|
|
90
|
-
}
|
|
91
|
-
await Actor.push_data(data)
|
|
92
|
-
|
|
93
|
-
if __name__ == '__main__':
|
|
94
|
-
asyncio.run(main())
|
|
95
|
-
```
|
|
96
|
-
"""
|
|
58
|
+
"""The class of `Actor`. Only make a new instance if you're absolutely sure you need to."""
|
|
97
59
|
|
|
98
60
|
_is_rebooting = False
|
|
99
61
|
_is_any_instance_initialized = False
|
|
@@ -145,6 +107,7 @@ class _ActorType:
|
|
|
145
107
|
|
|
146
108
|
self._is_initialized = False
|
|
147
109
|
|
|
110
|
+
@ignore_docs
|
|
148
111
|
async def __aenter__(self) -> Self:
|
|
149
112
|
"""Initialize the Actor.
|
|
150
113
|
|
|
@@ -156,6 +119,7 @@ class _ActorType:
|
|
|
156
119
|
await self.init()
|
|
157
120
|
return self
|
|
158
121
|
|
|
122
|
+
@ignore_docs
|
|
159
123
|
async def __aexit__(
|
|
160
124
|
self,
|
|
161
125
|
_exc_type: type[BaseException] | None,
|
apify/_charging.py
CHANGED
|
@@ -4,10 +4,11 @@ import math
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from datetime import datetime, timezone
|
|
6
6
|
from decimal import Decimal
|
|
7
|
-
from typing import TYPE_CHECKING, Protocol
|
|
7
|
+
from typing import TYPE_CHECKING, Protocol, Union
|
|
8
8
|
|
|
9
9
|
from pydantic import TypeAdapter
|
|
10
10
|
|
|
11
|
+
from apify_shared.utils import ignore_docs
|
|
11
12
|
from crawlee._utils.context import ensure_context
|
|
12
13
|
|
|
13
14
|
from apify._models import ActorRun, PricingModel
|
|
@@ -22,21 +23,13 @@ if TYPE_CHECKING:
|
|
|
22
23
|
|
|
23
24
|
from apify._configuration import Configuration
|
|
24
25
|
|
|
25
|
-
run_validator = TypeAdapter[ActorRun | None](ActorRun | None)
|
|
26
26
|
|
|
27
|
+
run_validator: TypeAdapter[ActorRun | None] = TypeAdapter(Union[ActorRun, None])
|
|
27
28
|
|
|
28
|
-
@docs_group('Charging')
|
|
29
|
-
class ChargingManager(Protocol):
|
|
30
|
-
"""Provides fine-grained access to pay-per-event functionality.
|
|
31
|
-
|
|
32
|
-
The ChargingManager allows you to charge for specific events in your Actor when using
|
|
33
|
-
the pay-per-event pricing model. This enables precise cost control and transparent
|
|
34
|
-
billing for different operations within your Actor.
|
|
35
29
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
"""
|
|
30
|
+
@docs_group('Interfaces')
|
|
31
|
+
class ChargingManager(Protocol):
|
|
32
|
+
"""Provides fine-grained access to pay-per-event functionality."""
|
|
40
33
|
|
|
41
34
|
async def charge(self, event_name: str, count: int = 1) -> ChargeResult:
|
|
42
35
|
"""Charge for a specified number of events - sub-operations of the Actor.
|
|
@@ -65,7 +58,7 @@ class ChargingManager(Protocol):
|
|
|
65
58
|
"""
|
|
66
59
|
|
|
67
60
|
|
|
68
|
-
@docs_group('
|
|
61
|
+
@docs_group('Data structures')
|
|
69
62
|
@dataclass(frozen=True)
|
|
70
63
|
class ChargeResult:
|
|
71
64
|
"""Result of the `ChargingManager.charge` method."""
|
|
@@ -80,7 +73,7 @@ class ChargeResult:
|
|
|
80
73
|
"""How many events of each known type can still be charged within the limit."""
|
|
81
74
|
|
|
82
75
|
|
|
83
|
-
@docs_group('
|
|
76
|
+
@docs_group('Data structures')
|
|
84
77
|
@dataclass
|
|
85
78
|
class ActorPricingInfo:
|
|
86
79
|
"""Result of the `ChargingManager.get_pricing_info` method."""
|
|
@@ -98,6 +91,7 @@ class ActorPricingInfo:
|
|
|
98
91
|
"""Price of every known event type."""
|
|
99
92
|
|
|
100
93
|
|
|
94
|
+
@ignore_docs
|
|
101
95
|
class ChargingManagerImplementation(ChargingManager):
|
|
102
96
|
"""Implementation of the `ChargingManager` Protocol - this is only meant to be instantiated internally."""
|
|
103
97
|
|
apify/_configuration.py
CHANGED
|
@@ -25,7 +25,7 @@ def _transform_to_list(value: Any) -> list[str] | None:
|
|
|
25
25
|
return value if isinstance(value, list) else str(value).split(',')
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
@docs_group('
|
|
28
|
+
@docs_group('Classes')
|
|
29
29
|
class Configuration(CrawleeConfiguration):
|
|
30
30
|
"""A class for specifying the configuration of an Actor.
|
|
31
31
|
|
|
@@ -334,6 +334,15 @@ class Configuration(CrawleeConfiguration):
|
|
|
334
334
|
),
|
|
335
335
|
] = None
|
|
336
336
|
|
|
337
|
+
user_is_paying: Annotated[
|
|
338
|
+
bool,
|
|
339
|
+
Field(
|
|
340
|
+
alias='apify_user_is_paying',
|
|
341
|
+
description='True if the user calling the Actor is paying user',
|
|
342
|
+
),
|
|
343
|
+
BeforeValidator(lambda val: False if val == '' else val),
|
|
344
|
+
] = False
|
|
345
|
+
|
|
337
346
|
web_server_port: Annotated[
|
|
338
347
|
int,
|
|
339
348
|
Field(
|
apify/_crypto.py
CHANGED
|
@@ -12,6 +12,7 @@ from cryptography.hazmat.primitives import hashes, serialization
|
|
|
12
12
|
from cryptography.hazmat.primitives.asymmetric import padding, rsa
|
|
13
13
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
14
14
|
|
|
15
|
+
from apify_shared.utils import ignore_docs
|
|
15
16
|
from crawlee._utils.crypto import crypto_random_object_id
|
|
16
17
|
|
|
17
18
|
from apify._consts import ENCRYPTED_INPUT_VALUE_REGEXP, ENCRYPTED_JSON_VALUE_PREFIX, ENCRYPTED_STRING_VALUE_PREFIX
|
|
@@ -21,6 +22,7 @@ ENCRYPTION_IV_LENGTH = 16
|
|
|
21
22
|
ENCRYPTION_AUTH_TAG_LENGTH = 16
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
@ignore_docs
|
|
24
26
|
def public_encrypt(value: str, *, public_key: rsa.RSAPublicKey) -> dict:
|
|
25
27
|
"""Encrypts the given value using AES cipher and the password for encryption using the public key.
|
|
26
28
|
|
|
@@ -64,6 +66,7 @@ def public_encrypt(value: str, *, public_key: rsa.RSAPublicKey) -> dict:
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
|
|
69
|
+
@ignore_docs
|
|
67
70
|
def private_decrypt(
|
|
68
71
|
encrypted_password: str,
|
|
69
72
|
encrypted_value: str,
|
|
@@ -115,6 +118,7 @@ def private_decrypt(
|
|
|
115
118
|
return decipher_bytes.decode('utf-8')
|
|
116
119
|
|
|
117
120
|
|
|
121
|
+
@ignore_docs
|
|
118
122
|
def load_private_key(private_key_file_base64: str, private_key_password: str) -> rsa.RSAPrivateKey:
|
|
119
123
|
private_key = serialization.load_pem_private_key(
|
|
120
124
|
base64.b64decode(private_key_file_base64.encode('utf-8')),
|
|
@@ -134,6 +138,7 @@ def _load_public_key(public_key_file_base64: str) -> rsa.RSAPublicKey:
|
|
|
134
138
|
return public_key
|
|
135
139
|
|
|
136
140
|
|
|
141
|
+
@ignore_docs
|
|
137
142
|
def decrypt_input_secrets(private_key: rsa.RSAPrivateKey, input_data: Any) -> Any:
|
|
138
143
|
"""Decrypt input secrets."""
|
|
139
144
|
if not isinstance(input_data, dict):
|
|
@@ -175,6 +180,7 @@ def encode_base62(num: int) -> str:
|
|
|
175
180
|
return res
|
|
176
181
|
|
|
177
182
|
|
|
183
|
+
@ignore_docs
|
|
178
184
|
def create_hmac_signature(secret_key: str, message: str) -> str:
|
|
179
185
|
"""Generate an HMAC signature and encodes it using Base62. Base62 encoding reduces the signature length.
|
|
180
186
|
|
apify/_models.py
CHANGED
|
@@ -13,10 +13,10 @@ from crawlee._utils.urls import validate_http_url
|
|
|
13
13
|
from apify._utils import docs_group
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
|
-
from
|
|
16
|
+
from typing_extensions import TypeAlias
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@docs_group('
|
|
19
|
+
@docs_group('Data structures')
|
|
20
20
|
class Webhook(BaseModel):
|
|
21
21
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
22
22
|
|
|
@@ -35,14 +35,14 @@ class Webhook(BaseModel):
|
|
|
35
35
|
] = None
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
@docs_group('
|
|
38
|
+
@docs_group('Data structures')
|
|
39
39
|
class ActorRunMeta(BaseModel):
|
|
40
40
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
41
41
|
|
|
42
42
|
origin: Annotated[MetaOrigin, Field()]
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
@docs_group('
|
|
45
|
+
@docs_group('Data structures')
|
|
46
46
|
class ActorRunStats(BaseModel):
|
|
47
47
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
48
48
|
|
|
@@ -63,7 +63,7 @@ class ActorRunStats(BaseModel):
|
|
|
63
63
|
compute_units: Annotated[float, Field(alias='computeUnits')]
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
@docs_group('
|
|
66
|
+
@docs_group('Data structures')
|
|
67
67
|
class ActorRunOptions(BaseModel):
|
|
68
68
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
69
69
|
|
|
@@ -74,7 +74,7 @@ class ActorRunOptions(BaseModel):
|
|
|
74
74
|
max_total_charge_usd: Annotated[Decimal | None, Field(alias='maxTotalChargeUsd')] = None
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
@docs_group('
|
|
77
|
+
@docs_group('Data structures')
|
|
78
78
|
class ActorRunUsage(BaseModel):
|
|
79
79
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
80
80
|
|
|
@@ -92,7 +92,7 @@ class ActorRunUsage(BaseModel):
|
|
|
92
92
|
proxy_serps: Annotated[float | None, Field(alias='PROXY_SERPS')] = None
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
@docs_group('
|
|
95
|
+
@docs_group('Data structures')
|
|
96
96
|
class ActorRun(BaseModel):
|
|
97
97
|
__model_config__ = ConfigDict(populate_by_name=True)
|
|
98
98
|
|
apify/_platform_event_manager.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from datetime import datetime
|
|
5
|
-
from typing import TYPE_CHECKING, Annotated, Any, Literal
|
|
5
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal, Union
|
|
6
6
|
|
|
7
7
|
import websockets.asyncio.client
|
|
8
8
|
from pydantic import BaseModel, Discriminator, Field, TypeAdapter
|
|
@@ -27,10 +27,17 @@ if TYPE_CHECKING:
|
|
|
27
27
|
|
|
28
28
|
from apify._configuration import Configuration
|
|
29
29
|
|
|
30
|
+
|
|
30
31
|
__all__ = ['EventManager', 'LocalEventManager', 'PlatformEventManager']
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
@docs_group('
|
|
34
|
+
@docs_group('Data structures')
|
|
35
|
+
class PersistStateEvent(BaseModel):
|
|
36
|
+
name: Literal[Event.PERSIST_STATE]
|
|
37
|
+
data: Annotated[EventPersistStateData, Field(default_factory=lambda: EventPersistStateData(is_migrating=False))]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@docs_group('Data structures')
|
|
34
41
|
class SystemInfoEventData(BaseModel):
|
|
35
42
|
mem_avg_bytes: Annotated[float, Field(alias='memAvgBytes')]
|
|
36
43
|
mem_current_bytes: Annotated[float, Field(alias='memCurrentBytes')]
|
|
@@ -57,37 +64,31 @@ class SystemInfoEventData(BaseModel):
|
|
|
57
64
|
)
|
|
58
65
|
|
|
59
66
|
|
|
60
|
-
@docs_group('
|
|
61
|
-
class PersistStateEvent(BaseModel):
|
|
62
|
-
name: Literal[Event.PERSIST_STATE]
|
|
63
|
-
data: Annotated[EventPersistStateData, Field(default_factory=lambda: EventPersistStateData(is_migrating=False))]
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
@docs_group('Events')
|
|
67
|
+
@docs_group('Data structures')
|
|
67
68
|
class SystemInfoEvent(BaseModel):
|
|
68
69
|
name: Literal[Event.SYSTEM_INFO]
|
|
69
70
|
data: SystemInfoEventData
|
|
70
71
|
|
|
71
72
|
|
|
72
|
-
@docs_group('
|
|
73
|
+
@docs_group('Data structures')
|
|
73
74
|
class MigratingEvent(BaseModel):
|
|
74
75
|
name: Literal[Event.MIGRATING]
|
|
75
76
|
data: Annotated[EventMigratingData, Field(default_factory=EventMigratingData)]
|
|
76
77
|
|
|
77
78
|
|
|
78
|
-
@docs_group('
|
|
79
|
+
@docs_group('Data structures')
|
|
79
80
|
class AbortingEvent(BaseModel):
|
|
80
81
|
name: Literal[Event.ABORTING]
|
|
81
82
|
data: Annotated[EventAbortingData, Field(default_factory=EventAbortingData)]
|
|
82
83
|
|
|
83
84
|
|
|
84
|
-
@docs_group('
|
|
85
|
+
@docs_group('Data structures')
|
|
85
86
|
class ExitEvent(BaseModel):
|
|
86
87
|
name: Literal[Event.EXIT]
|
|
87
88
|
data: Annotated[EventExitData, Field(default_factory=EventExitData)]
|
|
88
89
|
|
|
89
90
|
|
|
90
|
-
@docs_group('
|
|
91
|
+
@docs_group('Data structures')
|
|
91
92
|
class EventWithoutData(BaseModel):
|
|
92
93
|
name: Literal[
|
|
93
94
|
Event.SESSION_RETIRED,
|
|
@@ -100,26 +101,41 @@ class EventWithoutData(BaseModel):
|
|
|
100
101
|
data: Any = None
|
|
101
102
|
|
|
102
103
|
|
|
103
|
-
@docs_group('
|
|
104
|
+
@docs_group('Data structures')
|
|
104
105
|
class DeprecatedEvent(BaseModel):
|
|
105
106
|
name: Literal['cpuInfo']
|
|
106
107
|
data: Annotated[dict[str, Any], Field(default_factory=dict)]
|
|
107
108
|
|
|
108
109
|
|
|
109
|
-
@docs_group('
|
|
110
|
+
@docs_group('Data structures')
|
|
110
111
|
class UnknownEvent(BaseModel):
|
|
111
112
|
name: str
|
|
112
113
|
data: Annotated[dict[str, Any], Field(default_factory=dict)]
|
|
113
114
|
|
|
114
115
|
|
|
115
|
-
EventMessage =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
+
]
|
|
119
135
|
)
|
|
120
136
|
|
|
121
137
|
|
|
122
|
-
@docs_group('
|
|
138
|
+
@docs_group('Classes')
|
|
123
139
|
class PlatformEventManager(EventManager):
|
|
124
140
|
"""A class for managing Actor events.
|
|
125
141
|
|
apify/_proxy_configuration.py
CHANGED
|
@@ -10,6 +10,7 @@ from urllib.parse import urljoin, urlparse
|
|
|
10
10
|
import httpx
|
|
11
11
|
|
|
12
12
|
from apify_shared.consts import ApifyEnvVars
|
|
13
|
+
from apify_shared.utils import ignore_docs
|
|
13
14
|
from crawlee.proxy_configuration import ProxyConfiguration as CrawleeProxyConfiguration
|
|
14
15
|
from crawlee.proxy_configuration import ProxyInfo as CrawleeProxyInfo
|
|
15
16
|
from crawlee.proxy_configuration import _NewUrlFunction
|
|
@@ -27,6 +28,7 @@ COUNTRY_CODE_REGEX = re.compile(r'^[A-Z]{2}$')
|
|
|
27
28
|
SESSION_ID_MAX_LENGTH = 50
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
@ignore_docs
|
|
30
32
|
def is_url(url: str) -> bool:
|
|
31
33
|
"""Check if the given string is a valid URL."""
|
|
32
34
|
try:
|
|
@@ -67,7 +69,7 @@ def _check(
|
|
|
67
69
|
raise ValueError(f'{error_str} does not match pattern {pattern.pattern!r}')
|
|
68
70
|
|
|
69
71
|
|
|
70
|
-
@docs_group('
|
|
72
|
+
@docs_group('Classes')
|
|
71
73
|
@dataclass
|
|
72
74
|
class ProxyInfo(CrawleeProxyInfo):
|
|
73
75
|
"""Provides information about a proxy connection that is used for requests."""
|
|
@@ -87,7 +89,7 @@ class ProxyInfo(CrawleeProxyInfo):
|
|
|
87
89
|
"""
|
|
88
90
|
|
|
89
91
|
|
|
90
|
-
@docs_group('
|
|
92
|
+
@docs_group('Classes')
|
|
91
93
|
class ProxyConfiguration(CrawleeProxyConfiguration):
|
|
92
94
|
"""Configures a connection to a proxy server with the provided options.
|
|
93
95
|
|
|
@@ -102,6 +104,7 @@ class ProxyConfiguration(CrawleeProxyConfiguration):
|
|
|
102
104
|
|
|
103
105
|
_configuration: Configuration
|
|
104
106
|
|
|
107
|
+
@ignore_docs
|
|
105
108
|
def __init__(
|
|
106
109
|
self,
|
|
107
110
|
*,
|
apify/_utils.py
CHANGED
|
@@ -3,10 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import builtins
|
|
4
4
|
import sys
|
|
5
5
|
from importlib import metadata
|
|
6
|
-
from typing import
|
|
7
|
-
|
|
8
|
-
if TYPE_CHECKING:
|
|
9
|
-
from collections.abc import Callable
|
|
6
|
+
from typing import Callable, Literal
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
def get_system_info() -> dict:
|
|
@@ -30,19 +27,7 @@ def is_running_in_ipython() -> bool:
|
|
|
30
27
|
return getattr(builtins, '__IPYTHON__', False)
|
|
31
28
|
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
GroupName = Literal[
|
|
35
|
-
'Actor',
|
|
36
|
-
'Charging',
|
|
37
|
-
'Configuration',
|
|
38
|
-
'Event data',
|
|
39
|
-
'Event managers',
|
|
40
|
-
'Events',
|
|
41
|
-
'Request loaders',
|
|
42
|
-
'Storage clients',
|
|
43
|
-
'Storage data',
|
|
44
|
-
'Storages',
|
|
45
|
-
]
|
|
30
|
+
GroupName = Literal['Classes', 'Abstract classes', 'Interfaces', 'Data structures', 'Errors', 'Functions']
|
|
46
31
|
|
|
47
32
|
|
|
48
33
|
def docs_group(group_name: GroupName) -> Callable: # noqa: ARG001
|
apify/log.py
CHANGED
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
+
from apify_shared.utils import ignore_docs
|
|
5
6
|
from crawlee._log_config import CrawleeLogFormatter, configure_logger, get_configured_log_level
|
|
6
7
|
|
|
7
8
|
# Name of the logger used throughout the library (resolves to 'apify')
|
|
@@ -11,6 +12,7 @@ logger_name = __name__.split('.')[0]
|
|
|
11
12
|
logger = logging.getLogger(logger_name)
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
@ignore_docs
|
|
14
16
|
class ActorLogFormatter(CrawleeLogFormatter): # noqa: D101 (Inherited from parent class)
|
|
15
17
|
pass
|
|
16
18
|
|
apify/storages/_request_list.py
CHANGED
|
@@ -4,7 +4,7 @@ import asyncio
|
|
|
4
4
|
import re
|
|
5
5
|
from asyncio import Task
|
|
6
6
|
from functools import partial
|
|
7
|
-
from typing import Annotated, Any
|
|
7
|
+
from typing import Annotated, Any, Union
|
|
8
8
|
|
|
9
9
|
from pydantic import BaseModel, Field, TypeAdapter
|
|
10
10
|
|
|
@@ -35,10 +35,10 @@ class _SimpleUrlInput(_RequestDetails):
|
|
|
35
35
|
url: str
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
url_input_adapter = TypeAdapter(list[_RequestsFromUrlInput
|
|
38
|
+
url_input_adapter = TypeAdapter(list[Union[_RequestsFromUrlInput, _SimpleUrlInput]])
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
@docs_group('
|
|
41
|
+
@docs_group('Classes')
|
|
42
42
|
class RequestList(CrawleeRequestList):
|
|
43
43
|
"""Extends crawlee RequestList.
|
|
44
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apify
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.3
|
|
4
4
|
Summary: Apify SDK for Python
|
|
5
5
|
Project-URL: Apify Homepage, https://apify.com
|
|
6
6
|
Project-URL: Changelog, https://docs.apify.com/sdk/python/docs/changelog
|
|
@@ -219,12 +219,13 @@ Classifier: Environment :: Console
|
|
|
219
219
|
Classifier: Intended Audience :: Developers
|
|
220
220
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
221
221
|
Classifier: Operating System :: OS Independent
|
|
222
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
222
223
|
Classifier: Programming Language :: Python :: 3.10
|
|
223
224
|
Classifier: Programming Language :: Python :: 3.11
|
|
224
225
|
Classifier: Programming Language :: Python :: 3.12
|
|
225
226
|
Classifier: Programming Language :: Python :: 3.13
|
|
226
227
|
Classifier: Topic :: Software Development :: Libraries
|
|
227
|
-
Requires-Python: >=3.
|
|
228
|
+
Requires-Python: >=3.9
|
|
228
229
|
Requires-Dist: apify-client<2.0.0
|
|
229
230
|
Requires-Dist: apify-shared<2.0.0
|
|
230
231
|
Requires-Dist: crawlee~=0.6.0
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
apify/__init__.py,sha256=HpgKg2FZWJuSPfDygzJ62psylhw4NN4tKFnoYUIhcd4,838
|
|
2
|
-
apify/_actor.py,sha256=
|
|
3
|
-
apify/_charging.py,sha256=
|
|
4
|
-
apify/_configuration.py,sha256=
|
|
2
|
+
apify/_actor.py,sha256=nEuSeGjBIV_IkdFGCVxGKItzVasM2BzyVP2SYvzavvI,51882
|
|
3
|
+
apify/_charging.py,sha256=fFCwg2NL6qtGvnyddp8a-eyhsiaO8-vPEGQMXZ-ZUcU,12225
|
|
4
|
+
apify/_configuration.py,sha256=qICQYEn3yxPy0rRgDfXcdVFqNm27m-a-JqpnNWO2g64,12179
|
|
5
5
|
apify/_consts.py,sha256=CjhyEJ4Mi0lcIrzfqz8dN7nPJWGjCeBrrXQy1PZ6zRI,440
|
|
6
|
-
apify/_crypto.py,sha256=
|
|
7
|
-
apify/_models.py,sha256
|
|
8
|
-
apify/_platform_event_manager.py,sha256=
|
|
9
|
-
apify/_proxy_configuration.py,sha256=
|
|
10
|
-
apify/_utils.py,sha256=
|
|
11
|
-
apify/log.py,sha256
|
|
6
|
+
apify/_crypto.py,sha256=UICTbzjhIKV74biisdtr3kx4c9AO-cKGJnP-XlSTe4E,6960
|
|
7
|
+
apify/_models.py,sha256=-Y0rljBJWxMMCp8iDCTG4UV3bEvNZzp-kx2SYbPfeIY,7919
|
|
8
|
+
apify/_platform_event_manager.py,sha256=igi9dRTfB7t0mRBM1bCfzMh7RBbr5adrJ0iRymUQ8S8,7990
|
|
9
|
+
apify/_proxy_configuration.py,sha256=eMeYr9mr2ITURBmgZw4Cel9kfkiLhdaxE47EDh-3okM,13091
|
|
10
|
+
apify/_utils.py,sha256=7YL7VhmNND0XARsXtPQWWQCyK4825n-ZVB8n9cgWm0A,1838
|
|
11
|
+
apify/log.py,sha256=j-E4t-WeA93bc1NCQRG8sTntehQCiiN8ia-MdQe3_Ts,1291
|
|
12
12
|
apify/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
apify/apify_storage_client/__init__.py,sha256=-UbR68bFsDR6ln8OFs4t50eqcnY36hujO-SeOt-KmcA,114
|
|
14
|
-
apify/apify_storage_client/_apify_storage_client.py,sha256=
|
|
14
|
+
apify/apify_storage_client/_apify_storage_client.py,sha256=qeWYsEQGeyyhJzS9TZTQFNqdSl8JzHz_4_HDKGY4I_Y,2736
|
|
15
15
|
apify/apify_storage_client/_dataset_client.py,sha256=9RxxhrJMic5QRJn2Vl4J-FnSlEigIpYW5Z_2B1dcRzM,5597
|
|
16
16
|
apify/apify_storage_client/_dataset_collection_client.py,sha256=gf5skMTkfpGhEscRy5bgo13vznxGZrSd7w9Ivh3Usyc,1516
|
|
17
17
|
apify/apify_storage_client/_key_value_store_client.py,sha256=OCFUAW0o-8KQvUpL8zmlZrpU3yRmDKdsO2529H2v40I,4002
|
|
@@ -36,9 +36,9 @@ apify/scrapy/pipelines/__init__.py,sha256=GWPeLN_Zwj8vRBWtXW6DaxdB7mvyQ7Jw5Tz1cc
|
|
|
36
36
|
apify/scrapy/pipelines/actor_dataset_push.py,sha256=XUUyznQTD-E3wYUUFt2WAOnWhbnRrY0WuedlfYfYhDI,846
|
|
37
37
|
apify/scrapy/pipelines/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
apify/storages/__init__.py,sha256=FW-z6ubuPnHGM-Wp15T8mR5q6lnpDGrCW-IkgZd5L30,177
|
|
39
|
-
apify/storages/_request_list.py,sha256=
|
|
39
|
+
apify/storages/_request_list.py,sha256=FCC4X2MX2V8vLZBCUi5Q1qg9w62y9UkF4ptOqyPVhG8,6052
|
|
40
40
|
apify/storages/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
-
apify-2.7.
|
|
42
|
-
apify-2.7.
|
|
43
|
-
apify-2.7.
|
|
44
|
-
apify-2.7.
|
|
41
|
+
apify-2.7.3.dist-info/METADATA,sha256=4z_Jhxs3dbwcl24FvTuk_vtMof4pnjCPjlvMxf-Zp0M,21768
|
|
42
|
+
apify-2.7.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
43
|
+
apify-2.7.3.dist-info/licenses/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
|
|
44
|
+
apify-2.7.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|