earningscall 0.0.4__tar.gz → 0.0.5__tar.gz
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-0.0.4 → earningscall-0.0.5}/.github/workflows/release.yml +1 -1
- {earningscall-0.0.4 → earningscall-0.0.5}/PKG-INFO +30 -3
- {earningscall-0.0.4 → earningscall-0.0.5}/README.md +26 -2
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/api.py +9 -2
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/company.py +3 -1
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/errors.py +5 -1
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/exports.py +7 -2
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/symbols.py +10 -1
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/utils.py +5 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/pyproject.toml +4 -1
- {earningscall-0.0.4 → earningscall-0.0.5}/scripts/list_all_companies.py +4 -0
- earningscall-0.0.5/tests/data/demo-symbols-v2.yaml +8 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/test_get_transcript.py +25 -12
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/test_symbols.py +1 -3
- {earningscall-0.0.4 → earningscall-0.0.5}/.gitignore +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/.python-version +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/CHANGELOG.md +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/DEVELOPMENT.md +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/LICENSE +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/TODO.md +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/__init__.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/event.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/sectors.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/earningscall/transcript.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/requirements-dev.lock +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/requirements.lock +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/scripts/get_all_company_transcripts.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/scripts/get_single_transcript.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/data/msft-transcript-response.yaml +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/data/symbols-v2.yaml +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/data/symbols.txt +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/data/symbols.yaml +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/test_earnings_event.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/test_helper.py +0 -0
- {earningscall-0.0.4 → earningscall-0.0.5}/tests/test_simple.py +0 -0
@@ -1,10 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: earningscall
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.5
|
4
4
|
Summary: The EarningsCall Python library.
|
5
|
+
Project-URL: Homepage, https://earningscall.biz
|
5
6
|
Project-URL: Documentation, https://github.com/EarningsCall/earningscall-python
|
7
|
+
Project-URL: Repository, https://github.com/EarningsCall/earningscall-python
|
6
8
|
Project-URL: Issues, https://github.com/EarningsCall/earningscall-python/issues
|
7
9
|
Project-URL: Source, https://github.com/EarningsCall/earningscall-python
|
10
|
+
Project-URL: Changelog, https://github.com/EarningsCall/earningscall-python/blob/master/CHANGELOG.md
|
8
11
|
Author-email: EarningsCall <dev@earningscall.biz>
|
9
12
|
License-File: LICENSE
|
10
13
|
Requires-Python: >=3.8
|
@@ -16,7 +19,11 @@ Description-Content-Type: text/markdown
|
|
16
19
|
|
17
20
|
# EarningsCall Python Library
|
18
21
|
|
19
|
-
|
22
|
+
[](https://pypi.python.org/pypi/earningscall)
|
23
|
+
[](https://github.com/EarningsCall/earningscall-python/actions?query=branch%3Amaster)
|
24
|
+
[](https://coveralls.io/github/EarningsCall/earningscall-python?branch=master)
|
25
|
+
|
26
|
+
The EarningsCall Python library provides convenient access to the [EarningsCall API](https://earningscall.biz/api-guide) from
|
20
27
|
applications written in the Python language. It includes a pre-defined set of
|
21
28
|
classes for API resources that initialize themselves dynamically from API
|
22
29
|
responses.
|
@@ -33,7 +40,6 @@ pip install --upgrade earningscall
|
|
33
40
|
|
34
41
|
* Python 3.8+ (PyPI supported)
|
35
42
|
|
36
|
-
|
37
43
|
## Get Transcript for a Single Quarter
|
38
44
|
|
39
45
|
```python
|
@@ -99,3 +105,24 @@ from earningscall import get_all_companies
|
|
99
105
|
for company in get_all_companies():
|
100
106
|
print(f"{company.company_info} -- {company.company_info.sector} -- {company.company_info.industry}")
|
101
107
|
```
|
108
|
+
|
109
|
+
By default, this library grants you access to only two companies, Apple Inc. and Microsoft, Inc.
|
110
|
+
|
111
|
+
To gain access 5,000+ companies please [signup here](https://earningscall.biz/api-pricing) to get your API key.
|
112
|
+
|
113
|
+
Once you have access to your API key, you can set the API Key like this:
|
114
|
+
|
115
|
+
```python
|
116
|
+
|
117
|
+
import earningscall
|
118
|
+
|
119
|
+
|
120
|
+
earningscall.api_key = "YOUR SECRET API KEY GOES HERE"
|
121
|
+
```
|
122
|
+
|
123
|
+
Alternatively, you can pass in your API key as an environment variable:
|
124
|
+
|
125
|
+
```sh
|
126
|
+
export ECALL_API_KEY="YOUR SECRET API KEY GOES HERE"
|
127
|
+
python your-python-script.py
|
128
|
+
```
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# EarningsCall Python Library
|
2
2
|
|
3
|
-
|
3
|
+
[](https://pypi.python.org/pypi/earningscall)
|
4
|
+
[](https://github.com/EarningsCall/earningscall-python/actions?query=branch%3Amaster)
|
5
|
+
[](https://coveralls.io/github/EarningsCall/earningscall-python?branch=master)
|
6
|
+
|
7
|
+
The EarningsCall Python library provides convenient access to the [EarningsCall API](https://earningscall.biz/api-guide) from
|
4
8
|
applications written in the Python language. It includes a pre-defined set of
|
5
9
|
classes for API resources that initialize themselves dynamically from API
|
6
10
|
responses.
|
@@ -17,7 +21,6 @@ pip install --upgrade earningscall
|
|
17
21
|
|
18
22
|
* Python 3.8+ (PyPI supported)
|
19
23
|
|
20
|
-
|
21
24
|
## Get Transcript for a Single Quarter
|
22
25
|
|
23
26
|
```python
|
@@ -83,3 +86,24 @@ from earningscall import get_all_companies
|
|
83
86
|
for company in get_all_companies():
|
84
87
|
print(f"{company.company_info} -- {company.company_info.sector} -- {company.company_info.industry}")
|
85
88
|
```
|
89
|
+
|
90
|
+
By default, this library grants you access to only two companies, Apple Inc. and Microsoft, Inc.
|
91
|
+
|
92
|
+
To gain access 5,000+ companies please [signup here](https://earningscall.biz/api-pricing) to get your API key.
|
93
|
+
|
94
|
+
Once you have access to your API key, you can set the API Key like this:
|
95
|
+
|
96
|
+
```python
|
97
|
+
|
98
|
+
import earningscall
|
99
|
+
|
100
|
+
|
101
|
+
earningscall.api_key = "YOUR SECRET API KEY GOES HERE"
|
102
|
+
```
|
103
|
+
|
104
|
+
Alternatively, you can pass in your API key as an environment variable:
|
105
|
+
|
106
|
+
```sh
|
107
|
+
export ECALL_API_KEY="YOUR SECRET API KEY GOES HERE"
|
108
|
+
python your-python-script.py
|
109
|
+
```
|
@@ -19,6 +19,10 @@ def get_api_key():
|
|
19
19
|
return api_key
|
20
20
|
|
21
21
|
|
22
|
+
def is_demo_account():
|
23
|
+
return get_api_key() == "demo"
|
24
|
+
|
25
|
+
|
22
26
|
def get_events(exchange: str,
|
23
27
|
symbol: str):
|
24
28
|
|
@@ -41,7 +45,7 @@ def get_transcript(exchange: str,
|
|
41
45
|
|
42
46
|
log.debug(f"get_transcript year: {year} quarter: {quarter}")
|
43
47
|
params = {
|
44
|
-
"apikey":
|
48
|
+
"apikey": get_api_key(),
|
45
49
|
"exchange": exchange,
|
46
50
|
"symbol": symbol,
|
47
51
|
"year": str(year),
|
@@ -61,7 +65,10 @@ def get_symbols_v1():
|
|
61
65
|
|
62
66
|
|
63
67
|
def get_symbols_v2():
|
64
|
-
|
68
|
+
params = {
|
69
|
+
"apikey": get_api_key(),
|
70
|
+
}
|
71
|
+
response = requests.get(f"{API_BASE}/symbols-v2.txt", params=params)
|
65
72
|
if response.status_code != 200:
|
66
73
|
return None
|
67
74
|
return response.text
|
@@ -15,7 +15,9 @@ class Company:
|
|
15
15
|
name: str
|
16
16
|
_events: [EarningsEvent]
|
17
17
|
|
18
|
-
def __init__(self, company_info):
|
18
|
+
def __init__(self, company_info: CompanyInfo):
|
19
|
+
if not company_info:
|
20
|
+
raise ValueError("company_info must be present.")
|
19
21
|
self.company_info = company_info
|
20
22
|
self.name = company_info.name
|
21
23
|
self._events = None
|
@@ -21,5 +21,9 @@ class ClientError(BaseError):
|
|
21
21
|
status: int = 400 # https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
|
22
22
|
|
23
23
|
|
24
|
-
class
|
24
|
+
class InsufficientApiAccessError(ClientError):
|
25
|
+
pass
|
26
|
+
|
27
|
+
|
28
|
+
class CompanyNotFound(ClientError):
|
25
29
|
pass
|
@@ -1,10 +1,15 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
1
3
|
from earningscall.symbols import get_symbols
|
2
4
|
|
3
5
|
from earningscall.company import Company
|
4
6
|
|
5
7
|
|
6
|
-
def get_company(symbol: str) -> Company:
|
7
|
-
|
8
|
+
def get_company(symbol: str) -> Optional[Company]:
|
9
|
+
company_info = get_symbols().lookup_company(symbol)
|
10
|
+
if company_info:
|
11
|
+
return Company(company_info=company_info)
|
12
|
+
return None
|
8
13
|
|
9
14
|
|
10
15
|
def get_all_companies() -> [Company]:
|
@@ -4,7 +4,8 @@ import re
|
|
4
4
|
from collections import defaultdict
|
5
5
|
from typing import Optional
|
6
6
|
|
7
|
-
from earningscall.api import get_symbols_v2
|
7
|
+
from earningscall.api import get_symbols_v2, is_demo_account
|
8
|
+
from earningscall.errors import InsufficientApiAccessError
|
8
9
|
from earningscall.sectors import sector_to_index, industry_to_index, index_to_sector, index_to_industry
|
9
10
|
|
10
11
|
# WARNING: Add new indexes to the *END* of this list
|
@@ -127,6 +128,9 @@ class Symbols:
|
|
127
128
|
return _symbol
|
128
129
|
except KeyError:
|
129
130
|
pass
|
131
|
+
if is_demo_account():
|
132
|
+
raise InsufficientApiAccessError(f"For full access, please get an API Key. See: "
|
133
|
+
f"https://earningscall.biz/api-pricing")
|
130
134
|
return None
|
131
135
|
|
132
136
|
def remove_exchange_symbol(self, exchange_symbol: str):
|
@@ -224,3 +228,8 @@ def get_symbols() -> Symbols:
|
|
224
228
|
if not _symbols:
|
225
229
|
_symbols = load_symbols()
|
226
230
|
return _symbols
|
231
|
+
|
232
|
+
|
233
|
+
def clear_symbols():
|
234
|
+
global _symbols
|
235
|
+
_symbols = None
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import logging
|
1
2
|
import os
|
2
3
|
import pathlib
|
3
4
|
|
@@ -13,3 +14,7 @@ def project_file_path(base_dir, file_name):
|
|
13
14
|
|
14
15
|
def data_path(file_name=None):
|
15
16
|
return project_file_path("tests/data", file_name)
|
17
|
+
|
18
|
+
|
19
|
+
def enable_debug_logs():
|
20
|
+
logging.basicConfig(level=logging.DEBUG)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "earningscall"
|
3
|
-
version = "0.0.
|
3
|
+
version = "0.0.5"
|
4
4
|
description = "The EarningsCall Python library."
|
5
5
|
readme = "README.md"
|
6
6
|
authors = [
|
@@ -15,9 +15,12 @@ dependencies = [
|
|
15
15
|
]
|
16
16
|
|
17
17
|
[project.urls]
|
18
|
+
Homepage = "https://earningscall.biz"
|
18
19
|
Documentation = "https://github.com/EarningsCall/earningscall-python"
|
20
|
+
Repository = "https://github.com/EarningsCall/earningscall-python"
|
19
21
|
Issues = "https://github.com/EarningsCall/earningscall-python/issues"
|
20
22
|
Source = "https://github.com/EarningsCall/earningscall-python"
|
23
|
+
Changelog = "https://github.com/EarningsCall/earningscall-python/blob/master/CHANGELOG.md"
|
21
24
|
|
22
25
|
[build-system]
|
23
26
|
requires = ["hatchling"]
|
@@ -1,10 +1,13 @@
|
|
1
|
+
import pytest
|
1
2
|
import responses
|
2
3
|
|
3
4
|
from earningscall import get_company
|
5
|
+
from earningscall.errors import InsufficientApiAccessError
|
6
|
+
from earningscall.symbols import clear_symbols
|
4
7
|
from earningscall.utils import data_path
|
5
8
|
|
6
9
|
|
7
|
-
# Uncomment following code to generate msft-transcript-response.yaml file
|
10
|
+
# Uncomment and run following code to generate msft-transcript-response.yaml file
|
8
11
|
#
|
9
12
|
# from responses import _recorder
|
10
13
|
# @_recorder.record(file_path="msft-transcript-response.yaml")
|
@@ -15,6 +18,7 @@ from earningscall.utils import data_path
|
|
15
18
|
@responses.activate
|
16
19
|
def test_get_demo_company():
|
17
20
|
##
|
21
|
+
clear_symbols()
|
18
22
|
responses._add_from_file(file_path=data_path("symbols-v2.yaml"))
|
19
23
|
responses._add_from_file(file_path=data_path("msft-transcript-response.yaml"))
|
20
24
|
##
|
@@ -25,14 +29,23 @@ def test_get_demo_company():
|
|
25
29
|
'Conference Call. At ')
|
26
30
|
|
27
31
|
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
|
32
|
+
# Uncomment and run following code to generate demo-symbols-v2.yaml file
|
33
|
+
#
|
34
|
+
# import requests
|
35
|
+
#
|
36
|
+
# from responses import _recorder
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# @_recorder.record(file_path="demo-symbols-v2.yaml")
|
40
|
+
# def test_save_symbols_v1():
|
41
|
+
# requests.get("https://v2.api.earningscall.biz/symbols-v2.txt?apikey=demo")
|
42
|
+
|
43
|
+
|
44
|
+
@responses.activate
|
45
|
+
def test_get_non_demo_company():
|
46
|
+
##
|
47
|
+
clear_symbols()
|
48
|
+
responses._add_from_file(file_path=data_path("demo-symbols-v2.yaml"))
|
49
|
+
##
|
50
|
+
with pytest.raises(InsufficientApiAccessError):
|
51
|
+
get_company("nvda")
|
@@ -9,8 +9,6 @@ from earningscall.utils import data_path
|
|
9
9
|
def test_load_symbols_txt_v2():
|
10
10
|
##
|
11
11
|
responses.patch(API_BASE)
|
12
|
-
print("symbols path")
|
13
|
-
print(data_path("symbols-v2.yaml"))
|
14
12
|
responses._add_from_file(file_path=data_path("symbols-v2.yaml"))
|
15
13
|
##
|
16
14
|
symbols = Symbols.load_txt_v2()
|
@@ -22,7 +20,7 @@ def test_load_symbols_txt_v2():
|
|
22
20
|
assert _symbol.sector == "Technology"
|
23
21
|
assert _symbol.industry == "Consumer Electronics"
|
24
22
|
assert len(responses.calls) == 1
|
25
|
-
assert responses.calls[0].request.url == "https://v2.api.earningscall.biz/symbols-v2.txt"
|
23
|
+
assert responses.calls[0].request.url == "https://v2.api.earningscall.biz/symbols-v2.txt?apikey=demo"
|
26
24
|
|
27
25
|
|
28
26
|
def test_symbols_serialization_to_text_v2():
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|