From 9fa7c2ecd2d5a10eb601009820f5d550a13432ae Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Fri, 29 May 2026 15:13:28 +0100 Subject: [PATCH 1/6] feat: added both afp forecast endpoints --- ...freight_pricing_forecast_explanation.ipynb | 80 ++++++++++ ..._freight_pricing_forecast_timeseries.ipynb | 89 +++++++++++ mkdocs.yml | 2 + pydocmd.yml | 4 + ...re_freight_pricing_forecast_explanation.py | 72 +++++++++ ...ere_freight_pricing_forecast_timeseries.py | 84 ++++++++++ vortexasdk/__init__.py | 6 + vortexasdk/endpoints/__init__.py | 10 ++ ...re_freight_pricing_forecast_explanation.py | 144 ++++++++++++++++++ ...ere_freight_pricing_forecast_timeseries.py | 128 ++++++++++++++++ .../anywhere_freight_pricing_types.py | 2 + vortexasdk/endpoints/endpoints.py | 6 + 12 files changed, 627 insertions(+) create mode 100644 docs/examples/try_me_out/anywhere_freight_pricing_forecast_explanation.ipynb create mode 100644 docs/examples/try_me_out/anywhere_freight_pricing_forecast_timeseries.ipynb create mode 100644 tests/endpoints/test_anywhere_freight_pricing_forecast_explanation.py create mode 100644 tests/endpoints/test_anywhere_freight_pricing_forecast_timeseries.py create mode 100644 vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py create mode 100644 vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py diff --git a/docs/examples/try_me_out/anywhere_freight_pricing_forecast_explanation.ipynb b/docs/examples/try_me_out/anywhere_freight_pricing_forecast_explanation.ipynb new file mode 100644 index 00000000..82060ac5 --- /dev/null +++ b/docs/examples/try_me_out/anywhere_freight_pricing_forecast_explanation.ipynb @@ -0,0 +1,80 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Try out the VortexaSDK" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First let's import our requirements" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from vortexasdk import AnywhereFreightPricingForecastExplanation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You'll need to enter your Vortexa API key when prompted." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get monthly forecast explanation for a Handymax MR2 clean route from Rotterdam to Houston\n", + "result = AnywhereFreightPricingForecastExplanation().search(\n", + " origin_port=\"68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e\",\n", + " destination_port=\"ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb\",\n", + " vessel_class=\"oil_handymax_mr2\",\n", + " product=\"clean\",\n", + " frequency=\"month\",\n", + ")\n", + "df = result.to_df()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's it! You've successfully loaded data using the Vortexa SDK. Check out https://vortechsa.github.io/python-sdk/ for more examples" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.9.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/examples/try_me_out/anywhere_freight_pricing_forecast_timeseries.ipynb b/docs/examples/try_me_out/anywhere_freight_pricing_forecast_timeseries.ipynb new file mode 100644 index 00000000..f32a20a1 --- /dev/null +++ b/docs/examples/try_me_out/anywhere_freight_pricing_forecast_timeseries.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Try out the VortexaSDK" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First let's import our requirements" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from vortexasdk import AnywhereFreightPricingForecastTimeseries\n", + "from datetime import datetime" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You'll need to enter your Vortexa API key when prompted." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get weekly forecast pricing for a Handymax MR2 clean route from Rotterdam to Houston\n", + "routes = [\n", + " {\n", + " \"origin_port\": \"68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e\",\n", + " \"destination_port\": \"ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb\",\n", + " \"product\": \"clean\",\n", + " \"vessel_class\": \"oil_handymax_mr2\",\n", + " }\n", + "]\n", + "result = AnywhereFreightPricingForecastTimeseries().search(\n", + " routes=routes,\n", + " time_min=datetime(2026, 6, 1),\n", + " time_max=datetime(2026, 8, 31),\n", + " frequency=\"week\",\n", + " unit=\"usd_per_tonne\",\n", + ")\n", + "df = result.to_df()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That's it! You've successfully loaded data using the Vortexa SDK. Check out https://vortechsa.github.io/python-sdk/ for more examples" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.9.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/mkdocs.yml b/mkdocs.yml index b12d67be..4689073b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,6 +34,8 @@ pages: Origin: endpoints/anywhere_freight_pricing_top_ports_origin.md Destination: endpoints/anywhere_freight_pricing_top_ports_destination.md Vessel Classes: endpoints/anywhere_freight_pricing_vessel_classes_details.md + Forecast Timeseries: endpoints/anywhere_freight_pricing_forecast_timeseries.md + Forecast Explainability: endpoints/anywhere_freight_pricing_forecast_explainability.md Vessel Availability: Search: endpoints/vessel_availability_search.md Time Series: endpoints/vessel_availability_timeseries.md diff --git a/pydocmd.yml b/pydocmd.yml index 2e0835c6..ac28076e 100644 --- a/pydocmd.yml +++ b/pydocmd.yml @@ -109,6 +109,10 @@ generate: - vortexasdk.endpoints.anywhere_freight_pricing_top_ports_destination++ - endpoints/anywhere_freight_pricing_vessel_classes_details.md: - vortexasdk.endpoints.anywhere_freight_pricing_vessel_classes_details++ + - endpoints/anywhere_freight_pricing_forecast_timeseries.md: + - vortexasdk.endpoints.anywhere_freight_pricing_forecast_timeseries++ + - endpoints/anywhere_freight_pricing_forecast_explainability.md: + - vortexasdk.endpoints.anywhere_freight_pricing_forecast_explanation++ pages: - Home: index.md << README.md - Endpoints: diff --git a/tests/endpoints/test_anywhere_freight_pricing_forecast_explanation.py b/tests/endpoints/test_anywhere_freight_pricing_forecast_explanation.py new file mode 100644 index 00000000..3dd3d7fd --- /dev/null +++ b/tests/endpoints/test_anywhere_freight_pricing_forecast_explanation.py @@ -0,0 +1,72 @@ +from tests.testcases import TestCaseUsingRealAPI +from vortexasdk import AnywhereFreightPricingForecastExplanation + + +class TestAnywhereFreightPricingForecastExplanation(TestCaseUsingRealAPI): + def test_search_returns_data(self): + result = AnywhereFreightPricingForecastExplanation().search( + origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + vessel_class="oil_handymax_mr2", + product="clean", + frequency="month", + ) + + result_list = result.to_list() + assert len(result_list) > 0 + assert "base_date" in result_list[0] + assert "explanation" in result_list[0] + + def test_search_to_df(self): + result = AnywhereFreightPricingForecastExplanation().search( + origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + vessel_class="oil_handymax_mr2", + product="clean", + frequency="month", + ) + + df = result.to_df() + assert len(df) > 0 + assert "base_date" in df.columns + assert "explanation" in df.columns + + def test_search_with_week_frequency(self): + result = AnywhereFreightPricingForecastExplanation().search( + origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + vessel_class="oil_handymax_mr2", + product="clean", + frequency="week", + ) + + result_list = result.to_list() + assert len(result_list) > 0 + assert "base_date" in result_list[0] + assert "explanation" in result_list[0] + + def test_search_with_avoid_zone(self): + result = AnywhereFreightPricingForecastExplanation().search( + origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + vessel_class="oil_handymax_mr2", + product="clean", + frequency="month", + avoid_zone=["Suez Canal"], + ) + + result_list = result.to_list() + assert len(result_list) > 0 + + def test_search_with_include_port_costs(self): + result = AnywhereFreightPricingForecastExplanation().search( + origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + vessel_class="oil_handymax_mr2", + product="clean", + frequency="month", + include_port_costs=True, + ) + + result_list = result.to_list() + assert len(result_list) > 0 diff --git a/tests/endpoints/test_anywhere_freight_pricing_forecast_timeseries.py b/tests/endpoints/test_anywhere_freight_pricing_forecast_timeseries.py new file mode 100644 index 00000000..724d4488 --- /dev/null +++ b/tests/endpoints/test_anywhere_freight_pricing_forecast_timeseries.py @@ -0,0 +1,84 @@ +from datetime import datetime + +from tests.testcases import TestCaseUsingRealAPI +from vortexasdk import AnywhereFreightPricingForecastTimeseries + + +class TestAnywhereFreightPricingForecastTimeseries(TestCaseUsingRealAPI): + def test_search_returns_data(self): + routes = [ + { + "origin_port": "68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + "destination_port": "ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + "product": "clean", + "vessel_class": "oil_handymax_mr2", + } + ] + + result = AnywhereFreightPricingForecastTimeseries().search( + routes=routes, + time_min=datetime(2026, 5, 26), + time_max=datetime(2026, 8, 26), + frequency="week", + unit="usd_per_tonne", + ) + + result_list = result.to_list() + assert len(result_list) > 0 + assert "origin_port" in result_list[0] + assert "destination_port" in result_list[0] + assert "prices" in result_list[0] + assert "lumpsums" in result_list[0] + assert "suggested_tonnage" in result_list[0] + + def test_search_to_df(self): + routes = [ + { + "origin_port": "68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + "destination_port": "ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + "product": "clean", + "vessel_class": "oil_handymax_mr2", + } + ] + + result = AnywhereFreightPricingForecastTimeseries().search( + routes=routes, + time_min=datetime(2026, 5, 26), + time_max=datetime(2026, 8, 26), + frequency="week", + unit="usd_per_tonne", + ) + + df = result.to_df() + assert len(df) > 0 + assert "origin_port" in df.columns + assert "destination_port" in df.columns + assert "vessel_class" in df.columns + assert "suggested_tonnage" in df.columns + + def test_search_multiple_routes(self): + routes = [ + { + "origin_port": "68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + "destination_port": "ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + "vessel_class": "oil_handymax_mr2", + "product": "clean", + }, + { + "origin_port": "7f314ba0a498c36359b1c88781e94a73e19dcc9bbb030ec6b82f944a73d4da2f", + "destination_port": "57a5c821cdc0d9e7187ffc242cd8afd8e86e287b725c1949c65396b575cb5d1e", + "vessel_class": "oil_handymax_mr2", + "product": "clean", + }, + ] + + result = AnywhereFreightPricingForecastTimeseries().search( + routes=routes, + time_min=datetime(2026, 5, 26), + time_max=datetime(2026, 8, 26), + frequency="week", + unit="usd_per_tonne", + ) + + result_list = result.to_list() + assert len(result_list) == 2 diff --git a/vortexasdk/__init__.py b/vortexasdk/__init__.py index 2684aa3e..36805d01 100644 --- a/vortexasdk/__init__.py +++ b/vortexasdk/__init__.py @@ -42,13 +42,16 @@ Refineries, AnywhereFreightPricingLatestUpdateTimestamp, AnywhereFreightPricingPriceTimeseries, + AnywhereFreightPricingForecastTimeseries, AnywhereFreightPricingGetPriceDetails, AnywhereFreightPricingPostPriceDetails, AnywhereFreightPricingTopPortsDestination, AnywhereFreightPricingTopPortsOrigin, AnywhereFreightPricingVesselClassesDetails, + AnywhereFreightPricingForecastExplanation, # AFP types AfpAvoidZone, + AfpExplanationFrequency, AfpFrequency, AfpProduct, AfpRoute, @@ -104,13 +107,16 @@ "Refineries", "AnywhereFreightPricingLatestUpdateTimestamp", "AnywhereFreightPricingPriceTimeseries", + "AnywhereFreightPricingForecastTimeseries", "AnywhereFreightPricingGetPriceDetails", "AnywhereFreightPricingPostPriceDetails", "AnywhereFreightPricingTopPortsDestination", "AnywhereFreightPricingTopPortsOrigin", "AnywhereFreightPricingVesselClassesDetails", + "AnywhereFreightPricingForecastExplanation", # AFP types "AfpAvoidZone", + "AfpExplanationFrequency", "AfpFrequency", "AfpProduct", "AfpRoute", diff --git a/vortexasdk/endpoints/__init__.py b/vortexasdk/endpoints/__init__.py index 88a54583..be202027 100644 --- a/vortexasdk/endpoints/__init__.py +++ b/vortexasdk/endpoints/__init__.py @@ -74,6 +74,9 @@ from vortexasdk.endpoints.anywhere_freight_pricing_price_timeseries import ( AnywhereFreightPricingPriceTimeseries, ) +from vortexasdk.endpoints.anywhere_freight_pricing_forecast_timeseries import ( + AnywhereFreightPricingForecastTimeseries, +) from vortexasdk.endpoints.anywhere_freight_pricing_get_price_details import ( AnywhereFreightPricingGetPriceDetails, ) @@ -89,8 +92,12 @@ from vortexasdk.endpoints.anywhere_freight_pricing_vessel_classes_details import ( AnywhereFreightPricingVesselClassesDetails, ) +from vortexasdk.endpoints.anywhere_freight_pricing_forecast_explanation import ( + AnywhereFreightPricingForecastExplanation, +) from vortexasdk.endpoints.anywhere_freight_pricing_types import ( AfpAvoidZone, + AfpExplanationFrequency, AfpFrequency, AfpProduct, AfpRoute, @@ -140,13 +147,16 @@ "Refineries", "AnywhereFreightPricingLatestUpdateTimestamp", "AnywhereFreightPricingPriceTimeseries", + "AnywhereFreightPricingForecastTimeseries", "AnywhereFreightPricingGetPriceDetails", "AnywhereFreightPricingPostPriceDetails", "AnywhereFreightPricingTopPortsDestination", "AnywhereFreightPricingTopPortsOrigin", "AnywhereFreightPricingVesselClassesDetails", + "AnywhereFreightPricingForecastExplanation", # AFP types for user type annotations "AfpAvoidZone", + "AfpExplanationFrequency", "AfpFrequency", "AfpProduct", "AfpRoute", diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py new file mode 100644 index 00000000..9fd3f0e9 --- /dev/null +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py @@ -0,0 +1,144 @@ +""" +Anywhere Freight Pricing Forecast Explanation endpoint. + +Explains forecast price movements for a route. + +Try me out in your browser: + +[![Binder](https://img.shields.io/badge/try%20me%20out-launch%20notebook-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0teleN20NbsvaOsY2+3LL9/Tz1bC0dLQ1dXZ2Nrf4+Lk5urq7/P3+fn4+Pz9/f7+/gB+Q1KaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gh/VorTECHsa/python-sdk/master?filepath=docs%2Fexamples%2Ftry_me_out%2Fanywhere_freight_pricing_forecast_explanation.ipynb) +""" +from typing import Any, Dict, List, Optional + +from vortexasdk.client import default_client, _handle_response +from vortexasdk.endpoints.endpoints import ( + ANYWHERE_FREIGHT_PRICING_FORECAST_EXPLANATION, +) +from vortexasdk.endpoints.anywhere_freight_pricing_result import ( + AnywhereFreightPricingResult, +) +from vortexasdk.endpoints.anywhere_freight_pricing_types import ( + AfpAvoidZone, + AfpExplanationFrequency, + AfpProduct, + AfpVesselClass, +) +from vortexasdk.logger import get_logger +from vortexasdk.retry_session import retry_get + +logger = get_logger(__name__) + + +class AnywhereFreightPricingForecastExplanation: + """ + Anywhere Freight Pricing Forecast Explanation endpoint. + + Explains forecast price movements for a route by providing a base date + and a list of explanations for upcoming time periods. + + Please note: you will require a subscription to our Anywhere Freight Pricing + module to access this endpoint. + """ + + def __init__(self) -> None: + self._resource = ANYWHERE_FREIGHT_PRICING_FORECAST_EXPLANATION + + def search( + self, + origin_port: str, + destination_port: str, + vessel_class: AfpVesselClass, + product: AfpProduct, + frequency: AfpExplanationFrequency = "month_fixed", + avoid_zone: Optional[List[AfpAvoidZone]] = None, + include_port_costs: Optional[bool] = None, + ) -> AnywhereFreightPricingResult: + """ + Get forecast price movement explanations for a route. + + Given a route (origin, destination, vessel class, product), this returns + a base date and a list of forecast explanations for upcoming time periods. + + # Arguments + + origin_port: Geographic ID of the origin port. + + destination_port: Geographic ID of the destination port. + + vessel_class: The vessel class for the route. Must be one of: + `'oil_coastal'`, `'oil_specialised'`, `'oil_handysize_mr1'`, + `'oil_handymax_mr2'`, `'oil_panamax_lr1'`, `'oil_aframax_lr2'`, + `'oil_suezmax_lr3'`, `'oil_vlcc'`. + + product: The product type. Must be one of: `'clean'`, `'dirty'`, `'crude'`. + + frequency: Frequency for the explanation periods. Must be one of: + `'day'`, `'week'`, `'month'`, `'month_fixed'`. Defaults to `'month_fixed'` + + avoid_zone: Routing zones to avoid for this route. Options: + `'Panama Canal'`, `'Suez Canal'`. + + include_port_costs: Whether to include port costs in the calculation. + + # Returns + `AnywhereFreightPricingResult` + + # Example + _Get monthly forecast explanation for a Handymax MR2 clean route + from Rotterdam to Houston._ + + ```python + >>> from vortexasdk import AnywhereFreightPricingForecastExplanation + >>> result = AnywhereFreightPricingForecastExplanation().search( + ... origin_port="68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + ... destination_port="ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + ... vessel_class="oil_handymax_mr2", + ... product="clean", + ... frequency="month", + ... ) + >>> df = result.to_df() + + ``` + + Returns a DataFrame with columns: + + | | base_date | explanation | + |---:|:------------|:---------------------------------------------------------| + | 0 | 2026-05-26 | [{'start_date': '2026-06-01', 'end_date': '2026-06-30'...}] | + + Each explanation entry contains: + - `start_date`: Start of the forecast period + - `end_date`: End of the forecast period + - `explanation`: Text explanation of expected price movements + + """ + logger.info( + f"Fetching Anywhere Freight Pricing forecast explanation for route " + f"{origin_port} -> {destination_port}" + ) + + params: Dict[str, Any] = { + "origin_port": origin_port, + "destination_port": destination_port, + "vessel_class": vessel_class, + "product": product, + "frequency": frequency, + } + + if avoid_zone is not None: + params["avoid_zone"] = avoid_zone + + if include_port_costs is not None: + params["include_port_costs"] = include_port_costs + + client = default_client() + url = client._create_url_with_params( + self._resource, params, doseq=True + ) + + response = retry_get(url) + + data = _handle_response(response) + return AnywhereFreightPricingResult( + records=data.get("data", []), + reference=data.get("metadata", {}), + ) diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py new file mode 100644 index 00000000..9cad8f2c --- /dev/null +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py @@ -0,0 +1,128 @@ +""" +Try me out in your browser: + +[![Binder](https://img.shields.io/badge/try%20me%20out-launch%20notebook-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0teleN20NbsvaOsY2+3LL9/Tz1bC0dLQ1dXZ2Nrf4+Lk5urq7/P3+fn4+Pz9/f7+/gB+Q1KaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gh/VorTECHsa/python-sdk/master?filepath=docs%2Fexamples%2Ftry_me_out%2Fanywhere_freight_pricing_forecast_timeseries.ipynb) +""" +from datetime import datetime +from typing import Any, Dict, List + +from vortexasdk.endpoints.endpoints import ( + ANYWHERE_FREIGHT_PRICING_FORECAST_TIMESERIES, +) +from vortexasdk.endpoints.anywhere_freight_pricing_result import ( + AnywhereFreightPricingResult, +) +from vortexasdk.endpoints.anywhere_freight_pricing_types import ( + AfpFrequency, + AfpRoute, + AfpUnit, +) +from vortexasdk.logger import get_logger +from vortexasdk.operations import Search +from vortexasdk.api.shared_types import to_date_string + +logger = get_logger(__name__) + + +class AnywhereFreightPricingForecastTimeseries(Search): + """ + Anywhere Freight Pricing Forecast Timeseries endpoint. + + Please note: you will require a subscription to our Anywhere Freight Pricing + module to access this endpoint. + """ + + def __init__(self) -> None: + Search.__init__(self, ANYWHERE_FREIGHT_PRICING_FORECAST_TIMESERIES) + + def search( + self, + routes: List[AfpRoute], + time_min: datetime, + time_max: datetime, + frequency: AfpFrequency = "month", + unit: AfpUnit = "usd_per_tonne", + ) -> AnywhereFreightPricingResult: + """ + Get forecast pricing over time for multiple routes. + + Given a set of details about multiple routes (origin, destination, etc), + a time period and frequency, this returns forecast pricing over time + bucketed by the chosen frequency. + + # Arguments + + routes: A list of route dictionaries. Each route must contain: + - `origin_port` (str, required): Geographical ID of the origin port. + - `destination_port` (str, required): Geographical ID of the destination port. + - `product` (str, required): One of `'clean'`, `'dirty'`, `'crude'`. + - `vessel_class` (str, required): One of `'oil_coastal'`, `'oil_specialised'`, + `'oil_handysize_mr1'`, `'oil_handymax_mr2'`, `'oil_panamax_lr1'`, + `'oil_aframax_lr2'`, `'oil_suezmax_lr3'`, `'oil_vlcc'`. + - `avoid_zone` (list, optional): Routing zones to avoid. Options: + `'Panama Canal'`, `'Suez Canal'`. + - `suggested_tonnage` (float, optional): Suggested tonnage for the route. + + time_min: The UTC start date of the time filter. + + time_max: The UTC end date of the time filter. + + frequency: Frequency denoting the granularity of the time series. + Must be one of: `'day'`, `'week'`, `'doe_week'`, `'month'`, `'quarter'`, `'year'`. + Note: `'quarter'` and `'year'` are not supported by the forecast model and + will return empty prices. + Defaults to `'month'`. + + unit: The unit for pricing. Must be one of: `'usd_per_tonne'`, `'usd_per_barrel'`. + Defaults to `'usd_per_tonne'`. + + # Returns + `AnywhereFreightPricingResult` + + # Example + _Get weekly forecast pricing for a Handymax MR2 clean route from Rotterdam to New York._ + + ```python + >>> from vortexasdk import AnywhereFreightPricingForecastTimeseries + >>> from datetime import datetime + >>> routes = [ + ... { + ... "origin_port": "68faf65af1345067f11dc6723b8da32f00e304a6f33c000118fccd81947deb4e", + ... "destination_port": "ea4921c8ad4fddb5fe3e7a4f834c1aa5863e43283c73da5f02d93bbc5dba72eb", + ... "product": "clean", + ... "vessel_class": "oil_handymax_mr2", + ... } + ... ] + >>> result = AnywhereFreightPricingForecastTimeseries().search( + ... routes=routes, + ... time_min=datetime(2026, 5, 26), + ... time_max=datetime(2026, 8, 26), + ... frequency="week", + ... unit="usd_per_tonne", + ... ) + >>> df = result.to_df() + + ``` + + Returns a DataFrame with columns: + + | | origin_port | destination_port | vessel_class | product | prices | lumpsums | suggested_tonnage | + |---:|:------------|:-----------------|:-----------------|:--------|:----------------------------|:----------------------------|------------------:| + | 0 | 68faf65a... | ea4921c8... | oil_handymax_mr2 | clean | [{'date': '2026-06-01', ...}] | [{'date': '2026-06-01', ...}] | 37000.0 | + + """ + api_params: Dict[str, Any] = { + "routes": routes, + "time_min": to_date_string(time_min), + "time_max": to_date_string(time_max), + "frequency": frequency, + "unit": unit, + } + + response = super().search_with_client( + response_type="breakdown", **api_params + ) + + return AnywhereFreightPricingResult( + records=response["data"], reference=response.get("reference", {}) + ) diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_types.py b/vortexasdk/endpoints/anywhere_freight_pricing_types.py index 7c182d3e..c5bc3544 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_types.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_types.py @@ -24,6 +24,8 @@ AfpAvoidZone = Literal["Panama Canal", "Suez Canal"] +AfpExplanationFrequency = Literal["day", "week", "month", "month_fixed"] + class AfpRoute(TypedDict, total=False): """ diff --git a/vortexasdk/endpoints/endpoints.py b/vortexasdk/endpoints/endpoints.py index 8d125c7b..896c8173 100644 --- a/vortexasdk/endpoints/endpoints.py +++ b/vortexasdk/endpoints/endpoints.py @@ -39,6 +39,9 @@ ANYWHERE_FREIGHT_PRICING_PRICE_TIMESERIES = ( "/v5/anywhere-freight-pricing/price-timeseries" ) +ANYWHERE_FREIGHT_PRICING_FORECAST_TIMESERIES = ( + "/v5/anywhere-freight-pricing/forecast-timeseries" +) ANYWHERE_FREIGHT_PRICING_PRICE_DETAILS = ( "/v5/anywhere-freight-pricing/price/details" ) @@ -51,6 +54,9 @@ ANYWHERE_FREIGHT_PRICING_VESSEL_CLASSES_DETAILS = ( "/v5/anywhere-freight-pricing/vessel-classes-details" ) +ANYWHERE_FREIGHT_PRICING_FORECAST_EXPLANATION = ( + "/v5/anywhere-freight-pricing/forecast-explanation" +) VOYAGES_SEARCH_ENRICHED = "/v5/voyages/search-enriched" VOYAGES_TOP_HITS = "/v5/voyages/top-hits" From 9fc541bc2fc98d190c02503ddc4db7bbc7f05630 Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Fri, 29 May 2026 15:37:12 +0100 Subject: [PATCH 2/6] fix: comment --- mkdocs.yml | 2 +- pydocmd.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 4689073b..2a078d65 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,7 +35,7 @@ pages: Destination: endpoints/anywhere_freight_pricing_top_ports_destination.md Vessel Classes: endpoints/anywhere_freight_pricing_vessel_classes_details.md Forecast Timeseries: endpoints/anywhere_freight_pricing_forecast_timeseries.md - Forecast Explainability: endpoints/anywhere_freight_pricing_forecast_explainability.md + Forecast Explanation: endpoints/anywhere_freight_pricing_forecast_explanation.md Vessel Availability: Search: endpoints/vessel_availability_search.md Time Series: endpoints/vessel_availability_timeseries.md diff --git a/pydocmd.yml b/pydocmd.yml index ac28076e..0c121d39 100644 --- a/pydocmd.yml +++ b/pydocmd.yml @@ -111,7 +111,7 @@ generate: - vortexasdk.endpoints.anywhere_freight_pricing_vessel_classes_details++ - endpoints/anywhere_freight_pricing_forecast_timeseries.md: - vortexasdk.endpoints.anywhere_freight_pricing_forecast_timeseries++ - - endpoints/anywhere_freight_pricing_forecast_explainability.md: + - endpoints/anywhere_freight_pricing_forecast_explanation.md: - vortexasdk.endpoints.anywhere_freight_pricing_forecast_explanation++ pages: - Home: index.md << README.md From d17ea2b77630a6a5adb8bd34d5d606e780b4b3d9 Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Tue, 2 Jun 2026 13:47:58 +0100 Subject: [PATCH 3/6] feat: updated details --- ...re_freight_pricing_forecast_explanation.py | 10 +++--- ...ere_freight_pricing_forecast_timeseries.py | 12 ++++--- .../anywhere_freight_pricing_types.py | 35 +++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py index 9fd3f0e9..daba7e94 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py @@ -19,8 +19,8 @@ from vortexasdk.endpoints.anywhere_freight_pricing_types import ( AfpAvoidZone, AfpExplanationFrequency, + AfpForecastVesselClass, AfpProduct, - AfpVesselClass, ) from vortexasdk.logger import get_logger from vortexasdk.retry_session import retry_get @@ -46,7 +46,7 @@ def search( self, origin_port: str, destination_port: str, - vessel_class: AfpVesselClass, + vessel_class: AfpForecastVesselClass, product: AfpProduct, frequency: AfpExplanationFrequency = "month_fixed", avoid_zone: Optional[List[AfpAvoidZone]] = None, @@ -67,7 +67,9 @@ def search( vessel_class: The vessel class for the route. Must be one of: `'oil_coastal'`, `'oil_specialised'`, `'oil_handysize_mr1'`, `'oil_handymax_mr2'`, `'oil_panamax_lr1'`, `'oil_aframax_lr2'`, - `'oil_suezmax_lr3'`, `'oil_vlcc'`. + `'oil_suezmax_lr3'`, `'oil_vlcc'`, `'lpg_sgc'`, `'lpg_mgc'`, + `'lpg_lgc'`, `'lpg_vlgc_vlec'`, `'lng_small_scale_lng'`, + `'lng_mid_scale_lng'`, `'lng_conventional_lng'`, `'lng_q_fleet'`. product: The product type. Must be one of: `'clean'`, `'dirty'`, `'crude'`. @@ -128,7 +130,7 @@ def search( params["avoid_zone"] = avoid_zone if include_port_costs is not None: - params["include_port_costs"] = include_port_costs + params["include_port_costs"] = str(include_port_costs).lower() client = default_client() url = client._create_url_with_params( diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py index 9cad8f2c..7dd1fafe 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py @@ -13,8 +13,8 @@ AnywhereFreightPricingResult, ) from vortexasdk.endpoints.anywhere_freight_pricing_types import ( + AfpForecastRoute, AfpFrequency, - AfpRoute, AfpUnit, ) from vortexasdk.logger import get_logger @@ -37,10 +37,10 @@ def __init__(self) -> None: def search( self, - routes: List[AfpRoute], + routes: List[AfpForecastRoute], time_min: datetime, time_max: datetime, - frequency: AfpFrequency = "month", + frequency: AfpFrequency = "week", unit: AfpUnit = "usd_per_tonne", ) -> AnywhereFreightPricingResult: """ @@ -58,7 +58,9 @@ def search( - `product` (str, required): One of `'clean'`, `'dirty'`, `'crude'`. - `vessel_class` (str, required): One of `'oil_coastal'`, `'oil_specialised'`, `'oil_handysize_mr1'`, `'oil_handymax_mr2'`, `'oil_panamax_lr1'`, - `'oil_aframax_lr2'`, `'oil_suezmax_lr3'`, `'oil_vlcc'`. + `'oil_aframax_lr2'`, `'oil_suezmax_lr3'`, `'oil_vlcc'`, `'lpg_sgc'`, + `'lpg_mgc'`, `'lpg_lgc'`, `'lpg_vlgc_vlec'`, `'lng_small_scale_lng'`, + `'lng_mid_scale_lng'`, `'lng_conventional_lng'`, `'lng_q_fleet'`. - `avoid_zone` (list, optional): Routing zones to avoid. Options: `'Panama Canal'`, `'Suez Canal'`. - `suggested_tonnage` (float, optional): Suggested tonnage for the route. @@ -71,7 +73,7 @@ def search( Must be one of: `'day'`, `'week'`, `'doe_week'`, `'month'`, `'quarter'`, `'year'`. Note: `'quarter'` and `'year'` are not supported by the forecast model and will return empty prices. - Defaults to `'month'`. + Defaults to `'week'`. unit: The unit for pricing. Must be one of: `'usd_per_tonne'`, `'usd_per_barrel'`. Defaults to `'usd_per_tonne'`. diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_types.py b/vortexasdk/endpoints/anywhere_freight_pricing_types.py index c5bc3544..77908fec 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_types.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_types.py @@ -26,6 +26,25 @@ AfpExplanationFrequency = Literal["day", "week", "month", "month_fixed"] +AfpForecastVesselClass = Literal[ + "oil_coastal", + "oil_specialised", + "oil_handysize_mr1", + "oil_handymax_mr2", + "oil_panamax_lr1", + "oil_aframax_lr2", + "oil_suezmax_lr3", + "oil_vlcc", + "lpg_sgc", + "lpg_mgc", + "lpg_lgc", + "lpg_vlgc_vlec", + "lng_small_scale_lng", + "lng_mid_scale_lng", + "lng_conventional_lng", + "lng_q_fleet", +] + class AfpRoute(TypedDict, total=False): """ @@ -50,3 +69,19 @@ class AfpRouteRequired(TypedDict): destination_port: str product: AfpProduct vessel_class: AfpVesselClass + + +class AfpForecastRoute(TypedDict, total=False): + """ + Route specification for AFP Forecast endpoints. + + Required keys: origin_port, destination_port, product, vessel_class. + Optional keys: avoid_zone, suggested_tonnage. + """ + + origin_port: str + destination_port: str + product: AfpProduct + vessel_class: AfpForecastVesselClass + avoid_zone: List[AfpAvoidZone] + suggested_tonnage: float From 9ab742870a81e86398553120432636a661368904 Mon Sep 17 00:00:00 2001 From: Jack-Burge55 <69143560+Jack-Burge55@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:47:30 +0100 Subject: [PATCH 4/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- vortexasdk/endpoints/anywhere_freight_pricing_types.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_types.py b/vortexasdk/endpoints/anywhere_freight_pricing_types.py index 77908fec..0a0343bf 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_types.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_types.py @@ -85,3 +85,12 @@ class AfpForecastRoute(TypedDict, total=False): vessel_class: AfpForecastVesselClass avoid_zone: List[AfpAvoidZone] suggested_tonnage: float + + +class AfpForecastRouteRequired(TypedDict): + """Required fields for AfpForecastRoute.""" + + origin_port: str + destination_port: str + product: AfpProduct + vessel_class: AfpForecastVesselClass From ac88fd4b706ac027d1fdf8848eedc850f74139a6 Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Tue, 2 Jun 2026 15:21:53 +0100 Subject: [PATCH 5/6] chore: softer text --- .../anywhere_freight_pricing_forecast_explanation.py | 4 ++-- .../endpoints/anywhere_freight_pricing_forecast_timeseries.py | 4 ++-- .../endpoints/anywhere_freight_pricing_get_price_details.py | 4 ++-- .../anywhere_freight_pricing_latest_update_timestamp.py | 4 ++-- .../endpoints/anywhere_freight_pricing_post_price_details.py | 4 ++-- .../endpoints/anywhere_freight_pricing_price_timeseries.py | 4 ++-- .../anywhere_freight_pricing_top_ports_destination.py | 4 ++-- .../endpoints/anywhere_freight_pricing_top_ports_origin.py | 4 ++-- .../anywhere_freight_pricing_vessel_classes_details.py | 4 ++-- vortexasdk/endpoints/onshore_inventories_result.py | 2 +- vortexasdk/endpoints/onshore_inventories_search.py | 2 +- vortexasdk/endpoints/onshore_inventories_timeseries.py | 2 +- vortexasdk/endpoints/vessel_availability_breakdown.py | 2 +- vortexasdk/endpoints/vessel_availability_result.py | 2 +- vortexasdk/endpoints/vessel_availability_search.py | 2 +- vortexasdk/endpoints/vessel_availability_timeseries.py | 2 +- vortexasdk/endpoints/voyages_congestion_breakdown.py | 2 +- vortexasdk/endpoints/voyages_congestion_breakdown_result.py | 2 +- vortexasdk/endpoints/voyages_geography_breakdown.py | 2 +- vortexasdk/endpoints/voyages_product_breakdown.py | 2 +- vortexasdk/endpoints/voyages_routes_breakdown.py | 2 +- vortexasdk/endpoints/voyages_timeseries.py | 2 +- vortexasdk/endpoints/voyages_timeseries_v2.py | 2 +- vortexasdk/endpoints/voyages_top_hits.py | 2 +- vortexasdk/endpoints/voyages_vessel_class_breakdown.py | 2 +- 25 files changed, 34 insertions(+), 34 deletions(-) diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py index daba7e94..63ecd640 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_explanation.py @@ -35,8 +35,8 @@ class AnywhereFreightPricingForecastExplanation: Explains forecast price movements for a route by providing a base date and a list of explanations for upcoming time periods. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py index 7dd1fafe..fcf5fa1c 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_forecast_timeseries.py @@ -28,8 +28,8 @@ class AnywhereFreightPricingForecastTimeseries(Search): """ Anywhere Freight Pricing Forecast Timeseries endpoint. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_get_price_details.py b/vortexasdk/endpoints/anywhere_freight_pricing_get_price_details.py index 36748b5c..a9487f7f 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_get_price_details.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_get_price_details.py @@ -33,8 +33,8 @@ class AnywhereFreightPricingGetPriceDetails: Given a set of details about a single route (origin, destination, etc), this will find rates, lumpsums and prediction confidence of the route. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_latest_update_timestamp.py b/vortexasdk/endpoints/anywhere_freight_pricing_latest_update_timestamp.py index 9a66daca..13ec983e 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_latest_update_timestamp.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_latest_update_timestamp.py @@ -19,8 +19,8 @@ class AnywhereFreightPricingLatestUpdateTimestamp: """ Anywhere Freight Pricing Latest Update Timestamp endpoint. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_post_price_details.py b/vortexasdk/endpoints/anywhere_freight_pricing_post_price_details.py index e156ed6a..5e5cf58d 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_post_price_details.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_post_price_details.py @@ -30,8 +30,8 @@ class AnywhereFreightPricingPostPriceDetails(Search): Given a set of details about multiple routes (origin, destination, etc), this will find rates, lumpsums and prediction confidence for each route. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_price_timeseries.py b/vortexasdk/endpoints/anywhere_freight_pricing_price_timeseries.py index 53332368..a68a38ea 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_price_timeseries.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_price_timeseries.py @@ -28,8 +28,8 @@ class AnywhereFreightPricingPriceTimeseries(Search): """ Anywhere Freight Pricing Price Timeseries endpoint. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_destination.py b/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_destination.py index 2819b512..31b618e7 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_destination.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_destination.py @@ -31,8 +31,8 @@ class AnywhereFreightPricingTopPortsDestination: List top destination ports. A top destination port refers to the port with the greatest volume of incoming voyages from vessels in a specified class. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_origin.py b/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_origin.py index ae659aa1..323cc07a 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_origin.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_top_ports_origin.py @@ -31,8 +31,8 @@ class AnywhereFreightPricingTopPortsOrigin: List top origin ports. A top origin port refers to the port with the greatest volume of outgoing voyages from vessels in a specified class. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/anywhere_freight_pricing_vessel_classes_details.py b/vortexasdk/endpoints/anywhere_freight_pricing_vessel_classes_details.py index fd42172b..947a37ca 100644 --- a/vortexasdk/endpoints/anywhere_freight_pricing_vessel_classes_details.py +++ b/vortexasdk/endpoints/anywhere_freight_pricing_vessel_classes_details.py @@ -23,8 +23,8 @@ class AnywhereFreightPricingVesselClassesDetails: Lists all the vessel classes supported for Anywhere Freight Pricing and the tonnages they can carry. - Please note: you will require a subscription to our Anywhere Freight Pricing - module to access this endpoint. + Please note, a subscription to our Anywhere Freight Pricing module is + required to access Anywhere Freight Pricing. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/onshore_inventories_result.py b/vortexasdk/endpoints/onshore_inventories_result.py index 964905ca..20b1fdc1 100644 --- a/vortexasdk/endpoints/onshore_inventories_result.py +++ b/vortexasdk/endpoints/onshore_inventories_result.py @@ -41,7 +41,7 @@ class OnshoreInventoriesResult(Result): """ Container class holdings search results returns from the crude onshore inventories endpoint. - Please note: you will require a subscription to the Onshore Inventories API to access Crude Onshore Inventories. + Please note, a subscription to our Crude Onshore Inventories module is required to access Crude Onshore Inventories. This class has two methods, `to_list()`, and `to_df()`, allowing search results to be represented as a list of `OnshoreInventories`, or as a `pd.DataFrame` , respectively. diff --git a/vortexasdk/endpoints/onshore_inventories_search.py b/vortexasdk/endpoints/onshore_inventories_search.py index e6a74537..fdc4b95f 100644 --- a/vortexasdk/endpoints/onshore_inventories_search.py +++ b/vortexasdk/endpoints/onshore_inventories_search.py @@ -23,7 +23,7 @@ class OnshoreInventoriesSearch(Search): """ Crude Onshore Inventories Endpoint, use this to search through Vortexa's Onshore Inventory data. - Please note: you will require a subscription to our Crude Onshore Inventories module to access this endpoint. + Please note, a subscription to our Crude Onshore Inventories module is required to access Crude Onshore Inventories. """ _MAX_PAGE_RESULT_SIZE = 500 diff --git a/vortexasdk/endpoints/onshore_inventories_timeseries.py b/vortexasdk/endpoints/onshore_inventories_timeseries.py index 72d881ea..b4d8d830 100644 --- a/vortexasdk/endpoints/onshore_inventories_timeseries.py +++ b/vortexasdk/endpoints/onshore_inventories_timeseries.py @@ -17,7 +17,7 @@ class OnshoreInventoriesTimeseries(Search): """ - Please note: you will require a subscription to our Crude Onshore Inventories module to access this endpoint. + Please note, a subscription to our Crude Onshore Inventories module is required to access Crude Onshore Inventories. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/vessel_availability_breakdown.py b/vortexasdk/endpoints/vessel_availability_breakdown.py index 40bb741a..ae0c1c7f 100644 --- a/vortexasdk/endpoints/vessel_availability_breakdown.py +++ b/vortexasdk/endpoints/vessel_availability_breakdown.py @@ -23,7 +23,7 @@ class VesselAvailabilityBreakdown(Search): """ - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/vessel_availability_result.py b/vortexasdk/endpoints/vessel_availability_result.py index f95ec43b..00072407 100644 --- a/vortexasdk/endpoints/vessel_availability_result.py +++ b/vortexasdk/endpoints/vessel_availability_result.py @@ -32,7 +32,7 @@ class VesselAvailabilityResult(Result): """ Container class holdings search results returns from the availability endpoint. - Please note: you will require a subscription to our Freight module to access Vessel Availability. + Please note, a subscription to our Freight module is required to access this endpoint. This class has two methods, `to_list()`, and `to_df()`, allowing search results to be represented as a list of `Availability`(ies), or as a `pd.DataFrame` , respectively. diff --git a/vortexasdk/endpoints/vessel_availability_search.py b/vortexasdk/endpoints/vessel_availability_search.py index d1767847..aae19fb5 100644 --- a/vortexasdk/endpoints/vessel_availability_search.py +++ b/vortexasdk/endpoints/vessel_availability_search.py @@ -22,7 +22,7 @@ class VesselAvailabilitySearch(Search): """ Vessel Availability Endpoint, use this to search through Vortexa's vessel availability data. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ _MAX_PAGE_RESULT_SIZE = 500 diff --git a/vortexasdk/endpoints/vessel_availability_timeseries.py b/vortexasdk/endpoints/vessel_availability_timeseries.py index f1228f5d..7663a9f2 100644 --- a/vortexasdk/endpoints/vessel_availability_timeseries.py +++ b/vortexasdk/endpoints/vessel_availability_timeseries.py @@ -25,7 +25,7 @@ class VesselAvailabilityTimeseries(Search): """ - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/voyages_congestion_breakdown.py b/vortexasdk/endpoints/voyages_congestion_breakdown.py index 9d3fb1d3..6f372c60 100644 --- a/vortexasdk/endpoints/voyages_congestion_breakdown.py +++ b/vortexasdk/endpoints/voyages_congestion_breakdown.py @@ -25,7 +25,7 @@ class VoyagesCongestionBreakdown(Search): """ - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/voyages_congestion_breakdown_result.py b/vortexasdk/endpoints/voyages_congestion_breakdown_result.py index 5f49e0fd..21719151 100644 --- a/vortexasdk/endpoints/voyages_congestion_breakdown_result.py +++ b/vortexasdk/endpoints/voyages_congestion_breakdown_result.py @@ -34,7 +34,7 @@ class CongestionBreakdownResult(Result): """ Container class holdings search results returns from the voyages congestion breakdown endpoint. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. This class has two methods, `to_list()`, and `to_df()`, allowing search results to be represented as a list of `CongestionBreakdownResult`(ies), or as a `pd.DataFrame` , respectively. diff --git a/vortexasdk/endpoints/voyages_geography_breakdown.py b/vortexasdk/endpoints/voyages_geography_breakdown.py index 99e56aa0..9d730ff9 100644 --- a/vortexasdk/endpoints/voyages_geography_breakdown.py +++ b/vortexasdk/endpoints/voyages_geography_breakdown.py @@ -30,7 +30,7 @@ class VoyagesGeographyBreakdown(Search): """ VoyagesGeographyBreakdown class requires a _geography_property_ to be provided and has an optional _second_breakdown_ property. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. # Arguments diff --git a/vortexasdk/endpoints/voyages_product_breakdown.py b/vortexasdk/endpoints/voyages_product_breakdown.py index 3bda6215..016b3bd3 100644 --- a/vortexasdk/endpoints/voyages_product_breakdown.py +++ b/vortexasdk/endpoints/voyages_product_breakdown.py @@ -31,7 +31,7 @@ class VoyagesProductBreakdown(Search): """ VoyagesProductBreakdown class has an optional _second_breakdown_ property. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. # Arguments diff --git a/vortexasdk/endpoints/voyages_routes_breakdown.py b/vortexasdk/endpoints/voyages_routes_breakdown.py index 4b916012..510b84e1 100644 --- a/vortexasdk/endpoints/voyages_routes_breakdown.py +++ b/vortexasdk/endpoints/voyages_routes_breakdown.py @@ -30,7 +30,7 @@ class VoyagesRoutesBreakdown(Search): """ VoyagesRoutesBreakdown class has an optional _second_breakdown_ property. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. # Arguments diff --git a/vortexasdk/endpoints/voyages_timeseries.py b/vortexasdk/endpoints/voyages_timeseries.py index 3b0f4f6e..f6e8e039 100644 --- a/vortexasdk/endpoints/voyages_timeseries.py +++ b/vortexasdk/endpoints/voyages_timeseries.py @@ -23,7 +23,7 @@ class VoyagesTimeseries(Search): """ - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/voyages_timeseries_v2.py b/vortexasdk/endpoints/voyages_timeseries_v2.py index afc277f7..6f7b2b21 100644 --- a/vortexasdk/endpoints/voyages_timeseries_v2.py +++ b/vortexasdk/endpoints/voyages_timeseries_v2.py @@ -27,7 +27,7 @@ class VoyagesTimeseriesV2(Search): """ VoyagesTimeseriesV2 class requires a _metric_ and a _breakdown_property_ to be provided. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. # Arguments diff --git a/vortexasdk/endpoints/voyages_top_hits.py b/vortexasdk/endpoints/voyages_top_hits.py index 8d568414..79ab4834 100644 --- a/vortexasdk/endpoints/voyages_top_hits.py +++ b/vortexasdk/endpoints/voyages_top_hits.py @@ -26,7 +26,7 @@ class VoyagesTopHits(Search): """ - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. """ def __init__(self) -> None: diff --git a/vortexasdk/endpoints/voyages_vessel_class_breakdown.py b/vortexasdk/endpoints/voyages_vessel_class_breakdown.py index ee9efb59..ef7a55a0 100644 --- a/vortexasdk/endpoints/voyages_vessel_class_breakdown.py +++ b/vortexasdk/endpoints/voyages_vessel_class_breakdown.py @@ -30,7 +30,7 @@ class VoyagesVesselClassBreakdown(Search): """ VoyagesVesselClassBreakdown class has an optional _second_breakdown_ property. - Please note: you will require a subscription to our Freight module to access this endpoint. + Please note, a subscription to our Freight module is required to access this endpoint. # Arguments From 1c2bd6bcb0908d75e026d86fd1389d4a11a9e4fd Mon Sep 17 00:00:00 2001 From: Jack Burgess Date: Tue, 2 Jun 2026 16:09:27 +0100 Subject: [PATCH 6/6] chore: vb --- vortexasdk/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vortexasdk/version.py b/vortexasdk/version.py index 9b719b6e..8c79b2ef 100644 --- a/vortexasdk/version.py +++ b/vortexasdk/version.py @@ -1 +1 @@ -__version__ = "1.0.25" +__version__ = "1.0.26"