yfinance 1.6.0__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.
- yfinance/__init__.py +61 -0
- yfinance/_http.py +101 -0
- yfinance/base.py +828 -0
- yfinance/cache.py +639 -0
- yfinance/calendars.py +547 -0
- yfinance/config.py +61 -0
- yfinance/const.py +1156 -0
- yfinance/data.py +689 -0
- yfinance/domain/__init__.py +5 -0
- yfinance/domain/domain.py +199 -0
- yfinance/domain/industry.py +156 -0
- yfinance/domain/market.py +143 -0
- yfinance/domain/sector.py +155 -0
- yfinance/exceptions.py +71 -0
- yfinance/live.py +350 -0
- yfinance/lookup.py +220 -0
- yfinance/multi.py +306 -0
- yfinance/pricing.proto +37 -0
- yfinance/pricing_pb2.py +33 -0
- yfinance/scrapers/__init__.py +0 -0
- yfinance/scrapers/analysis.py +204 -0
- yfinance/scrapers/fundamentals.py +204 -0
- yfinance/scrapers/funds.py +336 -0
- yfinance/scrapers/history.py +3757 -0
- yfinance/scrapers/holders.py +241 -0
- yfinance/scrapers/quote.py +947 -0
- yfinance/screener/__init__.py +4 -0
- yfinance/screener/query.py +259 -0
- yfinance/screener/screener.py +216 -0
- yfinance/search.py +159 -0
- yfinance/shared.py +29 -0
- yfinance/ticker.py +328 -0
- yfinance/tickers.py +100 -0
- yfinance/utils.py +1192 -0
- yfinance/version.py +1 -0
- yfinance-1.6.0.dist-info/METADATA +142 -0
- yfinance-1.6.0.dist-info/RECORD +40 -0
- yfinance-1.6.0.dist-info/WHEEL +5 -0
- yfinance-1.6.0.dist-info/licenses/LICENSE.txt +202 -0
- yfinance-1.6.0.dist-info/top_level.txt +1 -0
yfinance/__init__.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# yfinance - market data downloader
|
|
5
|
+
# https://github.com/ranaroussi/yfinance
|
|
6
|
+
#
|
|
7
|
+
# Copyright 2017-2019 Ran Aroussi
|
|
8
|
+
#
|
|
9
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
# you may not use this file except in compliance with the License.
|
|
11
|
+
# You may obtain a copy of the License at
|
|
12
|
+
#
|
|
13
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
#
|
|
15
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
# See the License for the specific language governing permissions and
|
|
19
|
+
# limitations under the License.
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
from . import version
|
|
23
|
+
from .search import Search
|
|
24
|
+
from .lookup import Lookup
|
|
25
|
+
from .ticker import Ticker
|
|
26
|
+
from .calendars import Calendars
|
|
27
|
+
from .tickers import Tickers
|
|
28
|
+
from .multi import download
|
|
29
|
+
from .live import WebSocket, AsyncWebSocket
|
|
30
|
+
from .utils import enable_debug_mode
|
|
31
|
+
from .cache import set_tz_cache_location
|
|
32
|
+
from .domain.sector import Sector
|
|
33
|
+
from .domain.industry import Industry
|
|
34
|
+
from .domain.market import Market, MarketRegion
|
|
35
|
+
from .config import YfConfig as config
|
|
36
|
+
from .data import Auth
|
|
37
|
+
|
|
38
|
+
from .screener.query import EquityQuery, FundQuery, ETFQuery
|
|
39
|
+
from .screener.screener import screen, PREDEFINED_SCREENER_QUERIES
|
|
40
|
+
|
|
41
|
+
__version__ = version.version
|
|
42
|
+
__author__ = "Ran Aroussi"
|
|
43
|
+
|
|
44
|
+
import warnings
|
|
45
|
+
warnings.filterwarnings('default', category=DeprecationWarning, module='^yfinance')
|
|
46
|
+
|
|
47
|
+
__all__ = ['download', 'Market', 'MarketRegion', 'Search', 'Lookup', 'Ticker', 'Tickers', 'enable_debug_mode', 'set_tz_cache_location',
|
|
48
|
+
'Sector', 'Industry', 'WebSocket', 'AsyncWebSocket', 'Calendars', 'Auth']
|
|
49
|
+
# screener stuff:
|
|
50
|
+
__all__ += ['EquityQuery', 'FundQuery', 'ETFQuery', 'screen', 'PREDEFINED_SCREENER_QUERIES']
|
|
51
|
+
|
|
52
|
+
# Config stuff:
|
|
53
|
+
_NOTSET=object()
|
|
54
|
+
def set_config(proxy=_NOTSET, retries=_NOTSET):
|
|
55
|
+
if proxy is not _NOTSET:
|
|
56
|
+
warnings.warn("Set proxy via new config control: yf.config.network.proxy = proxy", DeprecationWarning)
|
|
57
|
+
config.network.proxy = proxy
|
|
58
|
+
if retries is not _NOTSET:
|
|
59
|
+
warnings.warn("Set retries via new config control: yf.config.network.retries = retries", DeprecationWarning)
|
|
60
|
+
config.network.retries = retries
|
|
61
|
+
__all__ += ['config', 'set_config']
|
yfinance/_http.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""HTTP backend abstraction.
|
|
2
|
+
|
|
3
|
+
Prefers ``curl_cffi`` for browser TLS impersonation. Falls back to plain
|
|
4
|
+
``requests`` with a realistic ``User-Agent`` when ``curl_cffi`` cannot be
|
|
5
|
+
imported (e.g. binary not buildable on the host platform — see issue #2692)
|
|
6
|
+
or when ``YF_DISABLE_CURL_CFFI`` is set in the environment (downstream
|
|
7
|
+
packagers may ship without ``curl_cffi`` even if it is installed).
|
|
8
|
+
|
|
9
|
+
The fallback is best-effort: plain ``requests`` cannot replicate the
|
|
10
|
+
JA3/JA4 fingerprint and HTTP/2 settings that ``curl_cffi`` provides, so
|
|
11
|
+
Yahoo Finance may rate-limit or block this client. ``curl_cffi`` remains
|
|
12
|
+
the preferred backend and the default install dependency.
|
|
13
|
+
"""
|
|
14
|
+
import functools
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
from . import utils
|
|
18
|
+
|
|
19
|
+
_DISABLE = os.environ.get("YF_DISABLE_CURL_CFFI", "").lower() in ("1", "true", "yes")
|
|
20
|
+
|
|
21
|
+
if not _DISABLE:
|
|
22
|
+
try:
|
|
23
|
+
from curl_cffi import requests as _curl_backend
|
|
24
|
+
_backend = _curl_backend
|
|
25
|
+
HAS_CURL_CFFI = True
|
|
26
|
+
except ImportError:
|
|
27
|
+
import requests as _requests_backend
|
|
28
|
+
_backend = _requests_backend
|
|
29
|
+
HAS_CURL_CFFI = False
|
|
30
|
+
else:
|
|
31
|
+
import requests as _requests_backend
|
|
32
|
+
_backend = _requests_backend
|
|
33
|
+
HAS_CURL_CFFI = False
|
|
34
|
+
|
|
35
|
+
requests = _backend
|
|
36
|
+
HTTPError = _backend.exceptions.HTTPError
|
|
37
|
+
|
|
38
|
+
_FALLBACK_USER_AGENT = (
|
|
39
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
|
40
|
+
"(KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
_fallback_warned = False
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _warn_once_on_fallback():
|
|
47
|
+
global _fallback_warned
|
|
48
|
+
if HAS_CURL_CFFI or _fallback_warned:
|
|
49
|
+
return
|
|
50
|
+
_fallback_warned = True
|
|
51
|
+
utils.get_yf_logger().warning(
|
|
52
|
+
"curl_cffi not available; falling back to requests without browser TLS "
|
|
53
|
+
"impersonation. Yahoo Finance may rate-limit or block this client. "
|
|
54
|
+
"Install curl_cffi (>=0.15) for the supported configuration."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def new_session():
|
|
59
|
+
"""Create a default Session for the active backend."""
|
|
60
|
+
if HAS_CURL_CFFI:
|
|
61
|
+
return _backend.Session(impersonate="chrome")
|
|
62
|
+
_warn_once_on_fallback()
|
|
63
|
+
s = _backend.Session()
|
|
64
|
+
s.headers.update({
|
|
65
|
+
"User-Agent": _FALLBACK_USER_AGENT,
|
|
66
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
|
67
|
+
"Accept-Language": "en-US,en;q=0.5",
|
|
68
|
+
})
|
|
69
|
+
return s
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def cookie_jar(session):
|
|
73
|
+
"""Return the underlying ``http.cookiejar.CookieJar`` for either backend.
|
|
74
|
+
|
|
75
|
+
``curl_cffi`` exposes the jar as ``session.cookies.jar``; ``requests``
|
|
76
|
+
uses ``session.cookies`` directly (it subclasses ``CookieJar``).
|
|
77
|
+
"""
|
|
78
|
+
cookies = session.cookies
|
|
79
|
+
return getattr(cookies, "jar", cookies)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@functools.lru_cache(maxsize=1)
|
|
83
|
+
def _supported_session_classes() -> tuple:
|
|
84
|
+
classes = []
|
|
85
|
+
try:
|
|
86
|
+
from curl_cffi.requests.session import Session as _CurlSession
|
|
87
|
+
classes.append(_CurlSession)
|
|
88
|
+
except ImportError:
|
|
89
|
+
pass
|
|
90
|
+
try:
|
|
91
|
+
from requests.sessions import Session as _ReqSession
|
|
92
|
+
classes.append(_ReqSession)
|
|
93
|
+
except ImportError:
|
|
94
|
+
pass
|
|
95
|
+
return tuple(classes)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def is_supported_session(obj) -> bool:
|
|
99
|
+
"""True if ``obj`` is a Session from either supported backend."""
|
|
100
|
+
classes = _supported_session_classes()
|
|
101
|
+
return bool(classes) and isinstance(obj, classes)
|