earningscall 1.1.0__py3-none-any.whl → 1.1.1__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.
- earningscall/__init__.py +1 -5
- earningscall/api.py +21 -8
- earningscall/errors.py +4 -0
- {earningscall-1.1.0.dist-info → earningscall-1.1.1.dist-info}/METADATA +6 -6
- {earningscall-1.1.0.dist-info → earningscall-1.1.1.dist-info}/RECORD +7 -7
- {earningscall-1.1.0.dist-info → earningscall-1.1.1.dist-info}/WHEEL +0 -0
- {earningscall-1.1.0.dist-info → earningscall-1.1.1.dist-info}/licenses/LICENSE +0 -0
earningscall/__init__.py
CHANGED
@@ -5,10 +5,6 @@ from earningscall.symbols import Symbols, load_symbols
|
|
5
5
|
|
6
6
|
api_key: Optional[str] = None
|
7
7
|
enable_requests_cache: bool = True
|
8
|
-
retry_strategy: Dict[str, Union[str, int, float]] =
|
9
|
-
"strategy": "exponential",
|
10
|
-
"base_delay": 3,
|
11
|
-
"max_attempts": 5,
|
12
|
-
}
|
8
|
+
retry_strategy: Optional[Dict[str, Union[str, int, float]]] = None
|
13
9
|
|
14
10
|
__all__ = ["get_company", "get_all_companies", "get_sp500_companies", "Symbols", "load_symbols"]
|
earningscall/api.py
CHANGED
@@ -5,17 +5,23 @@ import logging
|
|
5
5
|
import os
|
6
6
|
import time
|
7
7
|
from importlib.metadata import PackageNotFoundError
|
8
|
-
from typing import Optional
|
8
|
+
from typing import Dict, Optional, Union
|
9
9
|
|
10
10
|
import requests
|
11
11
|
from requests_cache import CachedSession
|
12
12
|
|
13
13
|
import earningscall
|
14
|
+
from earningscall.errors import InvalidApiKeyError
|
14
15
|
|
15
16
|
log = logging.getLogger(__file__)
|
16
17
|
|
17
|
-
DOMAIN = os.environ.get("
|
18
|
+
DOMAIN = os.environ.get("EARNINGSCALL_DOMAIN", "earningscall.biz")
|
18
19
|
API_BASE = f"https://v2.api.{DOMAIN}"
|
20
|
+
DEFAULT_RETRY_STRATEGY: Dict[str, Union[str, int, float]] = {
|
21
|
+
"strategy": "exponential",
|
22
|
+
"base_delay": 1,
|
23
|
+
"max_attempts": 10,
|
24
|
+
}
|
19
25
|
|
20
26
|
|
21
27
|
def get_api_key():
|
@@ -121,8 +127,9 @@ def do_get(
|
|
121
127
|
full_url = f"{url}?{urllib.parse.urlencode(params)}"
|
122
128
|
log.debug(f"GET: {full_url}")
|
123
129
|
|
124
|
-
|
125
|
-
|
130
|
+
retry_strategy = earningscall.retry_strategy or DEFAULT_RETRY_STRATEGY
|
131
|
+
delay = retry_strategy["base_delay"]
|
132
|
+
max_attempts = int(retry_strategy["max_attempts"])
|
126
133
|
|
127
134
|
for attempt in range(max_attempts):
|
128
135
|
if use_cache and earningscall.enable_requests_cache:
|
@@ -138,16 +145,22 @@ def do_get(
|
|
138
145
|
if is_success(response):
|
139
146
|
return response
|
140
147
|
|
148
|
+
if response.status_code == 401:
|
149
|
+
raise InvalidApiKeyError(
|
150
|
+
"Your API key is invalid. You can get your API key at: https://earningscall.biz/api-key"
|
151
|
+
)
|
152
|
+
|
141
153
|
if not can_retry(response):
|
142
154
|
return response
|
143
155
|
|
144
156
|
if attempt < max_attempts - 1: # Don't sleep after the last attempt
|
145
|
-
if
|
146
|
-
wait_time = delay * (2**attempt) # Exponential backoff:
|
147
|
-
elif
|
148
|
-
wait_time = delay * (attempt + 1) # Linear backoff: 3s ->
|
157
|
+
if retry_strategy["strategy"] == "exponential":
|
158
|
+
wait_time = delay * (2**attempt) # Exponential backoff: 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s
|
159
|
+
elif retry_strategy["strategy"] == "linear":
|
160
|
+
wait_time = delay * (attempt + 1) # Linear backoff: 1s -> 2s -> 3s -> 4s -> 5s -> 6s -> 7s
|
149
161
|
else:
|
150
162
|
raise ValueError("Invalid retry strategy. Must be one of: 'exponential', 'linear'")
|
163
|
+
# TODO: Should we log a warning here? Does the customer want to see this log?
|
151
164
|
log.warning(
|
152
165
|
f"Rate limited (429). Retrying in {wait_time} seconds... (Attempt {attempt + 1}/{max_attempts})"
|
153
166
|
)
|
earningscall/errors.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: earningscall
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.1
|
4
4
|
Summary: The EarningsCall Python library provides convenient access to the EarningsCall API. It includes a pre-defined set of classes for API resources that initialize themselves dynamically from API responses.
|
5
5
|
Project-URL: Homepage, https://earningscall.biz
|
6
6
|
Project-URL: Documentation, https://github.com/EarningsCall/earningscall-python
|
@@ -324,8 +324,8 @@ Depending on your specific requirements, you can adjust the retry strategy. For
|
|
324
324
|
To customize the retry behavior, set the `retry_strategy` variable with the desired parameters:
|
325
325
|
|
326
326
|
- **strategy**: "exponential" | "linear" — defines the type of retry strategy (default is "exponential").
|
327
|
-
- **base_delay**: float (in seconds) — specifies the delay between retries (default is
|
328
|
-
- **max_attempts**: int — sets the maximum number of total request attempts (default is
|
327
|
+
- **base_delay**: float (in seconds) — specifies the delay between retries (default is 1 seconds).
|
328
|
+
- **max_attempts**: int — sets the maximum number of total request attempts (default is 10).
|
329
329
|
|
330
330
|
#### Default Retry Strategy
|
331
331
|
|
@@ -336,8 +336,8 @@ import earningscall
|
|
336
336
|
|
337
337
|
earningscall.retry_strategy = {
|
338
338
|
"strategy": "exponential",
|
339
|
-
"base_delay":
|
340
|
-
"max_attempts":
|
339
|
+
"base_delay": 1,
|
340
|
+
"max_attempts": 10,
|
341
341
|
}
|
342
342
|
```
|
343
343
|
|
@@ -350,7 +350,7 @@ import earningscall
|
|
350
350
|
|
351
351
|
earningscall.retry_strategy = {
|
352
352
|
"strategy": "exponential",
|
353
|
-
"base_delay":
|
353
|
+
"base_delay": 1,
|
354
354
|
"max_attempts": 1,
|
355
355
|
}
|
356
356
|
```
|
@@ -1,14 +1,14 @@
|
|
1
|
-
earningscall/__init__.py,sha256=
|
2
|
-
earningscall/api.py,sha256=
|
1
|
+
earningscall/__init__.py,sha256=6yPTdUeBrKo4sVVW_hJHduTlQUDTw-30BwV5-2PlzYM,413
|
2
|
+
earningscall/api.py,sha256=honHHVfJISlWrikNYNE3CjXAkKJWqCa0Jk4q2cg9v1U,7633
|
3
3
|
earningscall/company.py,sha256=Ie3LwW5GjXsy3_it5F25JjHfbU3pW8Zefhpv3IjIk4U,6609
|
4
|
-
earningscall/errors.py,sha256=
|
4
|
+
earningscall/errors.py,sha256=aLgwrrpMmYThYEZjCGOhqS57a-GoC0xj2BdbtJ20sy8,490
|
5
5
|
earningscall/event.py,sha256=Jf7KPvpeaF9KkeHe46LbL_HIYLXkyHrs3psq-ZY-bkI,692
|
6
6
|
earningscall/exports.py,sha256=YAo3vyX3PTgpKBFYwovVy-9797THrvMrdXWqLEHMtME,1425
|
7
7
|
earningscall/sectors.py,sha256=Xd6DLkAQ_fQkC2s-N9pReC8b_M3iy77OoFftoZj9FWY,5114
|
8
8
|
earningscall/symbols.py,sha256=NxabgKfZZI1YwDLUwh_MlNgyfkR9VZdcU-LqkGWwi28,6521
|
9
9
|
earningscall/transcript.py,sha256=P-CeTYhE5T78SXDHFEJ0AlVUFz2XPxDMtkeiorziBiw,1007
|
10
10
|
earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
|
11
|
-
earningscall-1.1.
|
12
|
-
earningscall-1.1.
|
13
|
-
earningscall-1.1.
|
14
|
-
earningscall-1.1.
|
11
|
+
earningscall-1.1.1.dist-info/METADATA,sha256=3clQWAU4LnVOmlHgW4YMCXIXlxv_49niY0hZtdqjsRE,15446
|
12
|
+
earningscall-1.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
13
|
+
earningscall-1.1.1.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
|
14
|
+
earningscall-1.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|