remove seeking alpha provider (#7570)

This commit is contained in:
Danglewood
2026-07-08 00:17:17 -07:00
committed by GitHub
parent 9bbc49675d
commit 0085344a0e
17 changed files with 0 additions and 3532 deletions

View File

@@ -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).

View File

@@ -1 +0,0 @@
"""Init file for Provider."""

View File

@@ -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",
)

View File

@@ -1 +0,0 @@
"""Init file for models."""

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1 +0,0 @@
"""Init file for utils."""

View File

@@ -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 ""

File diff suppressed because it is too large Load Diff

View File

@@ -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"

View File

@@ -1 +0,0 @@
"""Seeking Alpha provider tests."""

View File

@@ -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

View File

@@ -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
GGKAzCgxSDajTQJEYrTTImKAtIgZjBgAVXWhbOn4bBM1tggCHQMt3YgJUFF+JUDb7qmWdpk5ukaQ
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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

View File

@@ -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

View File

@@ -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