earningscall 0.0.22__py3-none-any.whl → 0.0.24__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/api.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import importlib
2
+ import urllib.parse
2
3
  import logging
3
4
  import os
4
5
  from importlib.metadata import PackageNotFoundError
@@ -18,7 +19,13 @@ API_BASE = f"https://v2.api.{DOMAIN}"
18
19
  def get_api_key():
19
20
  if earningscall.api_key:
20
21
  return earningscall.api_key
21
- return os.environ.get("ECALL_API_KEY", "demo")
22
+ e_call_key = os.environ.get("ECALL_API_KEY")
23
+ earnings_call_key = os.environ.get("EARNINGSCALL_API_KEY")
24
+ if e_call_key:
25
+ return e_call_key
26
+ if earnings_call_key:
27
+ return earnings_call_key
28
+ return "demo"
22
29
 
23
30
 
24
31
  def api_key_param():
@@ -83,7 +90,9 @@ def do_get(
83
90
  **kwargs.get("params", {}),
84
91
  }
85
92
  url = f"{API_BASE}/{path}"
86
- log.debug(f"do_get url: {url} params: {params}")
93
+ if log.isEnabledFor(logging.DEBUG):
94
+ full_url = f"{url}?{urllib.parse.urlencode(params)}"
95
+ log.debug(f"GET: {full_url}")
87
96
  if use_cache and earningscall.enable_requests_cache:
88
97
  return cache_session().get(url, params=params)
89
98
  else:
