mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-07 18:01:10 +00:00
remove seeking alpha provider (#7570)
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
# OpenBB Seeking Alpha Provider
|
||||
|
||||
This extension integrates the [Seeking Alpha](https://seekingalpha.com) data provider into the OpenBB Platform.
|
||||
|
||||
## Installation
|
||||
|
||||
To install the extension:
|
||||
|
||||
```bash
|
||||
pip install openbb-seeking-alpha
|
||||
```
|
||||
|
||||
Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing).
|
||||
@@ -1 +0,0 @@
|
||||
"""Init file for Provider."""
|
||||
@@ -1,23 +0,0 @@
|
||||
"""Seeking Alpha Provider module."""
|
||||
|
||||
from openbb_core.provider.abstract.provider import Provider
|
||||
from openbb_seeking_alpha.models.calendar_earnings import SACalendarEarningsFetcher
|
||||
from openbb_seeking_alpha.models.forward_eps_estimates import (
|
||||
SAForwardEpsEstimatesFetcher,
|
||||
)
|
||||
from openbb_seeking_alpha.models.forward_sales_estimates import (
|
||||
SAForwardSalesEstimatesFetcher,
|
||||
)
|
||||
|
||||
seeking_alpha_provider = Provider(
|
||||
name="seeking_alpha",
|
||||
website="https://seekingalpha.com",
|
||||
description="""Seeking Alpha is a data provider with access to news, analysis, and
|
||||
real-time alerts on stocks.""",
|
||||
fetcher_dict={
|
||||
"CalendarEarnings": SACalendarEarningsFetcher,
|
||||
"ForwardEpsEstimates": SAForwardEpsEstimatesFetcher,
|
||||
"ForwardSalesEstimates": SAForwardSalesEstimatesFetcher,
|
||||
},
|
||||
repr_name="Seeking Alpha",
|
||||
)
|
||||
@@ -1 +0,0 @@
|
||||
"""Init file for models."""
|
||||
@@ -1,176 +0,0 @@
|
||||
"""Seeking Alpha Calendar Earnings Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Literal
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.calendar_earnings import (
|
||||
CalendarEarningsData,
|
||||
CalendarEarningsQueryParams,
|
||||
)
|
||||
from openbb_core.provider.utils.country_utils import Country
|
||||
from openbb_seeking_alpha.utils.helpers import HEADERS, date_range
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
SA_COUNTRIES = {"us", "ca"}
|
||||
|
||||
|
||||
class SACalendarEarningsQueryParams(CalendarEarningsQueryParams):
|
||||
"""Seeking Alpha Calendar Earnings Query.
|
||||
|
||||
Source: https://seekingalpha.com/earnings/earnings-calendar
|
||||
"""
|
||||
|
||||
country: Literal["us", "ca"] = Field(
|
||||
default="us",
|
||||
description="The country to get calendar data for. "
|
||||
"Accepts 'us'/'ca', ISO codes ('US', 'USA', 'CA', 'CAN'), "
|
||||
"or names ('United States', 'Canada').",
|
||||
json_schema_extra={"choices": ["us", "ca"]},
|
||||
)
|
||||
|
||||
@field_validator("country", mode="before")
|
||||
@classmethod
|
||||
def _validate_country(cls, v):
|
||||
"""Normalize country input to Seeking Alpha format."""
|
||||
if v in SA_COUNTRIES:
|
||||
return v
|
||||
try:
|
||||
country = Country(v)
|
||||
code = country.alpha_2.lower()
|
||||
if code in SA_COUNTRIES:
|
||||
return code
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError(
|
||||
f"Country '{v}' not supported. Seeking Alpha only supports US and Canada."
|
||||
)
|
||||
|
||||
|
||||
class SACalendarEarningsData(CalendarEarningsData):
|
||||
"""Seeking Alpha Calendar Earnings Data."""
|
||||
|
||||
market_cap: float | None = Field(
|
||||
default=None,
|
||||
description="Market cap of the entity.",
|
||||
)
|
||||
reporting_time: str | None = Field(
|
||||
default=None,
|
||||
description="The reporting time - e.g. after market close.",
|
||||
)
|
||||
exchange: str | None = Field(
|
||||
default=None,
|
||||
description="The primary trading exchange.",
|
||||
)
|
||||
sector_id: int | None = Field(
|
||||
default=None,
|
||||
description="The Seeking Alpha Sector ID.",
|
||||
)
|
||||
|
||||
@field_validator("report_date", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def validate_release_date(cls, v):
|
||||
"""Validate the release date."""
|
||||
v = v.split("T")[0]
|
||||
return datetime.strptime(v, "%Y-%m-%d").date()
|
||||
|
||||
|
||||
class SACalendarEarningsFetcher(
|
||||
Fetcher[
|
||||
SACalendarEarningsQueryParams,
|
||||
list[SACalendarEarningsData],
|
||||
]
|
||||
):
|
||||
"""Seeking Alpha Calendar Earnings Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: dict[str, Any]) -> SACalendarEarningsQueryParams:
|
||||
"""Transform the query."""
|
||||
now = datetime.today().date()
|
||||
transformed_params = params
|
||||
if not params.get("start_date"):
|
||||
transformed_params["start_date"] = now
|
||||
if not params.get("end_date"):
|
||||
transformed_params["end_date"] = now + timedelta(days=3)
|
||||
return SACalendarEarningsQueryParams(**transformed_params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: SACalendarEarningsQueryParams,
|
||||
credentials: dict[str, str] | None,
|
||||
**kwargs: Any,
|
||||
) -> list[dict]:
|
||||
"""Return the raw data from the Seeking Alpha endpoint."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_core.provider.utils.client import ClientSession
|
||||
from openbb_core.provider.utils.helpers import amake_request
|
||||
|
||||
results: list[dict] = []
|
||||
dates = [
|
||||
date.strftime("%Y-%m-%d")
|
||||
for date in date_range(query.start_date, query.end_date)
|
||||
]
|
||||
currency = "USD" if query.country == "us" else "CAD"
|
||||
messages: list = []
|
||||
|
||||
async with ClientSession() as session:
|
||||
|
||||
async def get_date(date, currency):
|
||||
"""Get date for one date."""
|
||||
url = (
|
||||
f"https://seekingalpha.com/api/v3/earnings_calendar/tickers?"
|
||||
f"filter%5Bselected_date%5D={date}"
|
||||
f"&filter%5Bwith_rating%5D=false&filter%5Bcurrency%5D={currency}"
|
||||
)
|
||||
response = await amake_request(
|
||||
url=url, headers=HEADERS, session=session
|
||||
)
|
||||
# Try again if the response is blocked.
|
||||
if "blockScript" in response:
|
||||
response = await amake_request(
|
||||
url=url, headers=HEADERS, session=session
|
||||
)
|
||||
if "blockScript" in response:
|
||||
message = json.dumps(response)
|
||||
messages.append(message)
|
||||
warn(message)
|
||||
if "data" in response:
|
||||
results.extend(response.get("data")) # type: ignore
|
||||
|
||||
await asyncio.gather(*[get_date(date, currency) for date in dates])
|
||||
|
||||
if not results:
|
||||
raise OpenBBError(f"Error with the Seeking Alpha request -> {messages}")
|
||||
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: SACalendarEarningsQueryParams,
|
||||
data: list[dict],
|
||||
**kwargs: Any,
|
||||
) -> list[SACalendarEarningsData]:
|
||||
"""Transform the data to the standard format."""
|
||||
transformed_data: list[SACalendarEarningsData] = []
|
||||
for row in sorted(data, key=lambda x: x["attributes"]["release_date"]):
|
||||
attributes = row.get("attributes", {})
|
||||
transformed_data.append(
|
||||
SACalendarEarningsData.model_validate(
|
||||
{
|
||||
"report_date": attributes.get("release_date"),
|
||||
"reporting_time": attributes.get("release_time"),
|
||||
"symbol": attributes.get("slug"),
|
||||
"name": attributes.get("name"),
|
||||
"market_cap": attributes.get("marketcap"),
|
||||
"exchange": attributes.get("exchange"),
|
||||
"sector_id": attributes.get("sector_id"),
|
||||
}
|
||||
)
|
||||
)
|
||||
return transformed_data
|
||||
@@ -1,226 +0,0 @@
|
||||
"""Seeking Alpha Forward EPS Estimates Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from typing import Any, Literal
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.forward_eps_estimates import (
|
||||
ForwardEpsEstimatesData,
|
||||
ForwardEpsEstimatesQueryParams,
|
||||
)
|
||||
from openbb_core.provider.utils.helpers import amake_request
|
||||
from openbb_seeking_alpha.utils.helpers import HEADERS, get_seekingalpha_id
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
|
||||
class SAForwardEpsEstimatesQueryParams(ForwardEpsEstimatesQueryParams):
|
||||
"""Seeking Alpha Forward EPS Estimates Query.
|
||||
|
||||
Source: https://seekingalpha.com/earnings/earnings-calendar
|
||||
"""
|
||||
|
||||
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
|
||||
|
||||
period: Literal["annual", "quarter"] = Field(
|
||||
default="quarter",
|
||||
description="The reporting period.",
|
||||
json_schema_extra={"choices": ["annual", "quarter"]},
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def check_symbol(cls, value):
|
||||
"""Check the symbol."""
|
||||
if not value:
|
||||
raise OpenBBError("Symbol is a required field for Seeking Alpha.")
|
||||
return value
|
||||
|
||||
|
||||
class SAForwardEpsEstimatesData(ForwardEpsEstimatesData):
|
||||
"""Seeking Alpha Forward EPS Estimates Data."""
|
||||
|
||||
normalized_actual: float | None = Field(
|
||||
default=None,
|
||||
description="Actual normalized EPS.",
|
||||
)
|
||||
period_growth: float | None = Field(
|
||||
default=None,
|
||||
description="Estimated (or actual if reported) EPS growth for the period.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
low_estimate_gaap: float | None = Field(
|
||||
default=None,
|
||||
description="Estimated GAAP EPS low for the period.",
|
||||
)
|
||||
high_estimate_gaap: float | None = Field(
|
||||
default=None,
|
||||
description="Estimated GAAP EPS high for the period.",
|
||||
)
|
||||
mean_gaap: float | None = Field(
|
||||
default=None,
|
||||
description="Estimated GAAP EPS mean for the period.",
|
||||
)
|
||||
gaap_actual: float | None = Field(
|
||||
default=None,
|
||||
description="Actual GAAP EPS.",
|
||||
)
|
||||
|
||||
|
||||
class SAForwardEpsEstimatesFetcher(
|
||||
Fetcher[
|
||||
SAForwardEpsEstimatesQueryParams,
|
||||
list[SAForwardEpsEstimatesData],
|
||||
]
|
||||
):
|
||||
"""Seeking Alpha Forward EPS Estimates Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: dict[str, Any]) -> SAForwardEpsEstimatesQueryParams:
|
||||
"""Transform the query."""
|
||||
return SAForwardEpsEstimatesQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: SAForwardEpsEstimatesQueryParams,
|
||||
credentials: dict[str, str] | None,
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the Seeking Alpha endpoint."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_core.provider.utils.client import ClientSession
|
||||
|
||||
tickers = query.symbol.split(",") # type: ignore
|
||||
fp = query.period if query.period == "annual" else "quarterly"
|
||||
url = "https://seekingalpha.com/api/v3/symbol_data/estimates"
|
||||
querystring: dict = {
|
||||
"estimates_data_items": "eps_normalized_actual,eps_normalized_consensus_low,eps_normalized_consensus_mean,"
|
||||
"eps_normalized_consensus_high,eps_normalized_num_of_estimates,"
|
||||
"eps_gaap_actual,eps_gaap_consensus_low,eps_gaap_consensus_mean,eps_gaap_consensus_high,",
|
||||
"period_type": fp,
|
||||
"relative_periods": "-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11",
|
||||
}
|
||||
async with ClientSession(trust_env=True) as session:
|
||||
kwargs = {"session": session}
|
||||
ids = {
|
||||
ticker: await get_seekingalpha_id(ticker, **kwargs)
|
||||
for ticker in tickers
|
||||
}
|
||||
querystring["ticker_ids"] = ("%2C").join(list(ids.values()))
|
||||
response = await amake_request(
|
||||
url, headers=HEADERS, params=querystring, session=session
|
||||
)
|
||||
|
||||
estimates: dict = response.get("estimates", {}) # type: ignore
|
||||
if not estimates:
|
||||
raise OpenBBError(f"No estimates data was returned for: {query.symbol}")
|
||||
|
||||
output: dict = {"ids": ids, "estimates": estimates}
|
||||
|
||||
return output
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: SAForwardEpsEstimatesQueryParams,
|
||||
data: dict,
|
||||
**kwargs: Any,
|
||||
) -> list[SAForwardEpsEstimatesData]:
|
||||
"""Transform the data to the standard format."""
|
||||
tickers = query.symbol.split(",") # type: ignore
|
||||
ids = data.get("ids", {})
|
||||
estimates = data.get("estimates", {})
|
||||
results: list[SAForwardEpsEstimatesData] = []
|
||||
for ticker in tickers:
|
||||
sa_id = str(ids.get(ticker, ""))
|
||||
if sa_id == "" or sa_id not in estimates:
|
||||
warn(f"Symbol Error: No data found for, {ticker}")
|
||||
continue
|
||||
|
||||
seek_object = estimates.get(sa_id, {})
|
||||
if not seek_object:
|
||||
warn(f"No data found for {ticker}")
|
||||
continue
|
||||
items = len(seek_object.get("eps_normalized_num_of_estimates"))
|
||||
if not items:
|
||||
warn(f"No data found for {ticker}")
|
||||
continue
|
||||
for i in range(0, items - 4):
|
||||
eps_estimates: dict = {}
|
||||
eps_estimates["symbol"] = ticker
|
||||
num_estimates = seek_object["eps_normalized_num_of_estimates"].get(
|
||||
str(i)
|
||||
)
|
||||
if not num_estimates:
|
||||
continue
|
||||
period = num_estimates[0].get("period", {})
|
||||
if period:
|
||||
period_type = period.get("periodtypeid")
|
||||
eps_estimates["calendar_year"] = period.get("calendaryear")
|
||||
eps_estimates["calendar_period"] = (
|
||||
"Q" + str(period.get("calendarquarter", ""))
|
||||
if period_type == "quarterly"
|
||||
else "FY"
|
||||
)
|
||||
eps_estimates["date"] = period.get("periodenddate").split("T")[0]
|
||||
eps_estimates["fiscal_year"] = period.get("fiscalyear")
|
||||
eps_estimates["fiscal_period"] = (
|
||||
"Q" + str(period.get("fiscalquarter", ""))
|
||||
if period_type == "quarterly"
|
||||
else "FY"
|
||||
)
|
||||
eps_estimates["number_of_analysts"] = num_estimates[0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
actual = seek_object["eps_normalized_actual"].get(str(i))
|
||||
if actual:
|
||||
eps_estimates["normalized_actual"] = actual[0].get("dataitemvalue")
|
||||
gaap_actual = seek_object["eps_gaap_actual"].get(str(i))
|
||||
if gaap_actual:
|
||||
eps_estimates["gaap_actual"] = gaap_actual[0].get("dataitemvalue")
|
||||
low = seek_object["eps_normalized_consensus_low"].get(str(i))
|
||||
if low:
|
||||
eps_estimates["low_estimate"] = low[0].get("dataitemvalue")
|
||||
gaap_low = seek_object["eps_gaap_consensus_low"].get(str(i))
|
||||
if gaap_low:
|
||||
eps_estimates["low_estimate_gaap"] = gaap_low[0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
high = seek_object["eps_normalized_consensus_high"].get(str(i))
|
||||
if high:
|
||||
eps_estimates["high_estimate"] = high[0].get("dataitemvalue")
|
||||
gaap_high = seek_object["eps_gaap_consensus_high"].get(str(i))
|
||||
if gaap_high:
|
||||
eps_estimates["high_estimate_gaap"] = gaap_high[0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
mean = seek_object["eps_normalized_consensus_mean"].get(str(i))
|
||||
if mean:
|
||||
mean = mean[0].get("dataitemvalue")
|
||||
eps_estimates["mean"] = mean
|
||||
gaap_mean = seek_object["eps_gaap_consensus_mean"].get(str(i))
|
||||
if gaap_mean:
|
||||
eps_estimates["mean_gaap"] = gaap_mean[0].get("dataitemvalue")
|
||||
# Calculate the estimated growth percent.
|
||||
this = float(mean) if mean else None
|
||||
prev = None
|
||||
percent = None
|
||||
try:
|
||||
prev = float(
|
||||
seek_object["eps_normalized_actual"][str(i - 1)][0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
)
|
||||
except KeyError:
|
||||
prev = float(
|
||||
seek_object["eps_normalized_consensus_mean"][str(i - 1)][0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
)
|
||||
if this and prev:
|
||||
percent = (this - prev) / prev
|
||||
eps_estimates["period_growth"] = percent
|
||||
results.append(SAForwardEpsEstimatesData.model_validate(eps_estimates))
|
||||
|
||||
return results
|
||||
@@ -1,195 +0,0 @@
|
||||
"""Seeking Alpha Forward Sales Estimates Model."""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
|
||||
from typing import Any, Literal
|
||||
from warnings import warn
|
||||
|
||||
from openbb_core.app.model.abstract.error import OpenBBError
|
||||
from openbb_core.provider.abstract.fetcher import Fetcher
|
||||
from openbb_core.provider.standard_models.forward_sales_estimates import (
|
||||
ForwardSalesEstimatesData,
|
||||
ForwardSalesEstimatesQueryParams,
|
||||
)
|
||||
from openbb_core.provider.utils.helpers import amake_request
|
||||
from openbb_seeking_alpha.utils.helpers import HEADERS, get_seekingalpha_id
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
|
||||
class SAForwardSalesEstimatesQueryParams(ForwardSalesEstimatesQueryParams):
|
||||
"""Seeking Alpha Forward Sales Estimates Query.
|
||||
|
||||
Source: https://seekingalpha.com/earnings/earnings-calendar
|
||||
"""
|
||||
|
||||
__json_schema_extra__ = {"symbol": {"multiple_items_allowed": True}}
|
||||
|
||||
period: Literal["annual", "quarter"] = Field(
|
||||
default="quarter",
|
||||
description="The reporting period.",
|
||||
json_schema_extra={"choices": ["annual", "quarter"]},
|
||||
)
|
||||
|
||||
@field_validator("symbol", mode="before", check_fields=False)
|
||||
@classmethod
|
||||
def check_symbol(cls, value):
|
||||
"""Check the symbol."""
|
||||
if not value:
|
||||
raise OpenBBError("Symbol is a required field for Seeking Alpha.")
|
||||
return value
|
||||
|
||||
|
||||
class SAForwardSalesEstimatesData(ForwardSalesEstimatesData):
|
||||
"""Seeking Alpha Forward Sales Estimates Data."""
|
||||
|
||||
actual: int | None = Field(
|
||||
default=None,
|
||||
description="Actual sales (revenue) for the period.",
|
||||
)
|
||||
period_growth: float | None = Field(
|
||||
default=None,
|
||||
description="Estimated (or actual if reported) EPS growth for the period.",
|
||||
json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
|
||||
)
|
||||
|
||||
|
||||
class SAForwardSalesEstimatesFetcher(
|
||||
Fetcher[
|
||||
SAForwardSalesEstimatesQueryParams,
|
||||
list[SAForwardSalesEstimatesData],
|
||||
]
|
||||
):
|
||||
"""Seeking Alpha Forward Sales Estimates Fetcher."""
|
||||
|
||||
@staticmethod
|
||||
def transform_query(params: dict[str, Any]) -> SAForwardSalesEstimatesQueryParams:
|
||||
"""Transform the query."""
|
||||
return SAForwardSalesEstimatesQueryParams(**params)
|
||||
|
||||
@staticmethod
|
||||
async def aextract_data(
|
||||
query: SAForwardSalesEstimatesQueryParams,
|
||||
credentials: dict[str, str] | None,
|
||||
**kwargs: Any,
|
||||
) -> dict:
|
||||
"""Return the raw data from the Seeking Alpha endpoint."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from openbb_core.provider.utils.client import ClientSession
|
||||
|
||||
tickers = query.symbol.split(",") # type: ignore
|
||||
fp = query.period if query.period == "annual" else "quarterly"
|
||||
url = "https://seekingalpha.com/api/v3/symbol_data/estimates"
|
||||
querystring = {
|
||||
"estimates_data_items": "revenue_actual,revenue_consensus_low,revenue_consensus_mean,"
|
||||
"revenue_consensus_high,revenue_num_of_estimates",
|
||||
"period_type": fp,
|
||||
"relative_periods": "-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11,12",
|
||||
}
|
||||
|
||||
async with ClientSession(trust_env=True) as session:
|
||||
kwargs = {"session": session}
|
||||
ids = {
|
||||
ticker: await get_seekingalpha_id(ticker, **kwargs)
|
||||
for ticker in tickers
|
||||
}
|
||||
querystring["ticker_ids"] = ("%2C").join(list(ids.values()))
|
||||
response = await amake_request(
|
||||
url, headers=HEADERS, params=querystring, session=session
|
||||
)
|
||||
estimates = response.get("estimates", {}) # type: ignore
|
||||
|
||||
if not estimates:
|
||||
raise OpenBBError(f"No estimates data was returned for: {query.symbol}")
|
||||
output: dict = {"ids": ids, "estimates": estimates}
|
||||
|
||||
return output
|
||||
|
||||
@staticmethod
|
||||
def transform_data(
|
||||
query: SAForwardSalesEstimatesQueryParams,
|
||||
data: dict,
|
||||
**kwargs: Any,
|
||||
) -> list[SAForwardSalesEstimatesData]:
|
||||
"""Transform the data to the standard format."""
|
||||
tickers = query.symbol.split(",") # type: ignore
|
||||
ids = data.get("ids", {})
|
||||
estimates = data.get("estimates", {})
|
||||
results: list[SAForwardSalesEstimatesData] = []
|
||||
for ticker in tickers:
|
||||
sa_id = str(ids.get(ticker, ""))
|
||||
if sa_id == "" or sa_id not in estimates:
|
||||
warn(f"Symbol Error: No data found for, {ticker}")
|
||||
seek_object = estimates.get(sa_id, {})
|
||||
if not seek_object:
|
||||
warn(f"No data found for {ticker}")
|
||||
continue
|
||||
items = len(seek_object.get("revenue_num_of_estimates"))
|
||||
if not items:
|
||||
warn(f"No data found for {ticker}")
|
||||
continue
|
||||
for i in range(0, items - 4):
|
||||
rev_estimates: dict = {}
|
||||
rev_estimates["symbol"] = ticker
|
||||
num_estimates = seek_object["revenue_num_of_estimates"].get(str(i))
|
||||
if not num_estimates:
|
||||
continue
|
||||
period = num_estimates[0].get("period", {})
|
||||
if period:
|
||||
period_type = period.get("periodtypeid")
|
||||
rev_estimates["calendar_year"] = period.get("calendaryear")
|
||||
rev_estimates["calendar_period"] = (
|
||||
"Q" + str(period.get("calendarquarter", ""))
|
||||
if period_type == "quarterly"
|
||||
else "FY"
|
||||
)
|
||||
rev_estimates["date"] = period.get("periodenddate").split("T")[0]
|
||||
rev_estimates["fiscal_year"] = period.get("fiscalyear")
|
||||
rev_estimates["fiscal_period"] = (
|
||||
"Q" + str(period.get("fiscalquarter", ""))
|
||||
if period_type == "quarterly"
|
||||
else "FY"
|
||||
)
|
||||
rev_estimates["number_of_analysts"] = num_estimates[0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
mean = seek_object["revenue_consensus_mean"].get(str(i))
|
||||
if mean:
|
||||
mean = mean[0].get("dataitemvalue")
|
||||
rev_estimates["mean"] = int(float(mean))
|
||||
actual = (
|
||||
seek_object["revenue_actual"][str(i)][0].get("dataitemvalue")
|
||||
if i < 1
|
||||
else None
|
||||
)
|
||||
if actual:
|
||||
rev_estimates["actual"] = int(float(actual))
|
||||
low = seek_object["revenue_consensus_low"].get(str(i))
|
||||
if low:
|
||||
low = low[0].get("dataitemvalue")
|
||||
rev_estimates["low_estimate"] = int(float(low))
|
||||
high = seek_object["revenue_consensus_high"].get(str(i))
|
||||
if high:
|
||||
high = high[0].get("dataitemvalue")
|
||||
rev_estimates["high_estimate"] = int(float(high))
|
||||
# Calculate the estimated growth percent.
|
||||
this = float(mean) if mean else None
|
||||
prev = None
|
||||
percent = None
|
||||
try:
|
||||
prev = float(
|
||||
seek_object["revenue"][str(i - 1)][0].get("dataitemvalue")
|
||||
)
|
||||
except KeyError:
|
||||
prev = float(
|
||||
seek_object["revenue_consensus_mean"][str(i - 1)][0].get(
|
||||
"dataitemvalue"
|
||||
)
|
||||
)
|
||||
if this and prev:
|
||||
percent = (this - prev) / prev
|
||||
rev_estimates["period_growth"] = percent
|
||||
results.append(
|
||||
SAForwardSalesEstimatesData.model_validate(rev_estimates)
|
||||
)
|
||||
|
||||
return results
|
||||
@@ -1 +0,0 @@
|
||||
"""Init file for utils."""
|
||||
@@ -1,43 +0,0 @@
|
||||
"""Seeking Alpha Utilities."""
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from openbb_core.provider.utils.helpers import amake_request
|
||||
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0", # noqa
|
||||
"Accept": "*/*",
|
||||
"Accept-Language": "en-US,en;q=0.9",
|
||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||
"Sec-Fetch-Dest": "empty",
|
||||
"Sec-Fetch-Mode": "cors",
|
||||
"Sec-Fetch-Site": "same-origin",
|
||||
"Connection": "keep-alive",
|
||||
}
|
||||
|
||||
|
||||
def date_range(start_date, end_date):
|
||||
"""Yield dates between start_date and end_date."""
|
||||
for n in range(int((end_date - start_date).days) + 1):
|
||||
yield start_date + timedelta(n)
|
||||
|
||||
|
||||
async def get_seekingalpha_id(symbol: str, **kwargs) -> str:
|
||||
"""Map a ticker symbol to its Seeking Alpha ID."""
|
||||
session = kwargs.get("session")
|
||||
url = "https://seekingalpha.com/api/v3/searches"
|
||||
querystring = {
|
||||
"filter[type]": "symbols",
|
||||
"filter[list]": "all",
|
||||
"page[size]": "100",
|
||||
}
|
||||
querystring["filter[query]"] = symbol
|
||||
if session:
|
||||
response = await amake_request(
|
||||
url, headers=HEADERS, params=querystring, session=session
|
||||
)
|
||||
else:
|
||||
response = await amake_request(url, headers=HEADERS, params=querystring)
|
||||
ids = response.get("symbols") # type: ignore
|
||||
|
||||
return str(ids[0].get("id", "")) if isinstance(ids, list) and ids else ""
|
||||
1959
openbb_platform/providers/seeking_alpha/poetry.lock
generated
vendored
1959
openbb_platform/providers/seeking_alpha/poetry.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,19 +0,0 @@
|
||||
[tool.poetry]
|
||||
name = "openbb-seeking-alpha"
|
||||
version = "1.6.1"
|
||||
description = "Seeking Alpha extension for OpenBB"
|
||||
authors = ["OpenBB Team <hello@openbb.co>"]
|
||||
license = "AGPL-3.0-only"
|
||||
readme = "README.md"
|
||||
packages = [{ include = "openbb_seeking_alpha" }]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<4"
|
||||
openbb-core = "^1.6.10"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry.plugins."openbb_provider_extension"]
|
||||
seeking_alpha = "openbb_seeking_alpha:seeking_alpha_provider"
|
||||
@@ -1 +0,0 @@
|
||||
"""Seeking Alpha provider tests."""
|
||||
@@ -1,384 +0,0 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/earnings_calendar/tickers?filter%5Bcurrency%5D=USD&filter%5Bselected_date%5D=MOCK_DATE&filter%5Bwith_rating%5D=false
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA6tWSkksSVSyio6tBQCUZLJeCwAAAA==
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=600, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '31'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:20 GMT
|
||||
Etag:
|
||||
- W/"8fe32e407a1038ee38753b70e5374b3a"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=8037608641754; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
- machine_cookie_ts=1719483320; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- _QlzymQ8dZ8ofvS2
|
||||
X-Runtime:
|
||||
- '4.317659'
|
||||
X-Served-By:
|
||||
- cache-bfi-krnt7300042-BFI, cache-ams2100136-AMS
|
||||
X-Timer:
|
||||
- S1719483316.795630,VS0,VE4524
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/earnings_calendar/tickers?filter%5Bcurrency%5D=USD&filter%5Bselected_date%5D=MOCK_DATE&filter%5Bwith_rating%5D=false
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA6tWSkksSVSyio6tBQCUZLJeCwAAAA==
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=600, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '31'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:20 GMT
|
||||
Etag:
|
||||
- W/"8fe32e407a1038ee38753b70e5374b3a"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=3092703373685; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
- machine_cookie_ts=1719483320; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- bbIAcqtkbwuVyBAX
|
||||
X-Runtime:
|
||||
- '4.301692'
|
||||
X-Served-By:
|
||||
- cache-bfi-krnt7300029-BFI, cache-ams21031-AMS
|
||||
X-Timer:
|
||||
- S1719483316.795452,VS0,VE4525
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/earnings_calendar/tickers?filter%5Bcurrency%5D=USD&filter%5Bselected_date%5D=MOCK_DATE&filter%5Bwith_rating%5D=false
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA8VYXW/aSBT9K5YfVl0piebLY0/eDGFpEiC0gKLsahVN7BF4azzWeGgXRfnve6Gp
|
||||
bIO1ieymkRCSx2OZM+fcc8/l0Y2lle75X49uErvnrsC+e+Laba7gQkmTJdnyPpKpymJp7m0SfVEG
|
||||
NkhrTfKwsapwzx/dIt0sYfvkegC3MrnePTu5vB6cOJdZdAZr6t9oJbPlfv1utttVqMhqc797J/FO
|
||||
XKNSJQsFL9g/PNWFPR1L80VZ2PvjJvzS3U2CCDtF/JT4c8TOEYLPGULoT9i53j8Sydw9xwwLHxFB
|
||||
4dYZeno6eQZIGQ1aIxxf90uE46ivzRpOxPnN6et1LrPtHrA2uTbwU+OXgFN0BHxQwAk8P9sOti8C
|
||||
P/CRX0fNAioCrzXu215Y4r6V6dIolRVOT2tbOGGaJjKLVCPb4ewi/FTnuwH21KiudFMPIyRwUMcN
|
||||
h8Fbow7vLkvUYbRJ7NbpGZnFRSPUY2Ef89sdqE8xYT7jB6omhLTHGU4rOOOvOzKdcGO1M5XGvhbs
|
||||
cRV3FjPlAQWwlNcq2PM9wdrX8Gw8HZVw5yvlzJJ1nm6dodax8wd8FT/KGbZVnetXaZly7AG/4oBi
|
||||
QXB7iqc3wwrHuV4q5Qwyq0xukkI1c9yAl7yFpDHFGCNCcN2o4Qxa4x1NJiXcUQIlK7fA6ndnTnR2
|
||||
wOyvKV0oXOF7oOYaTo6J30HOw3nFpIZG5qt/lHXmKlplOtXL7csabuC0c+VyJjingtWRIky8Dhru
|
||||
9y8qGo4incr49V3n2J9+QspgAjEPUxJUIwbG0Iva2/HFaFKp1YttJpeycGBxb8eZMnAx3VnUWmfO
|
||||
Ikts8ZKacUPV/oyEFSDIGgccYwK13Lpup5PZvOR4mmQF5MxcFc5HncYQRYv3TJQQPDk9aEYcMSHa
|
||||
4w1vFhW84VqZJJKZc7Oxsdbm/9JGkzm/icQxEj4mgU+qEudwFKw97N7najvqGQ39CNqRMsutM0rW
|
||||
yXF4boDboOrOviV8TlDAWRUr81h70+ovRpVw1d+k+Suz45tw6XkYc3FIZQBLrSt2NppUZoOZSpNM
|
||||
QrUWeWJlukvM09FuZnohRzXMgJ25ZDD6MYJ5lUsvwEHQns2rz7OPpT1dKSOLVWlNHxaz3xvZbRBv
|
||||
A+DuswGFqQ9Gg1oz8hijov0M1Jv370rEvUSDH0dA62tx0jfRMQ4492A0qFPLOGGtdTy+uKpQC1dj
|
||||
Z2QPR/gGIvlxb+2sXMygy3jYqzuu8DrMeIPB5W4Mf/5zZpAn0aeNKqwziDeRtJCInaHRmxzaK8wE
|
||||
2X5Fpq/34gY5dz8FRCkWAa1Fq4AH7TkOB+NqglR2lQLwsYqh6abvq2iPCkEDUWecC9q+cq9uB5U5
|
||||
90p/U2nqDFP9sOPVxod/yzVI+y1IZZyxoO7JmFNMW9dtOO7dlMIO1w/6W0XUz7GxCfDxzHdsVZ01
|
||||
TBmi3MN1WlFA22t4cV2iXUQwBGwydVi17+dbxKd0X7B/P/0HpXkbX1oWAAA=
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=600, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '1127'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:20 GMT
|
||||
Etag:
|
||||
- W/"87e6693575f4ad23fd6fbe2cf87bda0b"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=1495625191801; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
- machine_cookie_ts=1719483320; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- z05Ea_34FLBBGDVb
|
||||
X-Runtime:
|
||||
- '4.343130'
|
||||
X-Served-By:
|
||||
- cache-bfi-kbfi7400039-BFI, cache-ams21034-AMS
|
||||
X-Timer:
|
||||
- S1719483316.791494,VS0,VE4559
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/earnings_calendar/tickers?filter%5Bcurrency%5D=USD&filter%5Bselected_date%5D=MOCK_DATE&filter%5Bwith_rating%5D=false
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=600, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '1822'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:20 GMT
|
||||
Etag:
|
||||
- W/"7b7915277eb0baf771477c2c5e44f61a"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=9262893191359; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
- machine_cookie_ts=1719483320; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- ZbyOD5CnyOaUB59V
|
||||
X-Runtime:
|
||||
- '4.413783'
|
||||
X-Served-By:
|
||||
- cache-bfi-kbfi7400022-BFI, cache-ams21038-AMS
|
||||
X-Timer:
|
||||
- S1719483316.791358,VS0,VE4627
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -1,222 +0,0 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: ''
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/searches?filter%5Blist%5D=all&filter%5Bquery%5D=NVDA&filter%5Btype%5D=symbols&page%5Bsize%5D=100
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA5WUUW/aMBSF/4qVp02CgO3YSVBVKSUwVerYJGgFmvYQiEsthYTZSUVU8d9nF0ri
|
||||
JkHb471O7E/n3HveLFnu1lkirdGvN4vH1ghCMuxZebln1uh8aPUsucmEargexh61ac8qRKLOB6e/
|
||||
B7OnMFBfpdFO/3WzvtWNm8H6VjU3WZqzNFf92dN9eB+AcSb2mYhynqX65qTYqrP0NY6sY+/E4CLf
|
||||
p6iTAnqIQps4fgvGqsJQDLqq3l9xlsTfowOoAYIfew0C7tNNtmNgniswti3BZDE14MoLHKUudb1u
|
||||
OOpj13ag+qKh0YMBp6sK7puIUp6z+UskmAToAB6ydGuQhhFPmmBJpRp1CL6iGqU+sltFC0bjpn2q
|
||||
998OjjaViRRRhHG3Tlgd2xi5LTrNDZ10Vem0EFEsALQRWRrq3LFIgHaJ5EUiAh01ux3DDTH2qU28
|
||||
NiIDqM03efFt/pKJ/B+Mq/mGXUquYMEhsQlpG6hHg0tXlVAhF+ygR/skip55tWPaUnBXJAlAS3Ae
|
||||
ts+zXphoTjfaEELHxsRR9I1hDw02XV1lOwcGePcRdrLFNTYCcfceengI1Rp+BlupVDCmvWo0gupL
|
||||
LSe+gvf0+JDsZ6EyTDIzJkoVYvUNwGiIvG5jqQ097Pqe2pGGeMGyH06mj7Pxon+6pRLzDLVsLGeQ
|
||||
JHIvuEqNkL8yIfkzZzGY/Cl4XoJpkcagD8ZJJCUIgF73WvIe+jF7LtJN/vHa8ffxL+rLp5MbBgAA
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=60, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '570'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:20 GMT
|
||||
Etag:
|
||||
- W/"424e9b30997c83c3edc9fae4ffb8d63a"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=8936971323398; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
- machine_cookie_ts=1719483320; expires=Wed, 27 Jun 2029 10:15:20 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- T6f6FHs3rNIpszua
|
||||
X-Runtime:
|
||||
- '0.058490'
|
||||
X-Served-By:
|
||||
- cache-bfi-kbfi7400064-BFI, cache-ams21032-AMS
|
||||
X-Timer:
|
||||
- S1719483321.612406,VS0,VE263
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: ''
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=MOCK_ITEMS&period_type=MOCK_PERIOD&relative_periods=MOCK_PERIODS&ticker_ids=MOCK_TICKER_IDS
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA+2d3W7bOBCF38XXsUFS/3qO3C0WgZAorQHHyeZv0S3y7jt2nFTpnLHJ8cRy0gAF
|
||||
2qpqa3/QfOQcUdTPyW3/OL+bXy/vJu3Pp5NJf3c/v+ru+9VvJ94XbvVzf3N39q3rbs7O6bx+efdw
|
||||
d7a4/nf1J/Wk/Yv+/PKyP7+fP/YX9Dcn7SS4kE9dOfXNqXOtK1uXzZxzU5e3zk1OJnRaN7/vrx67
|
||||
xcPqfDerazp809/Ory9W/+zzr+5/3PRz+v3kn4fu9r6/Xfygky7nd+fdYnNk0vqXIz/67nbS0v9c
|
||||
nUzohH550d0Oz3o59npe+fIf0qm/PndJH3KaufXnXv1487m7i8dueb75lsuHxeLp6e+TSWPFoFEy
|
||||
CFEM6Kx4BtU08ykMPF0nJhdC45UQsigIdFY0BO9SIXgjCHVZ5VoOeRQHOiuSQzV1nnMongsZF4QP
|
||||
2znQlUVKqNp8uxX8LDhn54U60gvkj2f9vPECYUj1Qr6VQihPPQmmakO1w42lHQNyXpQbC8igSGdQ
|
||||
GDGocqUWuBsRA+RGkUGqG0srBoZuRBCQGyUIyW6sjCDUwU6MCAISI4ZAM4VUMWZGEMpMWQ18cKDv
|
||||
xoyAGNAxYEUyQiqDbROFYhrc2opl65sdVsyboITAp4wIAp3FRkgMgaa6kUPDZmJMXzOcBkeT1bcT
|
||||
zPVscvscIn7UKColHm5MhAcZU8STaszt84cEBoVWFnw2iSAgY0oQko05FecP2dStLyGXtVQsvtxR
|
||||
Ka4olZcCr5SBGrY2V0QG6II+eEKlPH/NXKyUqahT+ps1MTp1DdFpfb0DkC+1lwmvFQQI1YoIKLJW
|
||||
VipZf82QrQEFoJKpWEfZ1Pupr099sb6CNl3uZlLPu/Ogdi2vIwQI1ZEEKLaOngHR1wz+NPiha9df
|
||||
c+3a6TbZhlV8QWhzsvRmMBIB5ZRuaLt3AvKcabwmEwjR4NjreRgRDUeRY/JmOAoyolUgxLOf7/Nv
|
||||
3+3CHz9zdebsFPVB8x/CUDVaCtxDiALykJiCRXroNQUzSoD8zAfDURthQLaRMMTa5heGbUqJT0QJ
|
||||
Q+ntZvkIAzIKxvAVAa0j7REjoFo7uPAZHGp6Ua+Dm94RI6BGy4DLETFAchQZpMrRJgKiIUI7QPB5
|
||||
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
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=60, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '2598'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:22 GMT
|
||||
Etag:
|
||||
- W/"838b81ecf42fb5cfc4c3f6af59a84404"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=7389503728978; expires=Wed, 27 Jun 2029 10:15:22 GMT; path=/;
|
||||
- machine_cookie_ts=1719483322; expires=Wed, 27 Jun 2029 10:15:22 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- 5PJT4n3X_f_75MrY
|
||||
X-Runtime:
|
||||
- '1.099906'
|
||||
X-Served-By:
|
||||
- cache-bfi-krnt7300064-BFI, cache-ams2100130-AMS
|
||||
X-Timer:
|
||||
- S1719483321.058640,VS0,VE1312
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -1,208 +0,0 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: ''
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/searches?filter%5Blist%5D=all&filter%5Bquery%5D=NVDA&filter%5Btype%5D=symbols&page%5Bsize%5D=100
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
H4sIAAAAAAAAA5WUUW/aMBSF/4qVp02CgO3YSVBVKSUwVerYJGgFmvYQiEsthYTZSUVU8d9nF0ri
|
||||
JkHb471O7E/n3HveLFnu1lkirdGvN4vH1ghCMuxZebln1uh8aPUsucmEargexh61ac8qRKLOB6e/
|
||||
B7OnMFBfpdFO/3WzvtWNm8H6VjU3WZqzNFf92dN9eB+AcSb2mYhynqX65qTYqrP0NY6sY+/E4CLf
|
||||
p6iTAnqIQps4fgvGqsJQDLqq3l9xlsTfowOoAYIfew0C7tNNtmNgniswti3BZDE14MoLHKUudb1u
|
||||
OOpj13ag+qKh0YMBp6sK7puIUp6z+UskmAToAB6ydGuQhhFPmmBJpRp1CL6iGqU+sltFC0bjpn2q
|
||||
998OjjaViRRRhHG3Tlgd2xi5LTrNDZ10Vem0EFEsALQRWRrq3LFIgHaJ5EUiAh01ux3DDTH2qU28
|
||||
NiIDqM03efFt/pKJ/B+Mq/mGXUquYMEhsQlpG6hHg0tXlVAhF+ygR/skip55tWPaUnBXJAlAS3Ae
|
||||
ts+zXphoTjfaEELHxsRR9I1hDw02XV1lOwcGePcRdrLFNTYCcfceengI1Rp+BlupVDCmvWo0gupL
|
||||
LSe+gvf0+JDsZ6EyTDIzJkoVYvUNwGiIvG5jqQ097Pqe2pGGeMGyH06mj7Pxon+6pRLzDLVsLGeQ
|
||||
JHIvuEqNkL8yIfkzZzGY/Cl4XoJpkcagD8ZJJCUIgF73WvIe+jF7LtJN/vHa8ffxL+rLp5MbBgAA
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '2'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=60, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '570'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:22 GMT
|
||||
Etag:
|
||||
- W/"424e9b30997c83c3edc9fae4ffb8d63a"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=4818488998497; expires=Wed, 27 Jun 2029 10:15:22 GMT; path=/;
|
||||
- machine_cookie_ts=1719483322; expires=Wed, 27 Jun 2029 10:15:22 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, HIT
|
||||
X-Cache-Hits:
|
||||
- 0, 1
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- T6f6FHs3rNIpszua
|
||||
X-Runtime:
|
||||
- '0.058490'
|
||||
X-Served-By:
|
||||
- cache-bfi-kbfi7400064-BFI, cache-ams2100136-AMS
|
||||
X-Timer:
|
||||
- S1719483323.567896,VS0,VE1
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: ''
|
||||
headers:
|
||||
Accept:
|
||||
- '*/*'
|
||||
Accept-Encoding:
|
||||
- gzip, deflate, br
|
||||
Accept-Language:
|
||||
- de,en-US;q=0.7,en;q=0.3
|
||||
Connection:
|
||||
- keep-alive
|
||||
Sec-Fetch-Dest:
|
||||
- empty
|
||||
Sec-Fetch-Mode:
|
||||
- cors
|
||||
Sec-Fetch-Site:
|
||||
- same-origin
|
||||
method: GET
|
||||
uri: https://seekingalpha.com/api/v3/symbol_data/estimates?estimates_data_items=MOCK_ITEMS&period_type=MOCK_PERIOD&relative_periods=MOCK_PERIODS&ticker_ids=MOCK_TICKER_IDS
|
||||
response:
|
||||
body:
|
||||
string: !!binary |
|
||||
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
|
||||
mV7uB02eUZ/a7s/Pz/8BoWuGb31PAAA=
|
||||
headers:
|
||||
Accept-Ranges:
|
||||
- bytes
|
||||
Age:
|
||||
- '0'
|
||||
Allow:
|
||||
- GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS
|
||||
Cache-Control:
|
||||
- max-age=60, public
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Encoding:
|
||||
- gzip
|
||||
Content-Length:
|
||||
- '1790'
|
||||
Content-Security-Policy:
|
||||
- 'default-src https: wss: data: blob: ''unsafe-inline'' ''unsafe-eval''; report-uri
|
||||
https://seekingalpha.com/report/csp'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 27 Jun 2024 10:15:23 GMT
|
||||
Etag:
|
||||
- W/"f0bf9d89b321bd3343704606eabf5623"
|
||||
Referrer-Policy:
|
||||
- strict-origin-when-cross-origin
|
||||
Set-Cookie:
|
||||
- machine_cookie=3485516037522; expires=Wed, 27 Jun 2029 10:15:23 GMT; path=/;
|
||||
- machine_cookie_ts=1719483323; expires=Wed, 27 Jun 2029 10:15:23 GMT; path=/;
|
||||
Strict-Transport-Security:
|
||||
- max-age=63072000; includeSubDomains; preload
|
||||
Vary:
|
||||
- User-Agent, Accept-Encoding
|
||||
X-Cache:
|
||||
- MISS, MISS
|
||||
X-Cache-Hits:
|
||||
- 0, 0
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Download-Options:
|
||||
- noopen
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Request-Id:
|
||||
- CYDO4gspiOH1ul6P
|
||||
X-Runtime:
|
||||
- '0.566340'
|
||||
X-Served-By:
|
||||
- cache-bfi-krnt7300083-BFI, cache-ams2100086-AMS
|
||||
X-Timer:
|
||||
- S1719483323.754011,VS0,VE789
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
alt-svc:
|
||||
- h3=":443";ma=86400,h3-29=":443";ma=86400,h3-27=":443";ma=86400
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -1,60 +0,0 @@
|
||||
"""Tests for the Seeking Alpha fetchers."""
|
||||
|
||||
import pytest
|
||||
from openbb_core.app.service.user_service import UserService
|
||||
from openbb_seeking_alpha.models.calendar_earnings import SACalendarEarningsFetcher
|
||||
from openbb_seeking_alpha.models.forward_eps_estimates import (
|
||||
SAForwardEpsEstimatesFetcher,
|
||||
)
|
||||
from openbb_seeking_alpha.models.forward_sales_estimates import (
|
||||
SAForwardSalesEstimatesFetcher,
|
||||
)
|
||||
|
||||
test_credentials = UserService().default_user_settings.credentials.model_dump(
|
||||
mode="json"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vcr_config():
|
||||
"""VCR configuration."""
|
||||
return {
|
||||
"filter_headers": [("User-Agent", None)],
|
||||
"filter_query_parameters": [
|
||||
("filter[selected_date]", "MOCK_DATE"),
|
||||
("relative_periods", "MOCK_PERIODS"),
|
||||
("estimates_data_items", "MOCK_ITEMS"),
|
||||
("period_type", "MOCK_PERIOD"),
|
||||
("ticker_ids", "MOCK_TICKER_IDS"),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_sa_calendar_earnings_fetcher(credentials=test_credentials):
|
||||
"""Test the Seeking Alpha Calendar Earnings fetcher."""
|
||||
params = {}
|
||||
|
||||
fetcher = SACalendarEarningsFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_sa_forward_eps_estimates(credentials=test_credentials):
|
||||
"""Test the Seeking Alpha Forward EPS Estimates fetcher."""
|
||||
params = {"symbol": "NVDA"}
|
||||
|
||||
fetcher = SAForwardEpsEstimatesFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
|
||||
|
||||
@pytest.mark.record_http
|
||||
def test_sa_forward_sales_estimates(credentials=test_credentials):
|
||||
"""Test the Seeking Alpha Forward Sales Estimates fetcher."""
|
||||
params = {"symbol": "NVDA"}
|
||||
|
||||
fetcher = SAForwardSalesEstimatesFetcher()
|
||||
result = fetcher.test(params, credentials)
|
||||
assert result is None
|
||||
Reference in New Issue
Block a user