earningscall 1.1.1__py3-none-any.whl → 1.2.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 +9 -2
- earningscall/api.py +14 -3
- earningscall/calendar.py +30 -0
- earningscall/company.py +4 -1
- earningscall/exports.py +43 -2
- {earningscall-1.1.1.dist-info → earningscall-1.2.1.dist-info}/METADATA +29 -2
- earningscall-1.2.1.dist-info/RECORD +15 -0
- earningscall-1.1.1.dist-info/RECORD +0 -14
- {earningscall-1.1.1.dist-info → earningscall-1.2.1.dist-info}/WHEEL +0 -0
- {earningscall-1.1.1.dist-info → earningscall-1.2.1.dist-info}/licenses/LICENSE +0 -0
earningscall/__init__.py
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
from typing import Dict, Optional, Union
|
2
2
|
|
3
|
-
from earningscall.exports import get_company, get_all_companies, get_sp500_companies
|
3
|
+
from earningscall.exports import get_company, get_all_companies, get_sp500_companies, get_calendar
|
4
4
|
from earningscall.symbols import Symbols, load_symbols
|
5
5
|
|
6
6
|
api_key: Optional[str] = None
|
7
7
|
enable_requests_cache: bool = True
|
8
8
|
retry_strategy: Optional[Dict[str, Union[str, int, float]]] = None
|
9
9
|
|
10
|
-
__all__ = [
|
10
|
+
__all__ = [
|
11
|
+
"get_company",
|
12
|
+
"get_all_companies",
|
13
|
+
"get_sp500_companies",
|
14
|
+
"Symbols",
|
15
|
+
"load_symbols",
|
16
|
+
"get_calendar",
|
17
|
+
]
|
earningscall/api.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import importlib
|
2
|
-
import platform
|
3
|
-
import urllib.parse
|
4
2
|
import logging
|
5
3
|
import os
|
4
|
+
import platform
|
6
5
|
import time
|
6
|
+
import urllib.parse
|
7
7
|
from importlib.metadata import PackageNotFoundError
|
8
8
|
from typing import Dict, Optional, Union
|
9
9
|
|
@@ -169,7 +169,18 @@ def do_get(
|
|
169
169
|
return response # Return the last response if all retries failed
|
170
170
|
|
171
171
|
|
172
|
-
def
|
172
|
+
def get_calendar_api_operation(year: int, month: int, day: int) -> dict:
|
173
|
+
params = {
|
174
|
+
"year": str(year),
|
175
|
+
"month": str(month),
|
176
|
+
"day": str(day),
|
177
|
+
}
|
178
|
+
response = do_get("calendar", params=params)
|
179
|
+
response.raise_for_status()
|
180
|
+
return response.json()
|
181
|
+
|
182
|
+
|
183
|
+
def get_events(exchange: str, symbol: str) -> Optional[dict]:
|
173
184
|
params = {
|
174
185
|
"exchange": exchange,
|
175
186
|
"symbol": symbol,
|
earningscall/calendar.py
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from datetime import datetime
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from dataclasses_json import config
|
6
|
+
from dataclasses_json import dataclass_json
|
7
|
+
from marshmallow import fields
|
8
|
+
|
9
|
+
|
10
|
+
@dataclass_json
|
11
|
+
@dataclass
|
12
|
+
class CalendarEvent:
|
13
|
+
"""
|
14
|
+
CalendarEvent
|
15
|
+
"""
|
16
|
+
|
17
|
+
company_name: str
|
18
|
+
exchange: str
|
19
|
+
symbol: str
|
20
|
+
year: int
|
21
|
+
quarter: int
|
22
|
+
transcript_ready: bool
|
23
|
+
conference_date: Optional[datetime] = field(
|
24
|
+
default=None,
|
25
|
+
metadata=config(
|
26
|
+
encoder=lambda date: date.isoformat() if date else None,
|
27
|
+
decoder=lambda date: datetime.fromisoformat(date) if date else None,
|
28
|
+
mm_field=fields.DateTime(format="iso"),
|
29
|
+
),
|
30
|
+
)
|
earningscall/company.py
CHANGED
@@ -93,7 +93,10 @@ class Company:
|
|
93
93
|
if 2 <= level <= 3:
|
94
94
|
transcript.text = " ".join(map(lambda spk: spk.text, transcript.speakers))
|
95
95
|
elif level == 4:
|
96
|
-
|
96
|
+
if transcript.questions_and_answers:
|
97
|
+
transcript.text = " ".join([transcript.prepared_remarks, transcript.questions_and_answers])
|
98
|
+
else:
|
99
|
+
transcript.text = transcript.prepared_remarks
|
97
100
|
if transcript.speaker_name_map_v2:
|
98
101
|
for speaker in transcript.speakers:
|
99
102
|
speaker.speaker_info = transcript.speaker_name_map_v2.get(speaker.speaker)
|
earningscall/exports.py
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
-
|
1
|
+
import datetime
|
2
|
+
from datetime import date, timedelta
|
3
|
+
from typing import List, Optional, Iterator
|
2
4
|
|
3
|
-
|
5
|
+
import requests
|
6
|
+
|
7
|
+
from earningscall import api
|
8
|
+
from earningscall.api import get_sp500_companies_txt_file, is_demo_account
|
9
|
+
from earningscall.calendar import CalendarEvent
|
4
10
|
from earningscall.company import Company
|
11
|
+
from earningscall.errors import InsufficientApiAccessError
|
5
12
|
from earningscall.symbols import get_symbols
|
6
13
|
|
7
14
|
|
@@ -43,3 +50,37 @@ def get_sp500_companies() -> Iterator[Company]:
|
|
43
50
|
company_info = get_symbols().lookup_company(ticker_symbol)
|
44
51
|
if company_info:
|
45
52
|
yield Company(company_info=company_info)
|
53
|
+
|
54
|
+
|
55
|
+
def get_calendar(input_date: date) -> List[CalendarEvent]:
|
56
|
+
"""
|
57
|
+
Get the earnings event calendar for a given input date.
|
58
|
+
|
59
|
+
:param date input_date: The date to get the calendar for.
|
60
|
+
|
61
|
+
:return: A list of CalendarEvent objects.
|
62
|
+
"""
|
63
|
+
if not input_date:
|
64
|
+
raise ValueError("Date is required")
|
65
|
+
if isinstance(input_date, datetime.datetime):
|
66
|
+
input_date = input_date.date()
|
67
|
+
if not isinstance(input_date, date):
|
68
|
+
raise ValueError("Date must be a date object")
|
69
|
+
if input_date < date(2018, 1, 1):
|
70
|
+
raise ValueError("input_date must be greater than or equal to 2018-01-01")
|
71
|
+
# Check if input_date is greater than 30 days from today
|
72
|
+
if input_date > datetime.datetime.now().date() + timedelta(days=30):
|
73
|
+
raise ValueError("input_date must be less than 30 days from today")
|
74
|
+
if is_demo_account() and input_date != date(2025, 1, 10):
|
75
|
+
raise InsufficientApiAccessError(
|
76
|
+
f"\"{input_date}\" requires an API Key for access. To get your API Key,"
|
77
|
+
f" see: https://earningscall.biz/api-pricing"
|
78
|
+
)
|
79
|
+
try:
|
80
|
+
json_data = api.get_calendar_api_operation(input_date.year, input_date.month, input_date.day)
|
81
|
+
return [CalendarEvent.from_dict(event) for event in json_data] # type: ignore
|
82
|
+
except requests.exceptions.HTTPError as error:
|
83
|
+
if error.response.status_code == 404:
|
84
|
+
# Calendar Date not found, simply return an empty list
|
85
|
+
return []
|
86
|
+
raise error
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: earningscall
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.2.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
|
@@ -260,6 +260,34 @@ print("Downloading audio file for Apple Inc. Q3 2021...")
|
|
260
260
|
audio_file = company.download_audio_file(year=2021, quarter=3, file_name="Apple Q3 2021.mp3")
|
261
261
|
```
|
262
262
|
|
263
|
+
## Get Earnings Event Calendar
|
264
|
+
|
265
|
+
```python
|
266
|
+
from datetime import date
|
267
|
+
|
268
|
+
from earningscall import get_calendar
|
269
|
+
|
270
|
+
calendar = get_calendar(date(2025, 1, 10))
|
271
|
+
|
272
|
+
for event in calendar:
|
273
|
+
print(f"{event.company_name} - Q{event.quarter} {event.year} on: {event.conference_date.astimezone().isoformat()} Transcript Ready: {event.transcript_ready}")
|
274
|
+
```
|
275
|
+
|
276
|
+
Output
|
277
|
+
|
278
|
+
```text
|
279
|
+
Tilray Brands, Inc. - Q2 2025 on: 2025-01-10T07:30:00-06:00 Transcript Ready: True
|
280
|
+
Walgreens Boots Alliance, Inc. - Q1 2025 on: 2025-01-10T07:30:00-06:00 Transcript Ready: True
|
281
|
+
Neogen Corporation - Q2 2025 on: 2025-01-10T07:30:00-06:00 Transcript Ready: True
|
282
|
+
E2open Parent Holdings, Inc. - Q3 2025 on: 2025-01-10T07:30:00-06:00 Transcript Ready: True
|
283
|
+
TD SYNNEX Corporation - Q4 2024 on: 2025-01-10T08:00:00-06:00 Transcript Ready: True
|
284
|
+
Delta Air Lines, Inc. - Q4 2024 on: 2025-01-10T09:00:00-06:00 Transcript Ready: True
|
285
|
+
Constellation Brands, Inc. - Q3 2025 on: 2025-01-10T09:30:00-06:00 Transcript Ready: True
|
286
|
+
PriceSmart, Inc. - Q1 2025 on: 2025-01-10T11:00:00-06:00 Transcript Ready: True
|
287
|
+
KORU Medical Systems, Inc. - Q4 2024 on: 2025-01-10T15:30:00-06:00 Transcript Ready: True
|
288
|
+
WD-40 Company - Q1 2025 on: 2025-01-10T16:00:00-06:00 Transcript Ready: True
|
289
|
+
```
|
290
|
+
|
263
291
|
## List All Companies
|
264
292
|
|
265
293
|
```python
|
@@ -297,7 +325,6 @@ for company in get_sp500_companies():
|
|
297
325
|
print(f"{company.company_info} -- {company.company_info.sector} -- {company.company_info.industry}")
|
298
326
|
```
|
299
327
|
|
300
|
-
|
301
328
|
## Advanced
|
302
329
|
|
303
330
|
### Disable Caching
|
@@ -0,0 +1,15 @@
|
|
1
|
+
earningscall/__init__.py,sha256=J1cBpSRDBivNtYDB-LIMNBZu6rQ3-_1eCY6ACFHlHhE,470
|
2
|
+
earningscall/api.py,sha256=zI7XrxC73pJXZX9Qe1te-EKVS3G-0VVz5FBiuFbi-W8,7936
|
3
|
+
earningscall/calendar.py,sha256=nQcb0UsVwCDhvvcr7dqdY0PCqdVGohB7JDON7jtbRyM,725
|
4
|
+
earningscall/company.py,sha256=7ISobyp3gSj9f1bj53FvmzCCOBLzfqk_uVO_5maDTac,6754
|
5
|
+
earningscall/errors.py,sha256=aLgwrrpMmYThYEZjCGOhqS57a-GoC0xj2BdbtJ20sy8,490
|
6
|
+
earningscall/event.py,sha256=Jf7KPvpeaF9KkeHe46LbL_HIYLXkyHrs3psq-ZY-bkI,692
|
7
|
+
earningscall/exports.py,sha256=G9eZqX_QydfS5O039Wa0rl4Si3KrC_pGyBZ_cxfUrtI,3147
|
8
|
+
earningscall/sectors.py,sha256=Xd6DLkAQ_fQkC2s-N9pReC8b_M3iy77OoFftoZj9FWY,5114
|
9
|
+
earningscall/symbols.py,sha256=NxabgKfZZI1YwDLUwh_MlNgyfkR9VZdcU-LqkGWwi28,6521
|
10
|
+
earningscall/transcript.py,sha256=P-CeTYhE5T78SXDHFEJ0AlVUFz2XPxDMtkeiorziBiw,1007
|
11
|
+
earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
|
12
|
+
earningscall-1.2.1.dist-info/METADATA,sha256=83qqm2w9Npv1Pkj5g0B72ht2kiLIy8kpPCKVIA3hAAg,16667
|
13
|
+
earningscall-1.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
14
|
+
earningscall-1.2.1.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
|
15
|
+
earningscall-1.2.1.dist-info/RECORD,,
|
@@ -1,14 +0,0 @@
|
|
1
|
-
earningscall/__init__.py,sha256=6yPTdUeBrKo4sVVW_hJHduTlQUDTw-30BwV5-2PlzYM,413
|
2
|
-
earningscall/api.py,sha256=honHHVfJISlWrikNYNE3CjXAkKJWqCa0Jk4q2cg9v1U,7633
|
3
|
-
earningscall/company.py,sha256=Ie3LwW5GjXsy3_it5F25JjHfbU3pW8Zefhpv3IjIk4U,6609
|
4
|
-
earningscall/errors.py,sha256=aLgwrrpMmYThYEZjCGOhqS57a-GoC0xj2BdbtJ20sy8,490
|
5
|
-
earningscall/event.py,sha256=Jf7KPvpeaF9KkeHe46LbL_HIYLXkyHrs3psq-ZY-bkI,692
|
6
|
-
earningscall/exports.py,sha256=YAo3vyX3PTgpKBFYwovVy-9797THrvMrdXWqLEHMtME,1425
|
7
|
-
earningscall/sectors.py,sha256=Xd6DLkAQ_fQkC2s-N9pReC8b_M3iy77OoFftoZj9FWY,5114
|
8
|
-
earningscall/symbols.py,sha256=NxabgKfZZI1YwDLUwh_MlNgyfkR9VZdcU-LqkGWwi28,6521
|
9
|
-
earningscall/transcript.py,sha256=P-CeTYhE5T78SXDHFEJ0AlVUFz2XPxDMtkeiorziBiw,1007
|
10
|
-
earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
|
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
|