@@ -96,9 +105,7 @@ def do_get(
96
105
 
97
106
 
98
107
  def get_events(exchange: str, symbol: str):
99
- log.debug(f"get_events exchange: {exchange} symbol: {symbol}")
100
108
  params = {
101
- **api_key_param(),
102
109
  "exchange": exchange,
103
110
  "symbol": symbol,
104
111
  }
@@ -126,9 +133,7 @@ def get_transcript(
126
133
 
127
134
  :return: The transcript for the given exchange, symbol, year, and quarter.
128
135
  """
129
- log.debug(f"get_transcript exchange: {exchange} symbol: {symbol} year: {year} quarter: {quarter} level: {level}")
130
136
  params = {
131
- **api_key_param(),
132
137
  "exchange": exchange,
133
138
  "symbol": symbol,
134
139
  "year": str(year),
@@ -141,7 +146,6 @@ def get_transcript(
141
146
 
142
147
 
143
148
  def get_symbols_v2():
144
- log.debug("get_symbols_v2")
145
149
  response = do_get("symbols-v2.txt", use_cache=True)
146
150
  if response.status_code != 200:
147
151
  return None
@@ -149,7 +153,6 @@ def get_symbols_v2():
149
153
 
150
154
 
151
155
  def get_sp500_companies_txt_file():
152
- log.debug("get_sp500_companies_txt_file")
153
156
  response = do_get("symbols/sp500.txt", use_cache=True)
154
157
  if response.status_code != 200:
155
158
  return None
@@ -175,7 +178,6 @@ def download_audio_file(
175
178
  :rtype Optional[str]: The filename of the downloaded audio file.
176
179
  """
177
180
  params = {
178
- **api_key_param(),
179
181
  "exchange": exchange,
180
182
  "symbol": symbol,
181
183
  "year": str(year),
earningscall/company.py CHANGED
@@ -15,6 +15,8 @@ log = logging.getLogger(__file__)
15
15
  class Company:
16
16
  """
17
17
  A class representing a company.
18
+
19
+ Can be used to retrieve events, transcripts, and audio files.
18
20
  """
19
21
 
20
22
  company_info: CompanyInfo
@@ -129,7 +131,6 @@ class Company:
129
131
 
130
132
  :return: The audio for the given year and quarter.
131
133
  """
132
- log.info(f"Downloading audio file for {self.company_info.symbol} {event}")
133
134
  if not self.company_info.exchange or not self.company_info.symbol:
134
135
  return None
135
136
  if (not year or not quarter) and event:
earningscall/exports.py CHANGED
@@ -5,19 +5,37 @@ from earningscall.company import Company
5
5
  from earningscall.symbols import get_symbols
6
6
 
7
7
 
8
- def get_company(symbol: str) -> Optional[Company]:
9
- company_info = get_symbols().lookup_company(symbol)
8
+ def get_company(symbol: str, exchange: Optional[str] = None) -> Optional[Company]:
9
+ """
10
+ Get a company by symbol and optionally an exchange.
11
+
12
+ :param str symbol: The symbol to get the company for.
13
+ :param Optional[str] exchange: The exchange to get the company for.
14
+
15
+ :return: The company for the given symbol and exchange.
16
+ """
17
+ company_info = get_symbols().lookup_company(symbol=symbol, exchange=exchange)
10
18
  if company_info:
11
19
  return Company(company_info=company_info)
12
20
  return None
13
21
 
14
22
 
15
23
  def get_all_companies() -> Iterator[Company]:
24
+ """
25
+ Get all companies.
26
+
27
+ :return: An iterator of all companies that is available to the current API plan.
28
+ """
16
29
  for company_info in get_symbols().get_all():
17
30
  yield Company(company_info=company_info)
18
31
 
19
32
 
20
33
  def get_sp500_companies() -> Iterator[Company]:
34
+ """
35
+ Get all S&P 500 companies.
36
+
37
+ :return: An iterator of all S&P 500 companies that is available to the current API plan.
38
+ """
21
39
  resp = get_sp500_companies_txt_file()
22
40
  if not resp:
23
41
  return
earningscall/symbols.py CHANGED
@@ -8,7 +8,7 @@ from earningscall.errors import InsufficientApiAccessError
8
8
  from earningscall.sectors import sector_to_index, industry_to_index, index_to_sector, index_to_industry
9
9
 
10
10
  # WARNING: Add new indexes to the *END* of this list
11
- EXCHANGES_IN_ORDER = ["NYSE", "NASDAQ", "AMEX", "TSX", "TSXV", "OTC", "LSE"]
11
+ EXCHANGES_IN_ORDER = ["NYSE", "NASDAQ", "AMEX", "TSX", "TSXV", "OTC", "LSE", "CBOE"]
12
12
 
13
13
  log = logging.getLogger(__file__)
14
14
 
@@ -98,12 +98,12 @@ class Symbols:
98
98
  self.by_exchange_and_sym = {}
99
99
 
100
100
  def add(self, _sym: CompanyInfo):
101
- size_before = len(self.by_exchange_and_sym)
101
+ # size_before = len(self.by_exchange_and_sym)
102
102
  self.exchanges.add(_sym.exchange)
103
103
  self.by_name[_sym.name].add(_sym)
104
104
  self.by_exchange_and_sym[f"{_sym.exchange}_{_sym.symbol}"] = _sym
105
- if len(self.by_exchange_and_sym) == size_before:
106
- log.debug(f"Duplicate: {_sym}")
105
+ # if len(self.by_exchange_and_sym) == size_before:
106
+ # log.debug(f"Duplicate: {_sym}")
107
107
 
108
108
  def get_all(self) -> Iterator[CompanyInfo]:
109
109
  for _exchange_symbol, _symbol in self.by_exchange_and_sym.items():
@@ -115,7 +115,9 @@ class Symbols:
115
115
  def get_exchange_symbol(self, exchange_symbol: str) -> CompanyInfo:
116
116
  return self.by_exchange_and_sym[exchange_symbol]
117
117
 
118
- def lookup_company(self, symbol: str) -> Optional[CompanyInfo]:
118
+ def lookup_company(self, symbol: str, exchange: Optional[str] = None) -> Optional[CompanyInfo]:
119
+ if exchange:
120
+ return self.get(exchange, symbol.upper())
119
121
  for exchange in EXCHANGES_IN_ORDER:
120
122
  try:
121
123
  _symbol = self.get(exchange, symbol.upper())
@@ -9,8 +9,8 @@ from earningscall.event import EarningsEvent
9
9
  @dataclass_json
10
10
  @dataclass
11
11
  class SpeakerInfo:
12
- name: str
13
- title: str
12
+ name: Optional[str] = field(default=None)
13
+ title: Optional[str] = field(default=None)
14
14
 
15
15
 
16
16
  @dataclass_json
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: earningscall
3
- Version: 0.0.22
3
+ Version: 0.0.24
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
@@ -30,6 +30,7 @@ License: MIT License
30
30
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
31
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
32
  SOFTWARE.
33
+ License-File: LICENSE
33
34
  Keywords: earning call app,earnings call,earnings call api,earnings call app,earnings call transcript api,earnings call transcripts,earnings call transcripts api,earnings calls,earnings transcript api,listen to earnings calls,transcripts,where to listen to earnings calls
34
35
  Classifier: Development Status :: 3 - Alpha
35
36
  Classifier: Intended Audience :: Developers
@@ -55,6 +56,9 @@ Description-Content-Type: text/markdown
55
56
  [![Coverage Status](https://coveralls.io/repos/github/EarningsCall/earningscall-python/badge.svg?branch=master)](https://coveralls.io/github/EarningsCall/earningscall-python?branch=master)
56
57
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/earningscall?color=blue)](https://pypi.org/project/earningscall/)
57
58
 
59
+ [![Python](https://img.shields.io/badge/Python-14354C?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/)
60
+
61
+
58
62
  The EarningsCall Python library provides convenient access to the [EarningsCall API](https://earningscall.biz/api-guide) from
59
63
  applications written in the Python language. It includes a pre-defined set of
60
64
  classes for API resources that initialize themselves dynamically from API
@@ -272,13 +276,13 @@ Once you have access to your API key, you can set the API Key like this:
272
276
  ```python
273
277
  import earningscall
274
278
 
275
- earningscall.api_key = "YOUR SECRET API KEY GOES HERE"
279
+ earningscall.api_key = "YOUR-SECRET-API-KEY-GOES-HERE"
276
280
  ```
277
281
 
278
282
  Alternatively, you can pass in your API key as an environment variable:
279
283
 
280
284
  ```sh
281
- export ECALL_API_KEY="YOUR SECRET API KEY GOES HERE"
285
+ export EARNINGSCALL_API_KEY="YOUR-SECRET-API-KEY-GOES-HERE"
282
286
  python your-python-script.py
283
287
  ```
284
288
 
@@ -0,0 +1,14 @@
1
+ earningscall/__init__.py,sha256=0mANmPlE7LEWtOGzV2cmmlPfBIWBWlWRDkyqPHJ1jm8,333
2
+ earningscall/api.py,sha256=BPBL0juc5UzBT0qJpS5cAuDBnOcdxoSeEfM-JGJvh7A,5097
3
+ earningscall/company.py,sha256=Ie3LwW5GjXsy3_it5F25JjHfbU3pW8Zefhpv3IjIk4U,6609
4
+ earningscall/errors.py,sha256=EA-d6qIYgQs9csp8JptQiAaYoM0M9HhCGJgKA9GAWPg,440
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=Oy6o75AF6RNY7WZo-qIwu7eMZOoClBmI6xNGRhk-FJc,6475
9
+ earningscall/transcript.py,sha256=P-CeTYhE5T78SXDHFEJ0AlVUFz2XPxDMtkeiorziBiw,1007
10
+ earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
11
+ earningscall-0.0.24.dist-info/METADATA,sha256=7zUhC2fAwfGdVUhVGUum9XY8V9WwbLp-nHmaiFMK33w,13266
12
+ earningscall-0.0.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ earningscall-0.0.24.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
14
+ earningscall-0.0.24.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,14 +0,0 @@
1
- earningscall/__init__.py,sha256=0mANmPlE7LEWtOGzV2cmmlPfBIWBWlWRDkyqPHJ1jm8,333
2
- earningscall/api.py,sha256=NkYtMO9yq870Y2s_hWZni-scdc3DA2MO4MyQDAFNgws,5152
3
- earningscall/company.py,sha256=8HPM_UEoUUOW6mCESktBLpm63HydSk34GWyIv6vZdpw,6625
4
- earningscall/errors.py,sha256=EA-d6qIYgQs9csp8JptQiAaYoM0M9HhCGJgKA9GAWPg,440
5
- earningscall/event.py,sha256=Jf7KPvpeaF9KkeHe46LbL_HIYLXkyHrs3psq-ZY-bkI,692
6
- earningscall/exports.py,sha256=i9UWHY6Lq1OzZTZX_1SdNzrNd_PSlPwpB337lGMK4oM,837
7
- earningscall/sectors.py,sha256=Xd6DLkAQ_fQkC2s-N9pReC8b_M3iy77OoFftoZj9FWY,5114
8
- earningscall/symbols.py,sha256=39tL7oP1HT8BturwKW7mgS33dX2Y_X8cw5GKK0aV02k,6354
9
- earningscall/transcript.py,sha256=970kq1-cDOOyuY630bH1-nwWuPHv9K0gABH2HtCEddQ,943
10
- earningscall/utils.py,sha256=Qx8KhlumUdzyBSZRKMS6vpWlb8MGZpLKA4OffJaMdCE,1032
11
- earningscall-0.0.22.dist-info/METADATA,sha256=gaiZWluFyCgXDXxuuZpO5TsNhmulf62TaM8Opwq2CfY,13106
12
- earningscall-0.0.22.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
13
- earningscall-0.0.22.dist-info/licenses/LICENSE,sha256=ktEB_UcRMg2cQlX9wiDs544xWncWizwS9mEZuGsCLrM,1069
14
- earningscall-0.0.22.dist-info/RECORD,,