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 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("ECALL_DOMAIN", "earningscall.biz")
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
- delay = earningscall.retry_strategy["base_delay"]
125
- max_attempts = int(earningscall.retry_strategy["max_attempts"])
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 earningscall.retry_strategy["strategy"] == "exponential":
146
- wait_time = delay * (2**attempt) # Exponential backoff: 3s -> 6s -> 12s -> 24s -> 48s
147
- elif earningscall.retry_strategy["strategy"] == "linear":
148
- wait_time = delay * (attempt + 1) # Linear backoff: 3s -> 6s -> 9s -> 12s -> 15s
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
@@ -22,3 +22,7 @@ class ClientError(BaseError):
22
22
 
23
23
  class InsufficientApiAccessError(ClientError):
24
24
  pass
25
+
26
+
27
+ class InvalidApiKeyError(ClientError):
28
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: earningscall
3
- Version: 1.1.0
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 3 seconds).
328
- - **max_attempts**: int — sets the maximum number of total request attempts (default is 5).
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": 3,
340
- "max_attempts": 5,
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": 3,
353
+ "base_delay": 1,
354
354
  "max_attempts": 1,
355
355
  }
356
356
  ```
@@ -1,14 +1,14 @@
1
- earningscall/__init__.py,sha256=_7Xxi8zoSt98fDwzSpEfjrxgiJsc7UobZBwtsAbt3Lg,477
2
- earningscall/api.py,sha256=H4Z_GcD6RnTCkwGE--imCOsySDLkD9qf4Rj5j-dZHkw,7088
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=EA-d6qIYgQs9csp8JptQiAaYoM0M9HhCGJgKA9GAWPg,440
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.0.dist-info/METADATA,sha256=U7DpkmtPIfIRGfpIB5WM77okwWH2XrLxKRI_adOhv1k,15444
12
- earningscall-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- earningscall-1.1.0.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
14
- earningscall-1.1.0.dist-info/RECORD,,
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,,