diff --git a/openbb_platform/core/openbb_core/provider/standard_models/calendar_events.py b/openbb_platform/core/openbb_core/provider/standard_models/calendar_events.py new file mode 100644 index 00000000000..b8769d6ee6b --- /dev/null +++ b/openbb_platform/core/openbb_core/provider/standard_models/calendar_events.py @@ -0,0 +1,32 @@ +"""Company Events Calendar Standard Model.""" + +from datetime import date as dateType +from typing import Optional + +from openbb_core.provider.abstract.data import Data +from openbb_core.provider.abstract.query_params import QueryParams +from openbb_core.provider.utils.descriptions import ( + DATA_DESCRIPTIONS, + QUERY_DESCRIPTIONS, +) +from pydantic import Field + + +class CalendarEventsQueryParams(QueryParams): + """Company Events Calendar Query.""" + + start_date: Optional[dateType] = Field( + default=None, description=QUERY_DESCRIPTIONS.get("start_date", "") + ) + end_date: Optional[dateType] = Field( + default=None, description=QUERY_DESCRIPTIONS.get("end_date", "") + ) + + +class CalendarEventsData(Data): + """Company Events Calendar Data.""" + + date: dateType = Field( + description=DATA_DESCRIPTIONS.get("date", "") + " The date of the event." + ) + symbol: str = Field(description=DATA_DESCRIPTIONS.get("symbol", "")) diff --git a/openbb_platform/extensions/equity/integration/test_equity_api.py b/openbb_platform/extensions/equity/integration/test_equity_api.py index a99566b313d..c9452de4180 100644 --- a/openbb_platform/extensions/equity/integration/test_equity_api.py +++ b/openbb_platform/extensions/equity/integration/test_equity_api.py @@ -2219,3 +2219,27 @@ def test_equity_fundamental_management_discussion_analysis(params, headers): result = requests.get(url, headers=headers, timeout=10) assert isinstance(result, requests.Response) assert result.status_code == 200 + + +@parametrize( + "params", + [ + ( + { + "start_date": "2024-01-07", + "end_date": "2024-01-10", + "provider": "fmp", + } + ), + ], +) +@pytest.mark.integration +def test_equity_calendar_events(params, headers): + """Test the equity calendar events endpoint.""" + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://0.0.0.0:8000/api/v1/equity/calendar/events?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/extensions/equity/integration/test_equity_python.py b/openbb_platform/extensions/equity/integration/test_equity_python.py index 7be90e84e23..6f987e9f8c1 100644 --- a/openbb_platform/extensions/equity/integration/test_equity_python.py +++ b/openbb_platform/extensions/equity/integration/test_equity_python.py @@ -2076,3 +2076,24 @@ def test_equity_fundamental_management_discussion_analysis(params, obb): assert result assert isinstance(result, OBBject) assert len(result.results.content) > 0 + + +@parametrize( + "params", + [ + ( + { + "start_date": "2024-01-07", + "end_date": "2024-01-10", + "provider": "fmp", + } + ), + ], +) +@pytest.mark.integration +def test_equity_calendar_events(params, obb): + """Test the equity calendar events endpoint.""" + result = obb.equity.calendar_events(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py b/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py index 7c9395dde3c..5e9e7f64326 100644 --- a/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py +++ b/openbb_platform/extensions/equity/openbb_equity/calendar/calendar_router.py @@ -92,6 +92,30 @@ async def splits( return await OBBject.from_query(Query(**locals())) +@router.command( + model="CalendarEvents", + examples=[ + APIEx(parameters={"provider": "fmp"}), + APIEx( + description="Get company events calendar for specific dates.", + parameters={ + "start_date": "2024-02-01", + "end_date": "2024-02-07", + "provider": "fmp", + }, + ), + ], +) +async def events( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get historical and upcoming company events, such as Investor Day, Conference Call, Earnings Release.""" + return await OBBject.from_query(Query(**locals())) + + @router.command( model="CalendarEarnings", examples=[ diff --git a/openbb_platform/openbb/assets/reference.json b/openbb_platform/openbb/assets/reference.json index 2cdbffdda01..349e1c3ab4f 100644 --- a/openbb_platform/openbb/assets/reference.json +++ b/openbb_platform/openbb/assets/reference.json @@ -11371,6 +11371,135 @@ }, "model": "CalendarSplits" }, + "/equity/calendar/events": { + "deprecated": { + "flag": null, + "message": null + }, + "description": "Get historical and upcoming company events, such as Investor Day, Conference Call, Earnings Release.", + "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.equity.calendar.events(provider='fmp')\n# Get company events calendar for specific dates.\nobb.equity.calendar.events(start_date='2024-02-01', end_date='2024-02-07', provider='fmp')\n```\n\n", + "parameters": { + "standard": [ + { + "name": "start_date", + "type": "Union[date, str]", + "description": "Start date of the data, in YYYY-MM-DD format.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "end_date", + "type": "Union[date, str]", + "description": "End date of the data, in YYYY-MM-DD format.", + "default": null, + "optional": true, + "choices": null + } + ], + "fmp": [] + }, + "returns": { + "OBBject": [ + { + "name": "results", + "type": "List[CalendarEvents]", + "description": "Serializable results." + }, + { + "name": "provider", + "type": "Optional[Literal['fmp']]", + "description": "Provider name." + }, + { + "name": "warnings", + "type": "Optional[List[Warning_]]", + "description": "List of warnings." + }, + { + "name": "chart", + "type": "Optional[Chart]", + "description": "Chart object." + }, + { + "name": "extra", + "type": "Dict[str, Any]", + "description": "Extra info." + } + ] + }, + "data": { + "standard": [ + { + "name": "date", + "type": "Union[date, str]", + "description": "The date of the data. The date of the event.", + "default": "", + "optional": false, + "choices": null + }, + { + "name": "symbol", + "type": "str", + "description": "Symbol representing the entity requested in the data.", + "default": "", + "optional": false, + "choices": null + } + ], + "fmp": [ + { + "name": "exchange", + "type": "str", + "description": "Exchange where the symbol is listed.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "time", + "type": "str", + "description": "The estimated time of the event, local to the exchange.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "timing", + "type": "str", + "description": "The timing of the event - e.g. before, during, or after market hours.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "description", + "type": "str", + "description": "The title of the event.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "url", + "type": "str", + "description": "The URL to the press release for the announcement.", + "default": null, + "optional": true, + "choices": null + }, + { + "name": "announcement_date", + "type": "date", + "description": "The date when the event was announced.", + "default": null, + "optional": true, + "choices": null + } + ] + }, + "model": "CalendarEvents" + }, "/equity/calendar/earnings": { "deprecated": { "flag": null, @@ -26652,7 +26781,7 @@ "message": null }, "description": "Get the Management Discussion & Analysis section from the financial statements for a given company.", - "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', provider='sec')\n# Get the Management Discussion & Analysis section by calendar year and period.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period=4, provider='sec')\n# Setting 'include_tables' to True will attempt to extract all tables in valid Markdown.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period=4, provider='sec', include_tables=True)\n# Setting 'raw_html' to True will bypass extraction and return the raw HTML file, as is. Use this for custom parsing or to access the entire HTML filing.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period=4, provider='sec', raw_html=True)\n```\n\n", + "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', provider='sec')\n# Get the Management Discussion & Analysis section by calendar year and period.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period='Q4', provider='sec')\n# Setting 'include_tables' to True will attempt to extract all tables in valid Markdown.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period='Q4', provider='sec', include_tables=True)\n# Setting 'raw_html' to True will bypass extraction and return the raw HTML file, as is. Use this for custom parsing or to access the entire HTML filing.\nobb.equity.fundamental.management_discussion_analysis(symbol='AAPL', calendar_year=2020, calendar_period='Q4', provider='sec', raw_html=True)\n```\n\n", "parameters": { "standard": [ { @@ -26673,7 +26802,7 @@ }, { "name": "calendar_period", - "type": "int", + "type": "Literal['Q1', 'Q2', 'Q3', 'Q4']", "description": "Calendar period of the report. By default, is the most recent report available for the symbol. If no calendar year and no calendar period are provided, it will return the most recent report.", "default": null, "optional": true, @@ -26681,6 +26810,14 @@ } ], "sec": [ + { + "name": "strategy", + "type": "Literal['inscriptis', 'trafilatura']", + "description": "The strategy to use for extracting the text. Default is 'trafilatura'.", + "default": "trafilatura", + "optional": true, + "choices": null + }, { "name": "wrap_length", "type": "int", diff --git a/openbb_platform/openbb/package/equity_calendar.py b/openbb_platform/openbb/package/equity_calendar.py index 2d57eca41b3..afba3f0425b 100644 --- a/openbb_platform/openbb/package/equity_calendar.py +++ b/openbb_platform/openbb/package/equity_calendar.py @@ -15,6 +15,7 @@ class ROUTER_equity_calendar(Container): """/equity/calendar dividend earnings + events ipo splits """ @@ -208,6 +209,96 @@ class ROUTER_equity_calendar(Container): ) ) + @exception_handler + @validate + def events( + self, + start_date: Annotated[ + Union[datetime.date, None, str], + OpenBBField(description="Start date of the data, in YYYY-MM-DD format."), + ] = None, + end_date: Annotated[ + Union[datetime.date, None, str], + OpenBBField(description="End date of the data, in YYYY-MM-DD format."), + ] = None, + provider: Annotated[ + Optional[Literal["fmp"]], + OpenBBField( + description="The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp." + ), + ] = None, + **kwargs + ) -> OBBject: + """Get historical and upcoming company events, such as Investor Day, Conference Call, Earnings Release. + + Parameters + ---------- + start_date : Union[date, None, str] + Start date of the data, in YYYY-MM-DD format. + end_date : Union[date, None, str] + End date of the data, in YYYY-MM-DD format. + provider : Optional[Literal['fmp']] + The provider to use, by default None. If None, the priority list configured in the settings is used. Default priority: fmp. + + Returns + ------- + OBBject + results : List[CalendarEvents] + Serializable results. + provider : Optional[Literal['fmp']] + Provider name. + warnings : Optional[List[Warning_]] + List of warnings. + chart : Optional[Chart] + Chart object. + extra : Dict[str, Any] + Extra info. + + CalendarEvents + -------------- + date : date + The date of the data. The date of the event. + symbol : str + Symbol representing the entity requested in the data. + exchange : Optional[str] + Exchange where the symbol is listed. (provider: fmp) + time : Optional[str] + The estimated time of the event, local to the exchange. (provider: fmp) + timing : Optional[str] + The timing of the event - e.g. before, during, or after market hours. (provider: fmp) + description : Optional[str] + The title of the event. (provider: fmp) + url : Optional[str] + The URL to the press release for the announcement. (provider: fmp) + announcement_date : Optional[date] + The date when the event was announced. (provider: fmp) + + Examples + -------- + >>> from openbb import obb + >>> obb.equity.calendar.events(provider='fmp') + >>> # Get company events calendar for specific dates. + >>> obb.equity.calendar.events(start_date='2024-02-01', end_date='2024-02-07', provider='fmp') + """ # noqa: E501 + + return self._run( + "/equity/calendar/events", + **filter_inputs( + provider_choices={ + "provider": self._get_provider( + provider, + "equity.calendar.events", + ("fmp",), + ) + }, + standard_params={ + "start_date": start_date, + "end_date": end_date, + }, + extra_params=kwargs, + ) + ) + @exception_handler @validate def ipo( diff --git a/openbb_platform/providers/fmp/openbb_fmp/__init__.py b/openbb_platform/providers/fmp/openbb_fmp/__init__.py index 2e758c72cc6..bbb991ba135 100644 --- a/openbb_platform/providers/fmp/openbb_fmp/__init__.py +++ b/openbb_platform/providers/fmp/openbb_fmp/__init__.py @@ -7,6 +7,7 @@ from openbb_fmp.models.balance_sheet import FMPBalanceSheetFetcher from openbb_fmp.models.balance_sheet_growth import FMPBalanceSheetGrowthFetcher from openbb_fmp.models.calendar_dividend import FMPCalendarDividendFetcher from openbb_fmp.models.calendar_earnings import FMPCalendarEarningsFetcher +from openbb_fmp.models.calendar_events import FMPCalendarEventsFetcher from openbb_fmp.models.calendar_splits import FMPCalendarSplitsFetcher from openbb_fmp.models.cash_flow import FMPCashFlowStatementFetcher from openbb_fmp.models.cash_flow_growth import FMPCashFlowStatementGrowthFetcher @@ -80,6 +81,7 @@ stock market information (news, currencies, and stock prices).""", "BalanceSheetGrowth": FMPBalanceSheetGrowthFetcher, "CalendarDividend": FMPCalendarDividendFetcher, "CalendarEarnings": FMPCalendarEarningsFetcher, + "CalendarEvents": FMPCalendarEventsFetcher, "CalendarSplits": FMPCalendarSplitsFetcher, "CashFlowStatement": FMPCashFlowStatementFetcher, "CashFlowStatementGrowth": FMPCashFlowStatementGrowthFetcher, diff --git a/openbb_platform/providers/fmp/openbb_fmp/models/calendar_events.py b/openbb_platform/providers/fmp/openbb_fmp/models/calendar_events.py new file mode 100644 index 00000000000..bcac2d128ea --- /dev/null +++ b/openbb_platform/providers/fmp/openbb_fmp/models/calendar_events.py @@ -0,0 +1,136 @@ +"""FMP Company Events Calendar Model.""" + +# pylint: disable=unused-argument + +from datetime import date as dateType +from typing import Any, Optional + +from openbb_core.provider.abstract.fetcher import Fetcher +from openbb_core.provider.standard_models.calendar_events import ( + CalendarEventsData, + CalendarEventsQueryParams, +) +from pydantic import Field + + +class FmpCalendarEventsQueryParams(CalendarEventsQueryParams): + """FMP Company Events Calendar Query. + + Source: https://site.financialmodelingprep.com/developer/docs/earnings-calendar-confirmed-api + """ + + __alias_dict__ = {"start_date": "from", "end_date": "to"} + + +class FmpCalendarEventsData(CalendarEventsData): + """FMP Company Events Calendar Data.""" + + __alias_dict__ = { + "announcement_date": "publicationDate", + "timing": "when", + "description": "title", + } + + exchange: Optional[str] = Field( + default=None, + description="Exchange where the symbol is listed.", + ) + time: Optional[str] = Field( + default=None, + description="The estimated time of the event, local to the exchange.", + ) + timing: Optional[str] = Field( + default=None, + description="The timing of the event - e.g. before, during, or after market hours.", + ) + description: Optional[str] = Field( + default=None, + description="The title of the event.", + ) + url: Optional[str] = Field( + default=None, + description="The URL to the press release for the announcement.", + ) + announcement_date: Optional[dateType] = Field( + default=None, + description="The date when the event was announced.", + ) + + +class FMPCalendarEventsFetcher( + Fetcher[FmpCalendarEventsQueryParams, list[FmpCalendarEventsData]] +): + """FMP Company Events Calendar Fetcher.""" + + @staticmethod + def transform_query(params: dict[str, Any]) -> FmpCalendarEventsQueryParams: + """Transform query parameters.""" + return FmpCalendarEventsQueryParams(**params) + + @staticmethod + async def aextract_data( + query: FmpCalendarEventsQueryParams, + credentials: Optional[dict[str, str]], + **kwargs: Any, + ) -> list: + """Extract data from the API.""" + # pylint: disable=import-outside-toplevel + import asyncio # noqa + from datetime import timedelta + from openbb_core.provider.utils.errors import EmptyDataError, OpenBBError + from openbb_fmp.utils.helpers import get_data + from pandas import date_range, to_datetime + + api_key = credentials.get("fmp_api_key") if credentials else "" + + base_url = ( + "https://financialmodelingprep.com/api/v4/earning-calendar-confirmed?" + ) + + start_date = to_datetime( + query.start_date if query.start_date else dateType.today() + ) + end_date = to_datetime( + query.end_date if query.end_date else (dateType.today() + timedelta(days=3)) + ) + + # Assuming limit of 1000 events per request, and peak earnings season + # with 200+ events per day, in America alone, we split into 3-day ranges. + # We don't actually know what the API limitations are, so this is a conservative guess. + date_ranges = date_range(start=start_date, end=end_date, freq="3D") + if end_date not in date_ranges: + date_ranges = date_ranges.append(to_datetime([end_date])) + + urls: list = [] + results: list = [] + + for i in range(len(date_ranges) - 1): + from_date = date_ranges[i].strftime("%Y-%m-%d") + to_date = date_ranges[i + 1].strftime("%Y-%m-%d") + urls.append( + f"{base_url}from={from_date}&to={to_date}&limit=1000&apikey={api_key}" + ) + + async def get_one(url): + """Get data from one URL.""" + try: + response = await get_data(url, **kwargs) + except OpenBBError as e: + raise e from e + + if response: + results.extend(response) + + await asyncio.gather(*[get_one(url) for url in urls]) + + if not results: + raise EmptyDataError("The request was returned empty.") + + return sorted(results, key=lambda x: x["date"]) + + @staticmethod + def transform_data( + query: FmpCalendarEventsQueryParams, data: list, **kwargs: Any + ) -> list[FmpCalendarEventsData]: + """Transform the data.""" + return [FmpCalendarEventsData.model_validate(d) for d in data] diff --git a/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v1.yaml b/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v1.yaml new file mode 100644 index 00000000000..23f3b0b5127 --- /dev/null +++ b/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v1.yaml @@ -0,0 +1,66 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://financialmodelingprep.com/api/v4/earning-calendar-confirmed?apikey=MOCK_API_KEY&from=2025-01-07&limit=1000&to=2025-01-10 + response: + body: + string: !!binary | + H4sIAAAAAAAAA72WX2/aMBTF3/spLJ65JQkpaXijLYytLW0HWltNezBgitVgI8cpQ9O++66dEFJI + K/qHSYCQHbjnnp+P7Z8HhPzBNyGVeDkbyqjSJJX218tKNR1kv0dTKh6YGe7d99utfEbzmR11g6bj + rAYXUybM4FzGmsyoemR6NTWm2j7vOd4ROC444WpmngwjPqKaS3G2fsgH1wPXWZfTkZ1qUy0F+UHF + iJHLRPARn9OInEgxJp0EP1pCyAQnY3IqZzOG3/BDEzkhAybGTJGryYSp1d8mynY81XoeN2u1xWJx + OExiLlgcL7hihyM5qwm2iGtTOWM1I8v1XKfu+WHo15ioWTVg1UCuBowaMGogVwNFNSAnkKoBq6ZW + QTV/q6UsBrdXL8H4vyi8bRSenDNBtCTf2VwqTTo8HiGMwZSrMblJqNLot6mCD8RJpOMP2e55x+j9 + kbXdVgYtIa0MaWWwlSGrDLa/rPIrFnfbF+1Si1v9s9bNpslOWGayYp/hsVff8rjLIrTYrF4ll+SC + z7hmxUXepkpw8RCjwxGjMSPmP6u49gWuK7PeyCmNoiqhGI1bNhxRXA0TqTYYZeA+C5VX90Mn8B2D + yjZgFzw2AFkDhVysGoCsATANwFo/GP2A8iGTDyh/A3RGf0fe/d7drolyGvuDXRKowRnp3/d67TuT + qZVFBTg+bnFRRO4ZVRZoRyZKT3OKWesE98dvVODgkoRVC/UjMF0vcOph3W53gzNIBZrorQQW7PfB + CAQj0CJLBeacMoGAW2YmEEJL7RVa5yfdXWm5fgmtcaJweX0KsHAL2PkJ6aJT6RaY5i/F9ByMZZWT + yyP7yZxCx6+HR4HhdH4CRle6QaaxSuk852ER5cDyJL4Fz2DQ6u2+ee6b0PEWoT5TT3zEBlxTUZaq + krOqwwWe5xwn9xSoIHADt+EZUEV5ZZkqOdByee+KU+d05zS99zZxvAup7Sx1FBWPERd4dj2x5bNb + hcKiezqq3BBfQdAwMFYKwCp4drtABe88ba7bvS9vCEijWd+f6Y0t06+ZeEjQ876MEvOTuHC1eNn3 + dUI27hkfItHAG4Pr23MmkwW5rMKF4WUY62RsXB9SPAe//gF/IBOC7gwAAA== + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-Requested-With, content-type, auth-token, Authorization, stripe-signature, + APPS, publicauthkey, privateauthkey + Access-Control-Allow-Methods: + - GET, POST, OPTIONS + Access-Control-Allow-Origin: + - '*' + Access-Control-Max-Age: + - '3600' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Sat, 08 Feb 2025 23:44:12 GMT + Etag: + - W/"cee-/lugJH6O+1+Voy658pgVQ0Oh1kc" + Server: + - nginx/1.18.0 (Ubuntu) + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + X-Frame-Options: + - SAMEORIGIN + X-Powered-By: + - Express + status: + code: 200 + message: OK +version: 1 diff --git a/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v2.yaml b/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v2.yaml new file mode 100644 index 00000000000..f2cfa125ff6 --- /dev/null +++ b/openbb_platform/providers/fmp/tests/record/http/test_fmp_fetchers/test_fmp_calendar_events_fetcher_urllib3_v2.yaml @@ -0,0 +1,66 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://financialmodelingprep.com/api/v4/earning-calendar-confirmed?apikey=MOCK_API_KEY&from=2025-01-07&limit=1000&to=2025-01-10 + response: + body: + string: !!binary | + H4sIAAAAAAAAA72WX2/aMBTF3/spLJ65JQkpaXijLYytLW0HWltNezBgitVgI8cpQ9O++66dEFJI + K/qHSYCQHbjnnp+P7Z8HhPzBNyGVeDkbyqjSJJX218tKNR1kv0dTKh6YGe7d99utfEbzmR11g6bj + rAYXUybM4FzGmsyoemR6NTWm2j7vOd4ROC444WpmngwjPqKaS3G2fsgH1wPXWZfTkZ1qUy0F+UHF + iJHLRPARn9OInEgxJp0EP1pCyAQnY3IqZzOG3/BDEzkhAybGTJGryYSp1d8mynY81XoeN2u1xWJx + OExiLlgcL7hihyM5qwm2iGtTOWM1I8v1XKfu+WHo15ioWTVg1UCuBowaMGogVwNFNSAnkKoBq6ZW + QTV/q6UsBrdXL8H4vyi8bRSenDNBtCTf2VwqTTo8HiGMwZSrMblJqNLot6mCD8RJpOMP2e55x+j9 + kbXdVgYtIa0MaWWwlSGrDLa/rPIrFnfbF+1Si1v9s9bNpslOWGayYp/hsVff8rjLIrTYrF4ll+SC + z7hmxUXepkpw8RCjwxGjMSPmP6u49gWuK7PeyCmNoiqhGI1bNhxRXA0TqTYYZeA+C5VX90Mn8B2D + yjZgFzw2AFkDhVysGoCsATANwFo/GP2A8iGTDyh/A3RGf0fe/d7drolyGvuDXRKowRnp3/d67TuT + qZVFBTg+bnFRRO4ZVRZoRyZKT3OKWesE98dvVODgkoRVC/UjMF0vcOph3W53gzNIBZrorQQW7PfB + CAQj0CJLBeacMoGAW2YmEEJL7RVa5yfdXWm5fgmtcaJweX0KsHAL2PkJ6aJT6RaY5i/F9ByMZZWT + yyP7yZxCx6+HR4HhdH4CRle6QaaxSuk852ER5cDyJL4Fz2DQ6u2+ee6b0PEWoT5TT3zEBlxTUZaq + krOqwwWe5xwn9xSoIHADt+EZUEV5ZZkqOdByee+KU+d05zS99zZxvAup7Sx1FBWPERd4dj2x5bNb + hcKiezqq3BBfQdAwMFYKwCp4drtABe88ba7bvS9vCEijWd+f6Y0t06+ZeEjQ876MEvOTuHC1eNn3 + dUI27hkfItHAG4Pr23MmkwW5rMKF4WUY62RsXB9SPAe//gF/IBOC7gwAAA== + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Allow-Headers: + - X-Requested-With, content-type, auth-token, Authorization, stripe-signature, + APPS, publicauthkey, privateauthkey + Access-Control-Allow-Methods: + - GET, POST, OPTIONS + Access-Control-Allow-Origin: + - '*' + Access-Control-Max-Age: + - '3600' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json; charset=utf-8 + Date: + - Sat, 08 Feb 2025 23:42:42 GMT + Etag: + - W/"cee-/lugJH6O+1+Voy658pgVQ0Oh1kc" + Server: + - nginx/1.18.0 (Ubuntu) + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + X-Frame-Options: + - SAMEORIGIN + X-Powered-By: + - Express + status: + code: 200 + message: OK +version: 1 diff --git a/openbb_platform/providers/fmp/tests/test_fmp_fetchers.py b/openbb_platform/providers/fmp/tests/test_fmp_fetchers.py index 958a99104d8..5b20428a223 100644 --- a/openbb_platform/providers/fmp/tests/test_fmp_fetchers.py +++ b/openbb_platform/providers/fmp/tests/test_fmp_fetchers.py @@ -11,6 +11,7 @@ from openbb_fmp.models.balance_sheet import FMPBalanceSheetFetcher from openbb_fmp.models.balance_sheet_growth import FMPBalanceSheetGrowthFetcher from openbb_fmp.models.calendar_dividend import FMPCalendarDividendFetcher from openbb_fmp.models.calendar_earnings import FMPCalendarEarningsFetcher +from openbb_fmp.models.calendar_events import FMPCalendarEventsFetcher from openbb_fmp.models.calendar_splits import FMPCalendarSplitsFetcher from openbb_fmp.models.cash_flow import FMPCashFlowStatementFetcher from openbb_fmp.models.cash_flow_growth import FMPCashFlowStatementGrowthFetcher @@ -45,6 +46,7 @@ from openbb_fmp.models.executive_compensation import FMPExecutiveCompensationFet from openbb_fmp.models.financial_ratios import FMPFinancialRatiosFetcher from openbb_fmp.models.forward_ebitda_estimates import FMPForwardEbitdaEstimatesFetcher from openbb_fmp.models.forward_eps_estimates import FMPForwardEpsEstimatesFetcher +from openbb_fmp.models.government_trades import FMPGovernmentTradesFetcher from openbb_fmp.models.historical_dividends import FMPHistoricalDividendsFetcher from openbb_fmp.models.historical_employees import FMPHistoricalEmployeesFetcher from openbb_fmp.models.historical_eps import FMPHistoricalEpsFetcher @@ -71,7 +73,6 @@ from openbb_fmp.models.share_statistics import FMPShareStatisticsFetcher from openbb_fmp.models.treasury_rates import FMPTreasuryRatesFetcher from openbb_fmp.models.world_news import FMPWorldNewsFetcher from openbb_fmp.models.yield_curve import FMPYieldCurveFetcher -from openbb_fmp.models.government_trades import FMPGovernmentTradesFetcher test_credentials = UserService().default_user_settings.credentials.model_dump( mode="json" @@ -777,3 +778,15 @@ def test_fmp_government_trades_fetcher(credentials=test_credentials): fetcher = FMPGovernmentTradesFetcher() result = fetcher.test(params, credentials) assert result is None + + +@pytest.mark.record_http +def test_fmp_calendar_events_fetcher(credentials=test_credentials): + """Test FMP calendar events fetcher.""" + params = { + "start_date": date(2025, 1, 7), + "end_date": date(2025, 1, 10), + } + fetcher = FMPCalendarEventsFetcher() + result = fetcher.test(params, credentials) + assert result is None