earningscall 0.0.10__py3-none-any.whl → 0.0.12__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
@@ -4,3 +4,5 @@ from earningscall.exports import get_company, get_all_companies, get_sp500_compa
4
4
  from earningscall.symbols import Symbols, load_symbols
5
5
 
6
6
  api_key: Optional[str] = None
7
+
8
+ __all__ = ["get_company", "get_all_companies", "get_sp500_companies", "Symbols", "load_symbols"]
earningscall/api.py CHANGED
@@ -27,8 +27,7 @@ def is_demo_account():
27
27
  return get_api_key() == "demo"
28
28
 
29
29
 
30
- def get_events(exchange: str,
31
- symbol: str):
30
+ def get_events(exchange: str, symbol: str):
32
31
 
33
32
  log.debug(f"get_events exchange: {exchange} symbol: {symbol}")
34
33
  params = {
@@ -42,10 +41,7 @@ def get_events(exchange: str,
42
41
  return response.json()
43
42
 
44
43
 
45
- def get_transcript(exchange: str,
46
- symbol: str,
47
- year: int,
48
- quarter: int) -> Optional[str]:
44
+ def get_transcript(exchange: str, symbol: str, year: int, quarter: int) -> Optional[str]:
49
45
 
50
46
  log.debug(f"get_transcript year: {year} quarter: {quarter}")
51
47
  params = {
@@ -80,3 +76,9 @@ def get_sp500_companies_txt_file():
80
76
  if response.status_code != 200:
81
77
  return None
82
78
  return response.text
79
+
80
+
81
+ # def do_something():
82
+ # session = CachedSession('demo_cache', cache_control=True)
83
+ #
84
+ # # CachedSession()
earningscall/company.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Optional
2
+ from typing import Optional, List
3
3
 
4
4
  from earningscall import api
5
5
  from earningscall.event import EarningsEvent
@@ -12,8 +12,8 @@ log = logging.getLogger(__file__)
12
12
  class Company:
13
13
 
14
14
  company_info: CompanyInfo
15
- name: str
16
- _events: [EarningsEvent]
15
+ name: Optional[str]
16
+ _events: Optional[List[EarningsEvent]]
17
17
 
18
18
  def __init__(self, company_info: CompanyInfo):
19
19
  if not company_info:
@@ -25,31 +25,31 @@ class Company:
25
25
  def __str__(self):
26
26
  return str(self.name)
27
27
 
28
- def name(self) -> str:
29
- return self.company_info.name
30
-
31
- def _get_events(self):
28
+ def _get_events(self) -> List[EarningsEvent]:
29
+ if not self.company_info.exchange or not self.company_info.symbol:
30
+ return []
32
31
  raw_response = api.get_events(self.company_info.exchange, self.company_info.symbol)
33
32
  if not raw_response:
34
33
  return []
35
- return [EarningsEvent.from_dict(event) for event in raw_response["events"]]
34
+ return [EarningsEvent.from_dict(event) for event in raw_response["events"]] # type: ignore
36
35
 
37
- def events(self) -> [EarningsEvent]:
36
+ def events(self) -> List[EarningsEvent]:
38
37
  if not self._events:
39
38
  self._events = self._get_events()
40
39
  return self._events
41
40
 
42
- def get_transcript(self,
43
- year: Optional[int] = None,
44
- quarter: Optional[int] = None,
45
- event: Optional[EarningsEvent] = None) -> Optional[Transcript]:
41
+ def get_transcript(
42
+ self, year: Optional[int] = None, quarter: Optional[int] = None, event: Optional[EarningsEvent] = None
43
+ ) -> Optional[Transcript]:
46
44
 
45
+ if not self.company_info.exchange or not self.company_info.symbol:
46
+ return None
47
47
  if (not year or not quarter) and event:
48
48
  year = event.year
49
49
  quarter = event.quarter
50
- elif (not year or not quarter) and not event:
50
+ if (not year or not quarter) and not event:
51
51
  raise ValueError("Must specify either event or year and quarter")
52
- resp = api.get_transcript(self.company_info.exchange, self.company_info.symbol, year, quarter)
52
+ resp = api.get_transcript(self.company_info.exchange, self.company_info.symbol, year, quarter) # type: ignore
53
53
  if not resp:
54
54
  return None
55
- return Transcript.from_dict(resp)
55
+ return Transcript.from_dict(resp) # type: ignore
earningscall/errors.py CHANGED
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  class BaseError(RuntimeError):
4
2
  """
5
3
  Base error
@@ -18,6 +16,7 @@ class ClientError(BaseError):
18
16
  """
19
17
  Used to return 4XX errors.
20
18
  """
19
+
21
20
  status: int = 400 # https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
22
21
 
23
22
 
earningscall/event.py CHANGED
@@ -16,6 +16,7 @@ class EarningsEvent:
16
16
  """
17
17
  EarningsEvent
18
18
  """
19
+
19
20
  year: int
20
21
  quarter: int
21
22
  conference_date: Optional[datetime] = field(
@@ -23,6 +24,6 @@ class EarningsEvent:
23
24
  metadata=config(
24
25
  encoder=lambda date: date.isoformat() if date else None,
25
26
  decoder=lambda date: datetime.fromisoformat(date) if date else None,
26
- mm_field=fields.DateTime(format="iso")
27
- )
27
+ mm_field=fields.DateTime(format="iso"),
28
+ ),
28
29
  )
earningscall/exports.py CHANGED
@@ -1,4 +1,4 @@
1
- from typing import Optional
1
+ from typing import Optional, Iterator
2
2
 
3
3
  from earningscall.api import get_sp500_companies_txt_file
4
4
  from earningscall.company import Company
@@ -12,15 +12,15 @@ def get_company(symbol: str) -> Optional[Company]:
12
12
  return None
13
13
 
14
14
 
15
- def get_all_companies() -> [Company]:
15
+ def get_all_companies() -> Iterator[Company]:
16
16
  for company_info in get_symbols().get_all():
17
17
  yield Company(company_info=company_info)
18
18
 
19
19
 
20
- def get_sp500_companies() -> [Company]:
20
+ def get_sp500_companies() -> Iterator[Company]:
21
21
  resp = get_sp500_companies_txt_file()
22
22
  if not resp:
23
- return []
23
+ return
24
24
  for ticker_symbol in resp.split("\n"):
25
25
  company_info = get_symbols().lookup_company(ticker_symbol)
26
26
  if company_info:
earningscall/sectors.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import logging
3
-
3
+ from typing import Optional
4
4
 
5
5
  log = logging.getLogger(__file__)
6
6
  sectors_file_name = "sectors.json"
@@ -17,7 +17,7 @@ SECTORS_IN_ORDER = [
17
17
  'Industrials',
18
18
  'Real Estate',
19
19
  'Technology',
20
- 'Utilities'
20
+ 'Utilities',
21
21
  ]
22
22
 
23
23
 
@@ -166,7 +166,7 @@ INDUSTRIES_IN_ORDER = [
166
166
  'Utilities - Regulated Gas',
167
167
  'Utilities - Regulated Water',
168
168
  'Utilities - Renewable',
169
- 'Waste Management'
169
+ 'Waste Management',
170
170
  ]
171
171
 
172
172
 
@@ -198,9 +198,7 @@ def industry_to_index(_industry: str) -> int:
198
198
 
199
199
  class Sectors:
200
200
 
201
- def __init__(self,
202
- sectors: set = None,
203
- industries: set = None):
201
+ def __init__(self, sectors: Optional[set] = None, industries: Optional[set] = None):
204
202
  if sectors:
205
203
  self.sectors = sectors
206
204
  else:
@@ -218,7 +216,7 @@ class Sectors:
218
216
  if industry is not None:
219
217
  self.industries.add(industry)
220
218
 
221
- def to_dicts(self) -> {}:
219
+ def to_dicts(self) -> dict:
222
220
  return {
223
221
  "sectors": list(self.sectors),
224
222
  "industries": list(self.industries),
@@ -231,4 +229,3 @@ class Sectors:
231
229
  def from_json(json_str):
232
230
  data = json.loads(json_str)
233
231
  return Sectors(set(data["sectors"]), set(data["industries"]))
234
-
earningscall/symbols.py CHANGED
@@ -2,7 +2,7 @@ import json
2
2
  import logging
3
3
  import re
4
4
  from collections import defaultdict
5
- from typing import Optional
5
+ from typing import Optional, Iterator, List
6
6
 
7
7
  from earningscall.api import get_symbols_v2, is_demo_account
8
8
  from earningscall.errors import InsufficientApiAccessError
@@ -14,7 +14,9 @@ EXCHANGES_IN_ORDER = ["NYSE", "NASDAQ", "AMEX", "TSX", "TSXV", "OTC"]
14
14
  log = logging.getLogger(__file__)
15
15
 
16
16
 
17
- def exchange_to_index(_exchange: str) -> int:
17
+ def exchange_to_index(_exchange: Optional[str]) -> int:
18
+ if not _exchange:
19
+ return -1
18
20
  try:
19
21
  return EXCHANGES_IN_ORDER.index(_exchange)
20
22
  except ValueError:
@@ -110,7 +112,7 @@ class Symbols:
110
112
  if len(self.by_exchange_and_sym) == size_before:
111
113
  log.debug(f"Duplicate: {_sym}")
112
114
 
113
- def get_all(self) -> [CompanyInfo]:
115
+ def get_all(self) -> Iterator[CompanyInfo]:
114
116
  for _exchange_symbol, _symbol in self.by_exchange_and_sym.items():
115
117
  yield _symbol
116
118
 
@@ -129,8 +131,10 @@ class Symbols:
129
131
  except KeyError:
130
132
  pass
131
133
  if is_demo_account():
132
- raise InsufficientApiAccessError(f"\"{symbol}\" requires an API Key for access. To get your API Key,"
133
- f" see: https://earningscall.biz/api-pricing")
134
+ raise InsufficientApiAccessError(
135
+ f"\"{symbol}\" requires an API Key for access. To get your API Key,"
136
+ f" see: https://earningscall.biz/api-pricing"
137
+ )
134
138
  return None
135
139
 
136
140
  def remove_exchange_symbol(self, exchange_symbol: str):
@@ -142,11 +146,13 @@ class Symbols:
142
146
  def remove_keys(symbol_as_dict: dict, keys_to_remove: set):
143
147
  return {key: value for key, value in symbol_as_dict.items() if key not in keys_to_remove}
144
148
 
145
- def without_security_names(self) -> [dict]:
146
- return [self.remove_keys(symbol_as_dict, {"security_name", "sector", "industry"})
147
- for symbol_as_dict in self.to_dicts()]
149
+ def without_security_names(self) -> List[dict]:
150
+ return [
151
+ self.remove_keys(symbol_as_dict, {"security_name", "sector", "industry"})
152
+ for symbol_as_dict in self.to_dicts()
153
+ ]
148
154
 
149
- def to_dicts(self) -> [dict]:
155
+ def to_dicts(self) -> List[dict]:
150
156
  return [__symbol.__dict__ for __symbol in self.get_all()]
151
157
 
152
158
  def to_json(self, remove_security_names: bool = False) -> str:
@@ -154,9 +160,14 @@ class Symbols:
154
160
  return json.dumps(self.without_security_names())
155
161
  return json.dumps(self.to_dicts())
156
162
 
157
- def to_json_v2(self) -> str:
158
- return json.dumps([[exchange_to_index(__symbol.exchange), __symbol.company_info, __symbol.name]
159
- for __symbol in self.get_all()])
163
+ # TODO: Test this
164
+ # def to_json_v2(self) -> str:
165
+ # return json.dumps(
166
+ # [
167
+ # [exchange_to_index(__symbol.exchange), __symbol.company_info, __symbol.name]
168
+ # for __symbol in self.get_all()
169
+ # ]
170
+ # )
160
171
 
161
172
  def to_txt(self) -> str:
162
173
  exchange_symbol_names = [__symbol.to_txt_row() for __symbol in self.get_all()]
@@ -195,13 +206,15 @@ class Symbols:
195
206
  __symbols = Symbols()
196
207
  for line in txt_str.split("\n"):
197
208
  _exchange_index, _symbol, _name, _sector_index, _industry_index = line.split("\t")
198
- __symbols.add(CompanyInfo(
199
- exchange=index_to_exchange(int(_exchange_index)),
200
- symbol=_symbol,
201
- name=_name,
202
- sector=index_to_sector(int(_sector_index)),
203
- industry=index_to_industry(int(_industry_index)),
204
- ))
209
+ __symbols.add(
210
+ CompanyInfo(
211
+ exchange=index_to_exchange(int(_exchange_index)),
212
+ symbol=_symbol,
213
+ name=_name,
214
+ sector=index_to_sector(int(_sector_index)),
215
+ industry=index_to_industry(int(_industry_index)),
216
+ )
217
+ )
205
218
  return __symbols
206
219
 
207
220
  @staticmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: earningscall
3
- Version: 0.0.10
3
+ Version: 0.0.12
4
4
  Summary: The EarningsCall Python library.
5
5
  Project-URL: Homepage, https://earningscall.biz
6
6
  Project-URL: Documentation, https://github.com/EarningsCall/earningscall-python
@@ -34,6 +34,7 @@ License-File: LICENSE
34
34
  Requires-Python: >=3.8
35
35
  Requires-Dist: dataclasses-json>=0.6.4
36
36
  Requires-Dist: dataclasses>=0.6
37
+ Requires-Dist: requests-cache>=1.2.0
37
38
  Requires-Dist: requests>=2.30.0
38
39
  Description-Content-Type: text/markdown
39
40
 
@@ -129,10 +130,8 @@ To gain access to 5,000+ companies please [signup here](https://earningscall.biz
129
130
  Once you have access to your API key, you can set the API Key like this:
130
131
 
131
132
  ```python
132
-
133
133
  import earningscall
134
134
 
135
-
136
135
  earningscall.api_key = "YOUR SECRET API KEY GOES HERE"
137
136
  ```
138
137
 
@@ -0,0 +1,14 @@
1
+ earningscall/__init__.py,sha256=NX9f2et-q3p8BRGvJB0enRSLlSGecSAwspPxhDsL95Y,298
2
+ earningscall/api.py,sha256=eK43JazoBNI9YF0OMi5c0DrYv0tVzyOy2ycNyX63y8s,2000
3
+ earningscall/company.py,sha256=ZNF75htXg37oXtNzwrHH8DoTdyFJ3PBB9qSNBp_vo8c,1943
4
+ earningscall/errors.py,sha256=EA-d6qIYgQs9csp8JptQiAaYoM0M9HhCGJgKA9GAWPg,440
5
+ earningscall/event.py,sha256=O7KAE2wO3mBhlEWIFA1choMNGRthYd0gBIvVQOmVALs,692
6
+ earningscall/exports.py,sha256=i9UWHY6Lq1OzZTZX_1SdNzrNd_PSlPwpB337lGMK4oM,837
7
+ earningscall/sectors.py,sha256=9kAwTtJEDbWah6lz5io88qRwvCtmGgjQ-MU7rayTmVI,5962
8
+ earningscall/symbols.py,sha256=EXSPUMr50zZz-Cw9CimrRbVd7F71PB9McgsFC7yJ5S4,7980
9
+ earningscall/transcript.py,sha256=rLH2bGrrgUmS8XZGAPUP7msiIcL7f4ABmbnVJWXI28c,329
10
+ earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
11
+ earningscall-0.0.12.dist-info/METADATA,sha256=Br6DJz0J0ZVy4FrY6qkSYcFoze_unf2ooht9v7D__UQ,5714
12
+ earningscall-0.0.12.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
13
+ earningscall-0.0.12.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
14
+ earningscall-0.0.12.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- earningscall/__init__.py,sha256=LvXzPzsPyckMUVggfB5sklTAaswKsSG1IJ8ImC-fvTc,200
2
- earningscall/api.py,sha256=-nqxFGrTinCFCj8_wA-fkyrqr-WfDS50sMAh2UGdBR0,1958
3
- earningscall/company.py,sha256=VyiHOajDBAx-G6dgWrPBUwWKjDpBvb0moZIpULPmiKA,1765
4
- earningscall/errors.py,sha256=_m8CvAcyWQprdyTNzYjdoCX5nUZpEP7rG4c5-eLmxno,441
5
- earningscall/event.py,sha256=Gdda4829tWlrlFn38r8KOaI-IJzf-ambiNojKyr9XtY,689
6
- earningscall/exports.py,sha256=wA6d4-AJyT-0Wz8g_j-3rFHHhnXHx5V1GCsaPJMatFc,814
7
- earningscall/sectors.py,sha256=9aw14krRzdLJSTFC72Nwk3MQaXAIgkTBk5S-KTiki3U,5946
8
- earningscall/symbols.py,sha256=StqRc_C2hFdlhCMEKpytfUmsruCSHY0WPQQIVIejF9k,7748
9
- earningscall/transcript.py,sha256=rLH2bGrrgUmS8XZGAPUP7msiIcL7f4ABmbnVJWXI28c,329
10
- earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
11
- earningscall-0.0.10.dist-info/METADATA,sha256=kfOIWa_oFRM35njNOeUIQHKxs23dS_9omh4nt3ieke8,5679
12
- earningscall-0.0.10.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
13
- earningscall-0.0.10.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
14
- earningscall-0.0.10.dist-info/RECORD,,