From 1309b51b4b15b72e2410363810110f7a75fff7b2 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Fri, 27 Feb 2026 21:32:02 +0300 Subject: [PATCH 1/7] docs: add Releases and PyPI links to documentation homepage This: - add direct link to GitHub Releases page - add direct link to published package on PyPI --- docs/source/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/index.md b/docs/source/index.md index b857b62..0029419 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -23,6 +23,8 @@ workflow-guides/index development-guides/index apidocs/index +Releases +PyPI GitHub ``` From b21787aadb3142485b890a61ac91b80b5326a73b Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Sun, 8 Mar 2026 00:49:00 +0300 Subject: [PATCH 2/7] feat(insights): improve insights API models, request handling, and documentation This: - align Insights API documentation with official Global Fishing Watch API terminology - enhance docstrings with official documentation references and data caveats - update `VesselInsightDatasetVessel` model to use `VesselDataset` enum for dataset identifiers - improve `VesselInsightBody` request model with explicit field aliases and clearer parameter documentation - extend `get_vessel_insights()` to accept vessel IDs directly (`List[str]`) - add validation tests for invalid request payload scenarios - add unit tests verifying request serialization and default dataset handling - improve test coverage for resource behavior when vessel IDs are passed directly --- src/gfwapiclient/client/client.py | 2 +- .../resources/insights/__init__.py | 26 +++++-- .../resources/insights/endpoints.py | 22 +++++- .../resources/insights/models/__init__.py | 34 ++++---- .../resources/insights/models/request.py | 35 ++++++--- .../resources/insights/models/response.py | 26 ++++++- .../resources/insights/resources.py | 78 ++++++++++++++++--- .../insights/models/test_request_models.py | 32 ++++++++ tests/resources/insights/test_resources.py | 51 ++++++++++-- 9 files changed, 253 insertions(+), 53 deletions(-) diff --git a/src/gfwapiclient/client/client.py b/src/gfwapiclient/client/client.py index 1474534..d7b0e98 100644 --- a/src/gfwapiclient/client/client.py +++ b/src/gfwapiclient/client/client.py @@ -53,7 +53,7 @@ class Client: Access to the Events data API resources. insights (InsightResource): - Access to the vessel insights data resources. + Access to the Insights API resources. datasets (DatasetResource): Access to the datasets data resources. diff --git a/src/gfwapiclient/resources/insights/__init__.py b/src/gfwapiclient/resources/insights/__init__.py index 9f108dc..4811520 100644 --- a/src/gfwapiclient/resources/insights/__init__.py +++ b/src/gfwapiclient/resources/insights/__init__.py @@ -1,11 +1,25 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API Resource. +"""Global Fishing Watch (GFW) API Python Client - Insights API Resource. -This module provides the `InsightResource` class, which allows you to interact with the -Global Fishing Watch Vessels Insights API. It provides methods for retrieving -insights data for specified vessels. +This module provides the `InsightResource` class, which allows to interact with the +Insights API. It provides methods for retrieving insights data for specified vessels. -For more details, please refer to the official -`Global Fishing Watch Insights API Documentation `_. +For detailed information about the Insights API, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api + +For more details on the Insights data caveats, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas + +See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ from gfwapiclient.resources.insights.resources import InsightResource diff --git a/src/gfwapiclient/resources/insights/endpoints.py b/src/gfwapiclient/resources/insights/endpoints.py index b3176e0..1337c4a 100644 --- a/src/gfwapiclient/resources/insights/endpoints.py +++ b/src/gfwapiclient/resources/insights/endpoints.py @@ -1,4 +1,4 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API EndPoints.""" +"""Global Fishing Watch (GFW) API Python Client - Get Vessels Insights API Endpoint.""" from gfwapiclient.http.client import HTTPClient from gfwapiclient.http.endpoints import PostEndPoint @@ -21,6 +21,26 @@ class VesselInsightEndPoint( This endpoint retrieves insights for specified vessels based on the provided request parameters. + + For detailed information about the Get Vessels Insights API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels-body + + For more details on the Get Vessels Insights data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas + + See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ def __init__( diff --git a/src/gfwapiclient/resources/insights/models/__init__.py b/src/gfwapiclient/resources/insights/models/__init__.py index 271d250..64fd1e1 100644 --- a/src/gfwapiclient/resources/insights/models/__init__.py +++ b/src/gfwapiclient/resources/insights/models/__init__.py @@ -1,18 +1,26 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API Models. +"""Global Fishing Watch (GFW) API Python Client - Get Vessels Insights API Models. -This module contains the Pydantic models used for interacting with the Global Fishing Watch -Vessels Insights API. These models define the structure of the request and response data -for the API endpoints, ensuring type safety and data validation. +This module defines Pydantic data models used for interacting with the +Vessels Insights API endpoint. These models are used to represent request bodies +and response data when retrieving insights data for specified vessels. -For more information on the Vessels Insights API, please refer to the -`Global Fishing Watch API documentation `_. -""" +For detailed information about the Get Vessels Insights API endpoint, please +refer to the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels + +See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels-body + +For more details on the Get Vessels Insights data caveats, please refer to the +official Global Fishing Watch API documentation: -from gfwapiclient.resources.insights.models.request import VesselInsightBody -from gfwapiclient.resources.insights.models.response import ( - VesselInsightItem, - VesselInsightResult, -) +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas +See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage -__all__ = ["VesselInsightBody", "VesselInsightItem", "VesselInsightResult"] +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list +""" diff --git a/src/gfwapiclient/resources/insights/models/request.py b/src/gfwapiclient/resources/insights/models/request.py index 43b4f37..b049085 100644 --- a/src/gfwapiclient/resources/insights/models/request.py +++ b/src/gfwapiclient/resources/insights/models/request.py @@ -1,4 +1,4 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API Request Models.""" +"""Global Fishing Watch (GFW) API Python Client - Get Vessels Insights API Request Models.""" import datetime @@ -9,6 +9,7 @@ from gfwapiclient.base.models import BaseModel from gfwapiclient.http.models import RequestBody +from gfwapiclient.resources.vessels.base.models.request import VesselDataset __all__ = ["VesselInsightBody", "VesselInsightDatasetVessel", "VesselInsightInclude"] @@ -60,21 +61,29 @@ class VesselInsightDatasetVessel(BaseModel): vessel insights request. Attributes: - dataset_id (str): - The dataset identifier. Default to `"public-global-vessel-identity:latest"`. + dataset_id (VesselDataset): + The dataset identifier. Default to `VesselDataset.VESSEL_IDENTITY_LATEST`. - vessel_id: + vessel_id (str): The vessel identifier. """ - dataset_id: str = Field(...) - vessel_id: str = Field(...) + dataset_id: VesselDataset = Field( + VesselDataset.VESSEL_IDENTITY_LATEST, alias="datasetId" + ) + vessel_id: str = Field(..., alias="vesselId") class VesselInsightBody(RequestBody): """Vessel insight request body. - This model represents the request body for retrieving vessel insights. + Represents includes, start_date, end_date, vessels etc. parameters + for retrieving vessel insights. + + For more details on the Get Vessels Insights API endpoint supported request body, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels-body Attributes: includes (List[VesselInsightInclude]): @@ -86,11 +95,13 @@ class VesselInsightBody(RequestBody): end_date (datetime.date): End date of the request. - vessels List[VesselInsightIdBody]: + vessels (List[VesselInsightDatasetVessel]): List of Dataset and Vessel ID to use to get vessel insights. """ - includes: List[VesselInsightInclude] = Field([VesselInsightInclude.FISHING]) - start_date: datetime.date = Field(...) - end_date: datetime.date = Field(...) - vessels: List[VesselInsightDatasetVessel] = Field(...) + includes: List[VesselInsightInclude] = Field( + [VesselInsightInclude.FISHING], alias="includes" + ) + start_date: datetime.date = Field(..., alias="startDate") + end_date: datetime.date = Field(..., alias="endDate") + vessels: List[VesselInsightDatasetVessel] = Field(..., alias="vessels") diff --git a/src/gfwapiclient/resources/insights/models/response.py b/src/gfwapiclient/resources/insights/models/response.py index ba532d1..d183a75 100644 --- a/src/gfwapiclient/resources/insights/models/response.py +++ b/src/gfwapiclient/resources/insights/models/response.py @@ -1,4 +1,4 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API Response Models.""" +"""Global Fishing Watch (GFW) API Python Client - Get Vessels Insights API Response Models.""" import datetime @@ -220,6 +220,12 @@ class VesselIdentity(BaseModel): class VesselInsightItem(ResultItem): """Vessel insight item. + For more details on the Get Vessels Insights API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels + Attributes: period (Optional[Period], default=None): The period of the insights. @@ -251,7 +257,21 @@ class VesselInsightItem(ResultItem): class VesselInsightResult(Result[VesselInsightItem]): - """Result for Vessel Insights API endpoint.""" + """Result for Vessel Insights API endpoint. + + For more details on the Get Vessels Insights API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels + + Attributes: + _result_item_class (Type[VesselInsightItem]): + The model used for individual result items. + + _data (VesselInsightItem): + The vessel insight item returned in the response. + """ _result_item_class: Type[VesselInsightItem] _data: VesselInsightItem @@ -261,6 +281,6 @@ def __init__(self, data: VesselInsightItem) -> None: Args: data (VesselInsightItem): - The vessel insight item data. + The vessel insight data. """ super().__init__(data=data) diff --git a/src/gfwapiclient/resources/insights/resources.py b/src/gfwapiclient/resources/insights/resources.py index 70639b1..1e884d8 100644 --- a/src/gfwapiclient/resources/insights/resources.py +++ b/src/gfwapiclient/resources/insights/resources.py @@ -1,4 +1,4 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Insights API Resource.""" +"""Global Fishing Watch (GFW) API Python Client - Insights API Resource.""" import datetime @@ -24,7 +24,26 @@ class InsightResource(BaseResource): """Insights data API resource. - This resource provides methods to interact with the insights data API endpoints. + This resource provides methods to interact with the Insights API, specifically + for retrieving insights data for specified vessels. + + For detailed information about the Insights API, please refer to the official + Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api + + For more details on the Insights data caveats, please refer to the official + Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas + + See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ async def get_vessel_insights( @@ -33,34 +52,65 @@ async def get_vessel_insights( includes: Union[List[VesselInsightInclude], List[str]], start_date: Union[datetime.date, str], end_date: Union[datetime.date, str], - vessels: Union[List[VesselInsightDatasetVessel], List[Dict[str, Any]]], + vessels: Union[ + List[VesselInsightDatasetVessel], List[Dict[str, Any]], List[str] + ], **kwargs: Dict[str, Any], ) -> VesselInsightResult: - """Get vessels insights data. + """Get insights for one or several vessels. Retrieves insights data for specified vessels based on the provided request parameters. + The following insight types are supported: + + - Any apparent fishing events in no-take MPAs (`"FISHING"`) + - Any apparent fishing events detected in areas with no known RFMO authorization (`"FISHING"`) + - The vessel's AIS coverage metric (`"COVERAGE"`) + - Any AIS off/disabling events (`"GAP"`) + - If the vessel is present on an RFMO IUU vessel list (`"VESSEL-IDENTITY-IUU-VESSEL-LIST"`) + - The vessel's flag changes (`"VESSEL-IDENTITY-FLAG-CHANGES"`) + - The vessel's flag state presence under the Tokyo/Paris MOU black or grey lists (`"VESSEL-IDENTITY-MOU-LIST"`) + + For detailed information about the Get Vessels Insights API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-by-vessels + + For more details on the Get Vessels Insights data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas + + See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list + Args: - includes (Union[List[VesselInsightInclude], List[str]]): + includes (Union[List[VesselInsightInclude], List[str]], default=["FISHING"]): List of insight types to include in the response. Allowed values are `"COVERAGE"`, `"FISHING"`, `"GAP"`, `"VESSEL-IDENTITY-FLAG-CHANGES"`, `"VESSEL-IDENTITY-IUU-VESSEL-LIST"`, `"VESSEL-IDENTITY-MOU-LIST"`. Example: `["FISHING", "GAP"]`. - start_date (Union[datetime.date, str]): + start_date (Union[datetime.date, str], default=None): The start date for the insights period. Allowed values: A string in `ISO 8601 format` or `datetime.date` instance. Example: "2020-01-01" or `datetime.date(2020, 1, 1)`. - end_date (Union[datetime.date, str]): + end_date (Union[datetime.date, str], default=None): The end date for the insights period. Allowed values: A string in `ISO 8601 format` or `datetime.date` instance. Example: `"2025-03-03"` or `datetime.date(2025, 3, 3)`. - vessels (Union[List[VesselInsightDatasetVessel], List[Dict[str, Any]]]): + vessels (Union[List[VesselInsightDatasetVessel], List[Dict[str, Any]], List[str]], default=None): List of vessel identifiers to retrieve insights for. - Example: `[{"vessel_id": "785101812-2127-e5d2-e8bf-7152c5259f5f", "dataset_id": "public-global-vessel-identity:latest",}]`. + Example: `[{"vessel_id": "785101812-2127-e5d2-e8bf-7152c5259f5f", "dataset_id": "public-global-vessel-identity:latest"}]` + or `["785101812-2127-e5d2-e8bf-7152c5259f5f"]`. **kwargs (Dict[str, Any]): Additional keyword arguments. @@ -98,16 +148,22 @@ def _prepare_get_vessel_insights_request_body( includes: Union[List[VesselInsightInclude], List[str]], start_date: Union[datetime.date, str], end_date: Union[datetime.date, str], - vessels: Union[List[VesselInsightDatasetVessel], List[Dict[str, Any]]], + vessels: Union[ + List[VesselInsightDatasetVessel], List[Dict[str, Any]], List[str] + ], **kwargs: Dict[str, Any], ) -> VesselInsightBody: """Prepare and returns get vessel insights request body.""" try: + _vessels: List[Union[VesselInsightDatasetVessel, Dict[str, Any]]] = [ + {"vessel_id": vessel} if isinstance(vessel, str) else vessel + for vessel in vessels + ] _request_body: Dict[str, Any] = { "includes": includes, "start_date": start_date, "end_date": end_date, - "vessels": vessels, + "vessels": _vessels, } request_body: VesselInsightBody = VesselInsightBody(**_request_body) except pydantic.ValidationError as exc: diff --git a/tests/resources/insights/models/test_request_models.py b/tests/resources/insights/models/test_request_models.py index b6e3669..06c8513 100644 --- a/tests/resources/insights/models/test_request_models.py +++ b/tests/resources/insights/models/test_request_models.py @@ -3,6 +3,7 @@ from typing import Any, Dict from gfwapiclient.resources.insights.models.request import VesselInsightBody +from gfwapiclient.resources.vessels.base.models.request import VesselDataset def test_vessel_insight_request_body_serializes_all_fields( @@ -16,4 +17,35 @@ def test_vessel_insight_request_body_serializes_all_fields( assert vessel_insight_body.start_date is not None assert vessel_insight_body.end_date is not None assert vessel_insight_body.vessels is not None + + for vessel in vessel_insight_body.vessels: + assert vessel.dataset_id is not None + + assert vessel_insight_body.to_json_body() == mock_raw_vessel_insight_request_body + + +def test_vessel_insight_request_body_serializes_none_vessels_dataset_id_with_default( + mock_raw_vessel_insight_request_body: Dict[str, Any], +) -> None: + """Test that `VesselInsightBody` serializes vessels with no dataset id using default dataset id.""" + raw_vessel_insight_request_body: Dict[str, Any] = { + **mock_raw_vessel_insight_request_body + } + raw_vessel_insight_request_body["vessels"] = [ + {**vessel, "dataset_id": None} + for vessel in raw_vessel_insight_request_body["vessels"] + ] + + vessel_insight_body: VesselInsightBody = VesselInsightBody( + **raw_vessel_insight_request_body + ) + assert vessel_insight_body.includes is not None + assert vessel_insight_body.start_date is not None + assert vessel_insight_body.end_date is not None + assert vessel_insight_body.vessels is not None + + for vessel in vessel_insight_body.vessels: + assert vessel.dataset_id is not None + assert vessel.dataset_id == VesselDataset.VESSEL_IDENTITY_LATEST + assert vessel_insight_body.to_json_body() == mock_raw_vessel_insight_request_body diff --git a/tests/resources/insights/test_resources.py b/tests/resources/insights/test_resources.py index c1902cc..d85a9f4 100644 --- a/tests/resources/insights/test_resources.py +++ b/tests/resources/insights/test_resources.py @@ -5,6 +5,8 @@ import pytest import respx +from pydantic.alias_generators import to_snake + from gfwapiclient.exceptions.validation import RequestBodyValidationError from gfwapiclient.http.client import HTTPClient from gfwapiclient.resources.insights.models.request import ( @@ -41,10 +43,48 @@ async def test_insight_resource_get_vessel_insights( assert isinstance(data, VesselInsightItem) +@pytest.mark.asyncio +@pytest.mark.respx +async def test_insight_resource_get_vessel_insights_by_vessels_ids( + mock_http_client: HTTPClient, + mock_raw_vessel_insight_request_body: Dict[str, Any], + mock_raw_vessel_insight_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `InsightResource` get vessel insights with list of vessels ids succeeds with valid response.""" + mock_responsex.post("/insights/vessels").respond( + 200, json=mock_raw_vessel_insight_item + ) + resource = InsightResource(http_client=mock_http_client) + result = await resource.get_vessel_insights( + includes=mock_raw_vessel_insight_request_body["includes"], + start_date=mock_raw_vessel_insight_request_body["startDate"], + end_date=mock_raw_vessel_insight_request_body["endDate"], + vessels=[ + v["vesselId"] for v in mock_raw_vessel_insight_request_body["vessels"] + ], + ) + data = cast(VesselInsightItem, result.data()) + assert isinstance(result, VesselInsightResult) + assert isinstance(data, VesselInsightItem) + + +@pytest.mark.parametrize( + "invalid_vessel_insight_request_body", + [ + {"includes": ["INVALID_INCLUDE"]}, + {"start_date": "INVALID_START_DATE"}, + {"end_date": "INVALID_END_DATE"}, + {"vessels": [None]}, + {"vessels": [{"vessel_id": None}]}, + {"vessels": [{"vessel_id": None, "dataset_id": "INVALID_DATASET_ID"}]}, + ], +) @pytest.mark.asyncio async def test_insight_resource_get_vessel_insights_validation_error_raises( mock_http_client: HTTPClient, mock_raw_vessel_insight_request_body: Dict[str, Any], + invalid_vessel_insight_request_body: Dict[str, Any], ) -> None: """Test `InsightResource` get vessel insights raises `RequestBodyValidationError` with invalid parameters.""" resource = InsightResource(http_client=mock_http_client) @@ -53,9 +93,8 @@ async def test_insight_resource_get_vessel_insights_validation_error_raises( RequestBodyValidationError, match=VESSEL_INSIGHT_REQUEST_BODY_VALIDATION_ERROR_MESSAGE, ): - await resource.get_vessel_insights( - includes=["INVALID_INCLUDE"], - start_date=mock_raw_vessel_insight_request_body["startDate"], - end_date=mock_raw_vessel_insight_request_body["endDate"], - vessels=mock_raw_vessel_insight_request_body["vessels"], - ) + raw_vessel_insight_request_body: Dict[str, Any] = { + **{to_snake(k): v for k, v in mock_raw_vessel_insight_request_body.items()}, + **invalid_vessel_insight_request_body, + } + await resource.get_vessel_insights(**raw_vessel_insight_request_body) From c3e64c5fc7472b01492033b76f1aeaaa3e74042c Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Sun, 8 Mar 2026 01:07:23 +0300 Subject: [PATCH 3/7] test(insights): expand integration coverage for additional insight types This: - update integration tests to pass vessel IDs directly instead of `{dataset_id, vessel_id}` objects - add integration tests for `VESSEL-IDENTITY-FLAG-CHANGES` insight type - add integration tests for `VESSEL-IDENTITY-MOU-LIST` insight type --- tests/integration/test_insights_api.py | 107 ++++++++++++++++++------- 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/tests/integration/test_insights_api.py b/tests/integration/test_insights_api.py index 4bc2b81..36ab47d 100644 --- a/tests/integration/test_insights_api.py +++ b/tests/integration/test_insights_api.py @@ -38,10 +38,7 @@ async def test_insights_get_vessel_insights_get_insights_for_fishing_events( start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "785101812-2127-e5d2-e8bf-7152c5259f5f", - } + "785101812-2127-e5d2-e8bf-7152c5259f5f", ], ) data: VesselInsightItem = cast(VesselInsightItem, result.data()) @@ -72,10 +69,7 @@ async def test_insights_get_vessel_insights_get_insights_for_ais_off_events( start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "2339c52c3-3a84-1603-f968-d8890f23e1ed", - } + "2339c52c3-3a84-1603-f968-d8890f23e1ed", ], ) data: VesselInsightItem = cast(VesselInsightItem, result.data()) @@ -106,10 +100,7 @@ async def test_insights_get_vessel_insights_get_insights_for_ais_coverage_events start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "2339c52c3-3a84-1603-f968-d8890f23e1ed", - } + "2339c52c3-3a84-1603-f968-d8890f23e1ed", ], ) data: VesselInsightItem = cast(VesselInsightItem, result.data()) @@ -141,10 +132,70 @@ async def test_insights_get_vessel_insights_get_insights_for_iuu_list( start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", - } + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], + ) + data: VesselInsightItem = cast(VesselInsightItem, result.data()) + assert isinstance(result, VesselInsightResult) + assert isinstance(data, VesselInsightItem) + + df: pd.DataFrame = cast(pd.DataFrame, result.df()) + assert isinstance(df, pd.DataFrame) + assert len(df) >= 1, "Expected at least one row in the DataFrame." + assert list(df.columns) == list(dict(data).keys()) + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_insights_get_vessel_insights_get_insights_for_flag_changes( + gfw_client: gfw.Client, +) -> None: + """Test getting vessel insights related to flag changes. + + This test verifies that the `get_vessel_insights` method correctly retrieves + insights for a specific vessel related to its flag changes within a given date range. + It checks the structure and content of the returned data, ensuring it's a + valid `VesselInsightResult` and that the data can be converted to a + pandas DataFrame. + """ + result: VesselInsightResult = await gfw_client.insights.get_vessel_insights( + includes=["VESSEL-IDENTITY-FLAG-CHANGES"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], + ) + data: VesselInsightItem = cast(VesselInsightItem, result.data()) + assert isinstance(result, VesselInsightResult) + assert isinstance(data, VesselInsightItem) + + df: pd.DataFrame = cast(pd.DataFrame, result.df()) + assert isinstance(df, pd.DataFrame) + assert len(df) >= 1, "Expected at least one row in the DataFrame." + assert list(df.columns) == list(dict(data).keys()) + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_insights_get_vessel_insights_get_insights_for_mou_list( + gfw_client: gfw.Client, +) -> None: + """Test getting vessel insights related to to being listed in the MOU list. + + This test verifies that the `get_vessel_insights` method correctly retrieves + insights for a specific vessel related to its flag state presence under the + Tokyo/Paris MOU black or grey lists within a given date range. + It checks the structure and content of the returned data, ensuring it's a + valid `VesselInsightResult` and that the data can be converted to a + pandas DataFrame. + """ + result: VesselInsightResult = await gfw_client.insights.get_vessel_insights( + includes=["VESSEL-IDENTITY-MOU-LIST"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "785101812-2127-e5d2-e8bf-7152c5259f5f", ], ) data: VesselInsightItem = cast(VesselInsightItem, result.data()) @@ -171,22 +222,20 @@ async def test_insights_get_vessel_insights_get_insights_for_multiple_insight_ty converted to a pandas DataFrame. """ result: VesselInsightResult = await gfw_client.insights.get_vessel_insights( - includes=["FISHING", "GAP", "VESSEL-IDENTITY-IUU-VESSEL-LIST", "COVERAGE"], + includes=[ + "FISHING", + "GAP", + "VESSEL-IDENTITY-IUU-VESSEL-LIST", + "COVERAGE", + "VESSEL-IDENTITY-FLAG-CHANGES", + "VESSEL-IDENTITY-MOU-LIST", + ], start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "785101812-2127-e5d2-e8bf-7152c5259f5f", - }, - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "2339c52c3-3a84-1603-f968-d8890f23e1ed", - }, - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", - }, + "785101812-2127-e5d2-e8bf-7152c5259f5f", + "2339c52c3-3a84-1603-f968-d8890f23e1ed", + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", ], ) data: VesselInsightItem = cast(VesselInsightItem, result.data()) From 3af0d22e69c5e27ce35e3ff574bce387e900fc68 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Sun, 8 Mar 2026 03:01:20 +0300 Subject: [PATCH 4/7] docs(insights): expand Insights API usage guide and notebook examples This: - update caveat references and dataset examples in documentation - update vessel input examples to use vessel ID strings instead of `{dataset_id, vessel_id}` objects - expand examples for `FISHING`, `VESSEL-IDENTITY-IUU-VESSEL-LIST`, and `COVERAGE` insights - expand examples for `GAP`, `VESSEL-IDENTITY-FLAG-CHANGES`, and `VESSEL-IDENTITY-MOU-LIST` insights - add example showing retrieval of multiple insights for multiple vessels --- docs/source/usage-guides/insights-api.md | 274 ++++- notebooks/usage-guides/insights-api.ipynb | 981 +++++++++++++++++- .../resources/insights/__init__.py | 4 +- .../resources/insights/endpoints.py | 4 +- .../resources/insights/models/__init__.py | 4 +- .../resources/insights/resources.py | 8 +- tests/integration/test_insights_api.py | 8 +- 7 files changed, 1258 insertions(+), 25 deletions(-) diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 840f848..03e4065 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -4,7 +4,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access aggregated insights about vessel activities. Currently, the [Insights API](https://globalfishingwatch.org/our-apis/documentation#insights-api) focuses on providing summaries related to specific vessels over a defined time range. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/insights-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Insights Data Caveats](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas)—it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits. +> **Note:** See the [Fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits. ## Prerequisites @@ -40,16 +40,15 @@ The `gfw_client.insights` object provides methods for retrieving insights data f The `get_vessel_insights()` method allows you to retrieve aggregated insights for a specific vessel within a given time range. +**Important:** `start_date` must be on or after `January 1, 2020` + ```python insights_result = await gfw_client.insights.get_vessel_insights( includes=["FISHING"], start_date="2020-01-01", end_date="2025-03-03", vessels=[ - { - "dataset_id": "public-global-vessel-identity:latest", - "vessel_id": "785101812-2127-e5d2-e8bf-7152c5259f5f", - } + "785101812-2127-e5d2-e8bf-7152c5259f5f", ], ) ``` @@ -100,6 +99,271 @@ dtypes: object(6) memory usage: 180.0+ bytes ``` +## Getting Apparent Fishing-related Insights (`FISHING`) + +```python +fishing_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["FISHING"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "785101812-2127-e5d2-e8bf-7152c5259f5f", + "2339c52c3-3a84-1603-f968-d8890f23e1ed", + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], +) +``` + +```python +fishing_insights_df = fishing_insights_result.df() +print(fishing_insights_df) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 0 non-null object + 3 coverage 0 non-null object + 4 apparent_fishing 1 non-null object + 5 vessel_identity 0 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting AIS off/disabling Insights (`GAP`) + +```python +gap_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["GAP"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "785101812-2127-e5d2-e8bf-7152c5259f5f", + "2339c52c3-3a84-1603-f968-d8890f23e1ed", + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], +) +``` + +```python +gap_insights_df = gap_insights_result.df() +print(gap_insights_df) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 1 non-null object + 3 coverage 0 non-null object + 4 apparent_fishing 0 non-null object + 5 vessel_identity 0 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting AIS Coverage Metrics Insights (`COVERAGE`) + +```python +coverage_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["COVERAGE"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "2339c52c3-3a84-1603-f968-d8890f23e1ed", + ], +) +``` + +```python +coverage_insights_df = coverage_insights_result.df() +print(coverage_insights_df) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 0 non-null object + 3 coverage 1 non-null object + 4 apparent_fishing 0 non-null object + 5 vessel_identity 0 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting Being Listed in IUU (Illegal,Unreported, and Unregulated) Insights (`VESSEL-IDENTITY-IUU-VESSEL-LIST`) + +```python +iuu_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["VESSEL-IDENTITY-IUU-VESSEL-LIST"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], +) +``` + +```python +iuu_insights_df = iuu_insights_result.df() +print(iuu_insights_df) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 0 non-null object + 3 coverage 0 non-null object + 4 apparent_fishing 0 non-null object + 5 vessel_identity 1 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting Flag Changes Insights (`VESSEL-IDENTITY-FLAG-CHANGES`) + +```python +flag_changes_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["VESSEL-IDENTITY-FLAG-CHANGES"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], +) +``` + +```python +flag_changes_insights_df = flag_changes_insights_result.df() +print(flag_changes_insights_df.info()) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 0 non-null object + 3 coverage 0 non-null object + 4 apparent_fishing 0 non-null object + 5 vessel_identity 1 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting Flag State Presence under Tokyo/Paris MOU black or grey Lists Insights (`VESSEL-IDENTITY-MOU-LIST`) + +```python +mou_insights_result = await gfw_client.insights.get_vessel_insights( + includes=["VESSEL-IDENTITY-MOU-LIST"], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "785101812-2127-e5d2-e8bf-7152c5259f5f", + ], +) +``` + +```python +mou_insights_df = mou_insights_result.df() +print(mou_insights_df.info()) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 0 non-null object + 3 coverage 0 non-null object + 4 apparent_fishing 0 non-null object + 5 vessel_identity 1 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +## Getting Multiple Insights for Multiple Vessels + +```python +all_insights_result = await gfw_client.insights.get_vessel_insights( + includes=[ + "FISHING", + "GAP", + "VESSEL-IDENTITY-IUU-VESSEL-LIST", + "COVERAGE", + "VESSEL-IDENTITY-FLAG-CHANGES", + "VESSEL-IDENTITY-MOU-LIST", + ], + start_date="2020-01-01", + end_date="2025-03-03", + vessels=[ + "785101812-2127-e5d2-e8bf-7152c5259f5f", + "2339c52c3-3a84-1603-f968-d8890f23e1ed", + "2d26aa452-2d4f-4cae-2ec4-377f85e88dcb", + ], +) +``` + +```python +all_insights_df = all_insights_result.df() +print(all_insights_df.info()) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 6 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 period 1 non-null object + 1 vessel_ids_without_identity 0 non-null object + 2 gap 1 non-null object + 3 coverage 1 non-null object + 4 apparent_fishing 1 non-null object + 5 vessel_identity 1 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + ## Next Steps Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine vessel insights with event data, vessel details, and more. Check out the following resources: diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 5b7c2ad..ff74a42 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -36,7 +36,7 @@ "id": "d1d62e3b-fc42-422a-bb7d-2ccc927ba494", "metadata": {}, "source": [ - "**Note:** See the [Insights Data Caveats](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas)—it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits." + "**Note:** See the [Fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits." ] }, { @@ -120,6 +120,8 @@ "source": [ "import os\n", "\n", + "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -188,10 +190,7 @@ " start_date=\"2020-01-01\",\n", " end_date=\"2025-03-03\",\n", " vessels=[\n", - " {\n", - " \"dataset_id\": \"public-global-vessel-identity:latest\",\n", - " \"vessel_id\": \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", - " }\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", " ],\n", ")" ] @@ -281,7 +280,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "\n", + "\n", "RangeIndex: 1 entries, 0 to 0\n", "Data columns (total 6 columns):\n", " # Column Non-Null Count Dtype \n", @@ -350,7 +349,7 @@ " None\n", " None\n", " None\n", - " {'datasets': ['public-global-fishing-events:v3...\n", + " {'datasets': ['public-global-fishing-events:v4...\n", " None\n", " \n", " \n", @@ -365,7 +364,7 @@ "0 None None None \n", "\n", " apparent_fishing vessel_identity \n", - "0 {'datasets': ['public-global-fishing-events:v3... None " + "0 {'datasets': ['public-global-fishing-events:v4... None " ] }, "execution_count": 10, @@ -376,6 +375,972 @@ "source": [ "insights_df.head()" ] + }, + { + "cell_type": "markdown", + "id": "49e9dbd4-b022-4247-a6d5-fe7c6dcb4b3b", + "metadata": {}, + "source": [ + "## Getting Apparent Fishing-related Insights (`FISHING`)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "262203ed-2597-4074-96b6-b31c3aa74e2c", + "metadata": {}, + "outputs": [], + "source": [ + "fishing_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"FISHING\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "5304c902-bbbb-4869-ab05-6d61a4869936", + "metadata": {}, + "outputs": [], + "source": [ + "fishing_insights_df = fishing_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "83a14697-b13b-4ff0-b9ff-182e6f2ac1b7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 0 non-null object\n", + " 3 coverage 0 non-null object\n", + " 4 apparent_fishing 1 non-null object\n", + " 5 vessel_identity 0 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "fishing_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "df330962-c019-4f7b-b9e9-bddcd79fd1f2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...NoneNoneNone{'datasets': ['public-global-fishing-events:v4...None
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity gap coverage \\\n", + "0 None None None \n", + "\n", + " apparent_fishing vessel_identity \n", + "0 {'datasets': ['public-global-fishing-events:v4... None " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fishing_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "f4dc3e37-ad7f-44d9-929c-4eb83678a9a7", + "metadata": {}, + "source": [ + "## Getting AIS off/disabling Insights (`GAP`)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "c18aba46-d1bd-4375-bf15-97afac3b5f3e", + "metadata": {}, + "outputs": [], + "source": [ + "gap_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"GAP\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "d9285f1c-db40-4215-9358-1a07473de2e2", + "metadata": {}, + "outputs": [], + "source": [ + "gap_insights_df = gap_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "c9cb34a3-dcdc-4f2e-b772-ff67e812e511", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 1 non-null object\n", + " 3 coverage 0 non-null object\n", + " 4 apparent_fishing 0 non-null object\n", + " 5 vessel_identity 0 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "gap_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "99a2d935-e3c5-49df-bead-d8bc1986abbd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...None{'datasets': ['public-global-gaps-events:v4.0'...NoneNoneNone
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity \\\n", + "0 None \n", + "\n", + " gap coverage \\\n", + "0 {'datasets': ['public-global-gaps-events:v4.0'... None \n", + "\n", + " apparent_fishing vessel_identity \n", + "0 None None " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gap_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "669396bc-6a19-493a-a1a9-d7840aad51aa", + "metadata": {}, + "source": [ + "## Getting AIS Coverage Metrics Insights (`COVERAGE`)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "0e991053-9015-4724-b7d6-ac1f0f77a880", + "metadata": {}, + "outputs": [], + "source": [ + "coverage_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"COVERAGE\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e7470865-9c6a-4e99-a1e8-10bfb760a723", + "metadata": {}, + "outputs": [], + "source": [ + "coverage_insights_df = coverage_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "14d88f0d-f779-4ad8-b565-37857be65067", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 0 non-null object\n", + " 3 coverage 1 non-null object\n", + " 4 apparent_fishing 0 non-null object\n", + " 5 vessel_identity 0 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "coverage_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "615025e8-5ee6-4562-b92f-b52030cf24d9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...NoneNone{'blocks': '8917', 'blocks_with_positions': '7...NoneNone
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity gap \\\n", + "0 None None \n", + "\n", + " coverage apparent_fishing \\\n", + "0 {'blocks': '8917', 'blocks_with_positions': '7... None \n", + "\n", + " vessel_identity \n", + "0 None " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "coverage_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "a72eebf7-e389-4ef4-8a0e-b97e11769292", + "metadata": {}, + "source": [ + "## Getting Being Listed in IUU (Illegal,Unreported, and Unregulated) Insights (`VESSEL-IDENTITY-IUU-VESSEL-LIST`)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "8d865858-c2dd-4561-9331-8a8e0e3134ef", + "metadata": {}, + "outputs": [], + "source": [ + "iuu_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"VESSEL-IDENTITY-IUU-VESSEL-LIST\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "2bbe1f16-4a8f-43dd-b8c4-8f077e8ac754", + "metadata": {}, + "outputs": [], + "source": [ + "iuu_insights_df = iuu_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "5bb6f05c-1582-4d26-ab75-d39fa0f0e1f2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 0 non-null object\n", + " 3 coverage 0 non-null object\n", + " 4 apparent_fishing 0 non-null object\n", + " 5 vessel_identity 1 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "iuu_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e12ef530-72f3-4309-baa6-7c7a158c7db4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...NoneNoneNoneNone{'datasets': ['public-global-vessel-identity:v...
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity gap coverage apparent_fishing \\\n", + "0 None None None None \n", + "\n", + " vessel_identity \n", + "0 {'datasets': ['public-global-vessel-identity:v... " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "iuu_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "da557346-5d3a-4ef4-9b3f-7e3aac3ae0c8", + "metadata": {}, + "source": [ + "## Getting Flag Changes Insights (`VESSEL-IDENTITY-FLAG-CHANGES`)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "c034210b-29f3-496d-b07e-f2c2700e191e", + "metadata": {}, + "outputs": [], + "source": [ + "flag_changes_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"VESSEL-IDENTITY-FLAG-CHANGES\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "884088b9-7c37-491f-87fd-2005925942cb", + "metadata": {}, + "outputs": [], + "source": [ + "flag_changes_insights_df = flag_changes_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "71b633c9-328c-40f7-8707-871ec79beb0a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 0 non-null object\n", + " 3 coverage 0 non-null object\n", + " 4 apparent_fishing 0 non-null object\n", + " 5 vessel_identity 1 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "flag_changes_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "c25b642a-fe12-4d77-8684-3c54b8f8bfd4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...NoneNoneNoneNone{'datasets': ['public-global-vessel-identity:v...
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity gap coverage apparent_fishing \\\n", + "0 None None None None \n", + "\n", + " vessel_identity \n", + "0 {'datasets': ['public-global-vessel-identity:v... " + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flag_changes_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "7037a8e7-a66c-4ee5-a08a-0f924ef14360", + "metadata": {}, + "source": [ + "## Getting Flag State Presence under Tokyo/Paris MOU black or grey Lists Insights (`VESSEL-IDENTITY-MOU-LIST`)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "2fcda356-43db-4060-9e17-678e349b5ee7", + "metadata": {}, + "outputs": [], + "source": [ + "mou_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"VESSEL-IDENTITY-MOU-LIST\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "950f328b-4b16-493f-af98-73f5ba8be300", + "metadata": {}, + "outputs": [], + "source": [ + "mou_insights_df = mou_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "c9ae5cad-01d0-4d97-bc5c-6d18cc7052df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 0 non-null object\n", + " 3 coverage 0 non-null object\n", + " 4 apparent_fishing 0 non-null object\n", + " 5 vessel_identity 1 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "mou_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "65ea0ba4-b9bd-4157-b488-e6a7f50a9778", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...NoneNoneNoneNone{'datasets': ['public-global-vessel-identity:v...
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity gap coverage apparent_fishing \\\n", + "0 None None None None \n", + "\n", + " vessel_identity \n", + "0 {'datasets': ['public-global-vessel-identity:v... " + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mou_insights_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "a70de4c2-1922-4ed1-84b7-de438103654a", + "metadata": {}, + "source": [ + "## Getting Multiple Insights for Multiple Vessels" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "6561627c-b472-401d-8ec6-befca13a41d6", + "metadata": {}, + "outputs": [], + "source": [ + "all_insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\n", + " \"FISHING\",\n", + " \"GAP\",\n", + " \"VESSEL-IDENTITY-IUU-VESSEL-LIST\",\n", + " \"COVERAGE\",\n", + " \"VESSEL-IDENTITY-FLAG-CHANGES\",\n", + " \"VESSEL-IDENTITY-MOU-LIST\",\n", + " ],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "09af2c8f-ee6c-4d6d-8372-092c4bef2051", + "metadata": {}, + "outputs": [], + "source": [ + "all_insights_df = all_insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "cf48b48e-b6ee-4ef8-8db8-1f265cbe29e8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 6 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 period 1 non-null object\n", + " 1 vessel_ids_without_identity 0 non-null object\n", + " 2 gap 1 non-null object\n", + " 3 coverage 1 non-null object\n", + " 4 apparent_fishing 1 non-null object\n", + " 5 vessel_identity 1 non-null object\n", + "dtypes: object(6)\n", + "memory usage: 180.0+ bytes\n" + ] + } + ], + "source": [ + "all_insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "73316b77-f4f8-4eca-8c0d-be0d0561f8f6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
periodvessel_ids_without_identitygapcoverageapparent_fishingvessel_identity
0{'start_date': 2020-01-01, 'end_date': 2025-03...None{'datasets': ['public-global-gaps-events:v4.0'...{'blocks': '53447', 'blocks_with_positions': '...{'datasets': ['public-global-fishing-events:v4...{'datasets': ['public-global-vessel-identity:v...
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2025-03... \n", + "\n", + " vessel_ids_without_identity \\\n", + "0 None \n", + "\n", + " gap \\\n", + "0 {'datasets': ['public-global-gaps-events:v4.0'... \n", + "\n", + " coverage \\\n", + "0 {'blocks': '53447', 'blocks_with_positions': '... \n", + "\n", + " apparent_fishing \\\n", + "0 {'datasets': ['public-global-fishing-events:v4... \n", + "\n", + " vessel_identity \n", + "0 {'datasets': ['public-global-vessel-identity:v... " + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "all_insights_df.head()" + ] } ], "metadata": { diff --git a/src/gfwapiclient/resources/insights/__init__.py b/src/gfwapiclient/resources/insights/__init__.py index 4811520..cca8d3c 100644 --- a/src/gfwapiclient/resources/insights/__init__.py +++ b/src/gfwapiclient/resources/insights/__init__.py @@ -13,12 +13,12 @@ See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas -See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage - See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ diff --git a/src/gfwapiclient/resources/insights/endpoints.py b/src/gfwapiclient/resources/insights/endpoints.py index 1337c4a..52c0304 100644 --- a/src/gfwapiclient/resources/insights/endpoints.py +++ b/src/gfwapiclient/resources/insights/endpoints.py @@ -34,12 +34,12 @@ class VesselInsightEndPoint( See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas - See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage - See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ diff --git a/src/gfwapiclient/resources/insights/models/__init__.py b/src/gfwapiclient/resources/insights/models/__init__.py index 64fd1e1..9aa519f 100644 --- a/src/gfwapiclient/resources/insights/models/__init__.py +++ b/src/gfwapiclient/resources/insights/models/__init__.py @@ -16,11 +16,11 @@ See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas -See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage - See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage +See: https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list """ diff --git a/src/gfwapiclient/resources/insights/resources.py b/src/gfwapiclient/resources/insights/resources.py index 1e884d8..e77cc9b 100644 --- a/src/gfwapiclient/resources/insights/resources.py +++ b/src/gfwapiclient/resources/insights/resources.py @@ -82,14 +82,18 @@ async def get_vessel_insights( See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas - See: https://globalfishingwatch.org/our-apis/documentation#what-does-it-mean-that-an-api-dataset-is-in-prototype-stage - See: https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas See: https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap + See: https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list + **Important:** + + `start_date` must be on or after `January 1, 2020` + Args: includes (Union[List[VesselInsightInclude], List[str]], default=["FISHING"]): List of insight types to include in the response. diff --git a/tests/integration/test_insights_api.py b/tests/integration/test_insights_api.py index 36ab47d..7790811 100644 --- a/tests/integration/test_insights_api.py +++ b/tests/integration/test_insights_api.py @@ -25,10 +25,10 @@ async def test_insights_get_vessel_insights_get_insights_for_fishing_events( gfw_client: gfw.Client, ) -> None: - """Test getting vessel insights related to fishing events. + """Test getting vessel insights related to apparent fishing events. This test verifies that the `get_vessel_insights` method correctly retrieves - insights for a specific vessel related to fishing activity within a given + insights for a specific vessel related to apparent fishing activity within a given date range. It checks the structure and content of the returned data, ensuring it's a valid `VesselInsightResult` and that the data can be converted to a pandas DataFrame. @@ -56,10 +56,10 @@ async def test_insights_get_vessel_insights_get_insights_for_fishing_events( async def test_insights_get_vessel_insights_get_insights_for_ais_off_events( gfw_client: gfw.Client, ) -> None: - """Test getting vessel insights related to AIS off events (gaps). + """Test getting vessel insights related to AIS off/disabling events (gaps). This test verifies that the `get_vessel_insights` method correctly retrieves - insights for a specific vessel related to AIS off events (gaps) within a + insights for a specific vessel related to AIS off/disabling events (gaps) within a given date range. It checks the structure and content of the returned data, ensuring it's a valid `VesselInsightResult` and that the data can be converted to a pandas DataFrame. From 488d76c0bba98840887df211a5c7c53a416c6c66 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 10 Mar 2026 20:56:26 +0300 Subject: [PATCH 5/7] docs(vessels): clarify POTENTIAL_RELATED_SELF_REPORTED_INFO include behavior This: - expand `VesselInclude.POTENTIAL_RELATED_SELF_REPORTED_INFO` docstring - add official Vessel Viewer reference link for context and usage understanding - align `VesselResource` parameter documentation with updated include description --- .../resources/vessels/base/models/request.py | 10 +++++++++- src/gfwapiclient/resources/vessels/resources.py | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/gfwapiclient/resources/vessels/base/models/request.py b/src/gfwapiclient/resources/vessels/base/models/request.py index dd96979..9f2a6bb 100644 --- a/src/gfwapiclient/resources/vessels/base/models/request.py +++ b/src/gfwapiclient/resources/vessels/base/models/request.py @@ -57,7 +57,15 @@ class VesselInclude(str, Enum): Attributes: POTENTIAL_RELATED_SELF_REPORTED_INFO (str): - Include potential related self-reported information. + Include potential related self-reported vessel information. + + This include provides related `vessel ids` identified through + matching with vessel registry records. It represents Global Fishing Watch's + best estimate for linking AIS (self-reported) vessel positions to Vessel + Identity information derived from public registries. + + See how the Vessel API is used in the Vessel Viewer + here: https://globalfishingwatch.org/our-apis/assets/2024_Vessel_Viewer_and_APIs_behind_It.pdf """ POTENTIAL_RELATED_SELF_REPORTED_INFO = "POTENTIAL_RELATED_SELF_REPORTED_INFO" diff --git a/src/gfwapiclient/resources/vessels/resources.py b/src/gfwapiclient/resources/vessels/resources.py index 0d4c0aa..b5d61c3 100644 --- a/src/gfwapiclient/resources/vessels/resources.py +++ b/src/gfwapiclient/resources/vessels/resources.py @@ -171,6 +171,14 @@ async def get_vessels_by_ids( Allowed values: `"POTENTIAL_RELATED_SELF_REPORTED_INFO"`. Example: `["POTENTIAL_RELATED_SELF_REPORTED_INFO"]`. + This include provides related `vessel ids` identified through + matching with vessel registry records. It represents Global Fishing Watch's + best estimate for linking AIS (self-reported) vessel positions to Vessel + Identity information derived from public registries. + + See how the Vessel API is used in the Vessel Viewer + here: https://globalfishingwatch.org/our-apis/assets/2024_Vessel_Viewer_and_APIs_behind_It.pdf + match_fields (Optional[Union[List[VesselMatchField], List[str]]], default=None): This query param allows to filter by matchFields levels. Defaults to `None`. Allowed values: `"SEVERAL_FIELDS"`, `"NO_MATCH"`, `"ALL"`. @@ -247,6 +255,14 @@ async def get_vessel_by_id( Allowed values: `"POTENTIAL_RELATED_SELF_REPORTED_INFO"`. Example: `["POTENTIAL_RELATED_SELF_REPORTED_INFO"]`. + This include provides related `vessel ids` identified through + matching with vessel registry records. It represents Global Fishing Watch's + best estimate for linking AIS (self-reported) vessel positions to Vessel + Identity information derived from public registries. + + See how the Vessel API is used in the Vessel Viewer + here: https://globalfishingwatch.org/our-apis/assets/2024_Vessel_Viewer_and_APIs_behind_It.pdf + match_fields (Optional[Union[List[VesselMatchField], List[str]]], default=None): This query param allows to filter by matchFields levels. Defaults to `None`. Allowed values: `"SEVERAL_FIELDS"`, `"NO_MATCH"`, `"ALL"`. From 5a333fd08f0800f857180de571e60855fb5f668b Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 30 Apr 2026 01:26:17 +0300 Subject: [PATCH 6/7] docs(vessels): expand API documentation and add data caveats This: - Update docstrings with links to Vessels API documentation - Update docstrings with vessel identity data caveats --- .../resources/bulk_downloads/resources.py | 2 +- .../resources/vessels/__init__.py | 10 ++++- .../resources/vessels/base/models/request.py | 4 ++ .../resources/vessels/detail/__init__.py | 12 ++++-- .../resources/vessels/detail/endpoints.py | 5 +++ .../resources/vessels/list/__init__.py | 12 ++++-- .../resources/vessels/list/endpoints.py | 5 +++ .../resources/vessels/resources.py | 40 +++++++++++++++++++ .../resources/vessels/search/__init__.py | 11 +++-- .../resources/vessels/search/endpoints.py | 7 +++- 10 files changed, 95 insertions(+), 13 deletions(-) diff --git a/src/gfwapiclient/resources/bulk_downloads/resources.py b/src/gfwapiclient/resources/bulk_downloads/resources.py index cde500c..249a4d9 100644 --- a/src/gfwapiclient/resources/bulk_downloads/resources.py +++ b/src/gfwapiclient/resources/bulk_downloads/resources.py @@ -119,7 +119,7 @@ async def create_bulk_report( long date range etc), generating the bulk report can take several minutes to several hours. - Attributes: + Args: name (str): Human-readable name of the bulk report. Example: `"sar-fixed-infrastructure-data-20240903"`. diff --git a/src/gfwapiclient/resources/vessels/__init__.py b/src/gfwapiclient/resources/vessels/__init__.py index 392b8ed..a84a3bb 100644 --- a/src/gfwapiclient/resources/vessels/__init__.py +++ b/src/gfwapiclient/resources/vessels/__init__.py @@ -6,8 +6,14 @@ details by ID or IDs, and provides a convenient way to access vessel data. For detailed information about the Vessels API, please refer to the official -`Global Fishing Watch Vessels API Documentation -`_. +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#vessels-api + +For more details on the Vessels data caveats, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ from gfwapiclient.resources.vessels.resources import VesselResource diff --git a/src/gfwapiclient/resources/vessels/base/models/request.py b/src/gfwapiclient/resources/vessels/base/models/request.py index 9f2a6bb..3de847f 100644 --- a/src/gfwapiclient/resources/vessels/base/models/request.py +++ b/src/gfwapiclient/resources/vessels/base/models/request.py @@ -66,6 +66,10 @@ class VesselInclude(str, Enum): See how the Vessel API is used in the Vessel Viewer here: https://globalfishingwatch.org/our-apis/assets/2024_Vessel_Viewer_and_APIs_behind_It.pdf + + For more details on the Vessels API data caveats, please refer to the + official Global Fishing Watch API documentation + here: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ POTENTIAL_RELATED_SELF_REPORTED_INFO = "POTENTIAL_RELATED_SELF_REPORTED_INFO" diff --git a/src/gfwapiclient/resources/vessels/detail/__init__.py b/src/gfwapiclient/resources/vessels/detail/__init__.py index 699e798..4857a4e 100644 --- a/src/gfwapiclient/resources/vessels/detail/__init__.py +++ b/src/gfwapiclient/resources/vessels/detail/__init__.py @@ -5,7 +5,13 @@ It defines the `VesselDetailEndPoint` class, which handles the construction of API requests and the parsing of API responses for vessel details. -For detailed information about the Get Vessel by ID API, please refer to the -official `Global Fishing Watch Vessels API Documentation -`_. +For detailed information about the Get Vessel by ID API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-vessel-by-id + +For more details on the Get Vessel by ID data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ diff --git a/src/gfwapiclient/resources/vessels/detail/endpoints.py b/src/gfwapiclient/resources/vessels/detail/endpoints.py index 76e7cab..34e6442 100644 --- a/src/gfwapiclient/resources/vessels/detail/endpoints.py +++ b/src/gfwapiclient/resources/vessels/detail/endpoints.py @@ -23,6 +23,11 @@ class VesselDetailEndPoint( This endpoint retrieves vessel details by ID and other provided request parameters. + + For more details on the Get Vessel by ID API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-vessel-by-id """ def __init__( diff --git a/src/gfwapiclient/resources/vessels/list/__init__.py b/src/gfwapiclient/resources/vessels/list/__init__.py index 3de3c55..3772ff5 100644 --- a/src/gfwapiclient/resources/vessels/list/__init__.py +++ b/src/gfwapiclient/resources/vessels/list/__init__.py @@ -5,7 +5,13 @@ It defines the `VesselListEndPoint` class, which handles the construction of API requests and the parsing of API responses for vessel lists. -For detailed information about the Get Vessels by IDs API, please refer to the -official `Global Fishing Watch Vessels API Documentation -`_. +For detailed information about the Get Vessels by IDs API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-list-of-vessels-filtered-by-ids + +For more details on the Get Vessels by IDs data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ diff --git a/src/gfwapiclient/resources/vessels/list/endpoints.py b/src/gfwapiclient/resources/vessels/list/endpoints.py index f0333a8..4095290 100644 --- a/src/gfwapiclient/resources/vessels/list/endpoints.py +++ b/src/gfwapiclient/resources/vessels/list/endpoints.py @@ -28,6 +28,11 @@ class VesselListEndPoint( This endpoint retrieves a list of vessels based on the provided IDs and other request parameters. + + For more details on the Get Vessels by IDs API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-list-of-vessels-filtered-by-ids """ def __init__( diff --git a/src/gfwapiclient/resources/vessels/resources.py b/src/gfwapiclient/resources/vessels/resources.py index b5d61c3..7d50cd0 100644 --- a/src/gfwapiclient/resources/vessels/resources.py +++ b/src/gfwapiclient/resources/vessels/resources.py @@ -48,6 +48,16 @@ class VesselResource(BaseResource): This resource provides methods to interact with the Vessels API, allowing retrieval of vessel information including search, list by IDs, and retrieval by ID. + + For detailed information about the Vessels API, please refer to the official + Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#vessels-api + + For more details on the Vessels API data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ async def search_vessels( @@ -64,6 +74,16 @@ async def search_vessels( ) -> VesselSearchResult: """Search vessels based on provided parameters. + For detailed information about the Vessels Search API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#search + + For more details on the Vessels Search data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information + Args: since (Optional[str], default=None): The token to send to get more results. @@ -147,6 +167,16 @@ async def get_vessels_by_ids( ) -> VesselListResult: """Get a list of vessels by their IDs. + For detailed information about the Get Vessels by IDs API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-list-of-vessels-filtered-by-ids + + For more details on the Get Vessels by IDs data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information + Args: ids (List[str]): List of vessel IDs to retrieve. @@ -232,6 +262,16 @@ async def get_vessel_by_id( ) -> VesselDetailResult: """Get vessel details by ID. + For detailed information about the Get Vessel by ID API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-vessel-by-id + + For more details on the Get Vessel by ID data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information + Args: id (str): The ID of the vessel to retrieve. diff --git a/src/gfwapiclient/resources/vessels/search/__init__.py b/src/gfwapiclient/resources/vessels/search/__init__.py index 7a6a453..4179298 100644 --- a/src/gfwapiclient/resources/vessels/search/__init__.py +++ b/src/gfwapiclient/resources/vessels/search/__init__.py @@ -9,8 +9,13 @@ filters, and other parameters. This module provides the necessary tools for interacting with the API's endpoint. -For detailed information about the Vessels Search API, please refer to the -official `Global Fishing Watch Vessels API Documentation -`_. +For detailed information about the Vessels Search API endpoint, please refer to +the official Global Fishing Watch API documentation: +See: https://globalfishingwatch.org/our-apis/documentation#search + +For more details on the Vessels Search data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information """ diff --git a/src/gfwapiclient/resources/vessels/search/endpoints.py b/src/gfwapiclient/resources/vessels/search/endpoints.py index a607e0b..4213d35 100644 --- a/src/gfwapiclient/resources/vessels/search/endpoints.py +++ b/src/gfwapiclient/resources/vessels/search/endpoints.py @@ -1,4 +1,4 @@ -"""Global Fishing Watch (GFW) API Python Client - Vessels Search API EndPoint. +"""Global Fishing Watch (GFW) API Python Client - Vessels Search API endpoint. This module defines the endpoint for searching vessels. """ @@ -27,6 +27,11 @@ class VesselSearchEndPoint( """Search vessels API endpoint. This endpoint searches for vessels based on the provided search request parameters. + + For more details on the Vessels Search API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#search """ def __init__( From 2c410e917ea327b8bdad8332cf6490578baa4a72 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 30 Apr 2026 02:17:05 +0300 Subject: [PATCH 7/7] docs(insights): add instructions to enable additional vessel insights This: - Add instructions for enabling `FLAG-CHANGES` and `MOU-LIST` insights - Update caveat links to use "Apparent fishing" terminology --- docs/source/usage-guides/insights-api.md | 8 +- notebooks/usage-guides/insights-api.ipynb | 152 ++++++++++-------- .../resources/insights/resources.py | 8 + 3 files changed, 102 insertions(+), 66 deletions(-) diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 03e4065..3b4f3bf 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -4,7 +4,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access aggregated insights about vessel activities. Currently, the [Insights API](https://globalfishingwatch.org/our-apis/documentation#insights-api) focuses on providing summaries related to specific vessels over a defined time range. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/insights-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits. +> **Note:** See the [Apparent fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Apparent fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits. ## Prerequisites @@ -249,6 +249,8 @@ memory usage: 180.0+ bytes ## Getting Flag Changes Insights (`VESSEL-IDENTITY-FLAG-CHANGES`) +> **Note:** In order to enable this insight for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup)). + ```python flag_changes_insights_result = await gfw_client.insights.get_vessel_insights( includes=["VESSEL-IDENTITY-FLAG-CHANGES"], @@ -285,6 +287,8 @@ memory usage: 180.0+ bytes ## Getting Flag State Presence under Tokyo/Paris MOU black or grey Lists Insights (`VESSEL-IDENTITY-MOU-LIST`) +> **Note:** In order to enable this insight for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup)). + ```python mou_insights_result = await gfw_client.insights.get_vessel_insights( includes=["VESSEL-IDENTITY-MOU-LIST"], @@ -321,6 +325,8 @@ memory usage: 180.0+ bytes ## Getting Multiple Insights for Multiple Vessels +> **Note:** In order to enable `VESSEL-IDENTITY-FLAG-CHANGES` and `VESSEL-IDENTITY-MOU-LIST` insights for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup)). + ```python all_insights_result = await gfw_client.insights.get_vessel_insights( includes=[ diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index ff74a42..be1aeaf 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -36,7 +36,7 @@ "id": "d1d62e3b-fc42-422a-bb7d-2ccc927ba494", "metadata": {}, "source": [ - "**Note:** See the [Fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits." + "**Note:** See the [Apparent fishing detected in no-take MPAs](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-detected-in-no-take-mpas), [Apparent fishing event detected outside known authorized areas](https://globalfishingwatch.org/our-apis/documentation#insights-api-fishing-event-detected-outside-known-authorized-areas), [Coverage](https://globalfishingwatch.org/our-apis/documentation#insights-api-coverage), [AIS off event (aka GAP)](https://globalfishingwatch.org/our-apis/documentation#insights-api-ais-off-event-aka-gap), and [RFMO IUU vessel list](https://globalfishingwatch.org/our-apis/documentation#insights-api-rfmo-iuu-vessel-list) Data Caveats — it is critical to avoid misinterpreting the insights. You can find the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), and [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction) for details on GFW data, API licenses, and rate limits." ] }, { @@ -120,8 +120,6 @@ "source": [ "import os\n", "\n", - "import pandas as pd\n", - "\n", "import gfwapiclient as gfw" ] }, @@ -392,15 +390,15 @@ "outputs": [], "source": [ "fishing_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"FISHING\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", - " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", - " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", - " ],\n", - " )" + " includes=[\"FISHING\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + ")" ] }, { @@ -528,15 +526,15 @@ "outputs": [], "source": [ "gap_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"GAP\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", - " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", - " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", - " ],\n", - " )" + " includes=[\"GAP\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + ")" ] }, { @@ -667,13 +665,13 @@ "outputs": [], "source": [ "coverage_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"COVERAGE\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", - " ],\n", - " )" + " includes=[\"COVERAGE\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " ],\n", + ")" ] }, { @@ -804,13 +802,13 @@ "outputs": [], "source": [ "iuu_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"VESSEL-IDENTITY-IUU-VESSEL-LIST\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", - " ],\n", - " )" + " includes=[\"VESSEL-IDENTITY-IUU-VESSEL-LIST\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + ")" ] }, { @@ -930,6 +928,14 @@ "## Getting Flag Changes Insights (`VESSEL-IDENTITY-FLAG-CHANGES`)" ] }, + { + "cell_type": "markdown", + "id": "1f3e5772-993e-4a96-a179-fa2d28430be4", + "metadata": {}, + "source": [ + "**Note:** In order to enable this insight for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup))." + ] + }, { "cell_type": "code", "execution_count": 27, @@ -938,13 +944,13 @@ "outputs": [], "source": [ "flag_changes_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"VESSEL-IDENTITY-FLAG-CHANGES\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", - " ],\n", - " )" + " includes=[\"VESSEL-IDENTITY-FLAG-CHANGES\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + ")" ] }, { @@ -1064,6 +1070,14 @@ "## Getting Flag State Presence under Tokyo/Paris MOU black or grey Lists Insights (`VESSEL-IDENTITY-MOU-LIST`)" ] }, + { + "cell_type": "markdown", + "id": "a36813b7-b2c5-4ea8-a55a-c1a923f9237d", + "metadata": {}, + "source": [ + "**Note:** In order to enable this insight for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup))." + ] + }, { "cell_type": "code", "execution_count": 31, @@ -1072,13 +1086,13 @@ "outputs": [], "source": [ "mou_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\"VESSEL-IDENTITY-MOU-LIST\"],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", - " ],\n", - " )" + " includes=[\"VESSEL-IDENTITY-MOU-LIST\"],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " ],\n", + ")" ] }, { @@ -1198,6 +1212,14 @@ "## Getting Multiple Insights for Multiple Vessels" ] }, + { + "cell_type": "markdown", + "id": "2899f3be-a582-47c2-9fa2-98bd2002c7fc", + "metadata": {}, + "source": [ + "**Note:** In order to enable `VESSEL-IDENTITY-FLAG-CHANGES` and `VESSEL-IDENTITY-MOU-LIST` insights for your API access token (`GFW_API_ACCESS_TOKEN`), please contact apis@globalfishingwatch.org. In your message, please specify the email address used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup))." + ] + }, { "cell_type": "code", "execution_count": 35, @@ -1206,22 +1228,22 @@ "outputs": [], "source": [ "all_insights_result = await gfw_client.insights.get_vessel_insights(\n", - " includes=[\n", - " \"FISHING\",\n", - " \"GAP\",\n", - " \"VESSEL-IDENTITY-IUU-VESSEL-LIST\",\n", - " \"COVERAGE\",\n", - " \"VESSEL-IDENTITY-FLAG-CHANGES\",\n", - " \"VESSEL-IDENTITY-MOU-LIST\",\n", - " ],\n", - " start_date=\"2020-01-01\",\n", - " end_date=\"2025-03-03\",\n", - " vessels=[\n", - " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", - " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", - " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", - " ],\n", - " )" + " includes=[\n", + " \"FISHING\",\n", + " \"GAP\",\n", + " \"VESSEL-IDENTITY-IUU-VESSEL-LIST\",\n", + " \"COVERAGE\",\n", + " \"VESSEL-IDENTITY-FLAG-CHANGES\",\n", + " \"VESSEL-IDENTITY-MOU-LIST\",\n", + " ],\n", + " start_date=\"2020-01-01\",\n", + " end_date=\"2025-03-03\",\n", + " vessels=[\n", + " \"785101812-2127-e5d2-e8bf-7152c5259f5f\",\n", + " \"2339c52c3-3a84-1603-f968-d8890f23e1ed\",\n", + " \"2d26aa452-2d4f-4cae-2ec4-377f85e88dcb\",\n", + " ],\n", + ")" ] }, { diff --git a/src/gfwapiclient/resources/insights/resources.py b/src/gfwapiclient/resources/insights/resources.py index e77cc9b..6193afa 100644 --- a/src/gfwapiclient/resources/insights/resources.py +++ b/src/gfwapiclient/resources/insights/resources.py @@ -94,6 +94,14 @@ async def get_vessel_insights( `start_date` must be on or after `January 1, 2020` + **Note:** + + In order to enable `"VESSEL-IDENTITY-FLAG-CHANGES"` and `"VESSEL-IDENTITY-MOU-LIST"` + insights for your API access token (`GFW_API_ACCESS_TOKEN`), please contact + apis@globalfishingwatch.org. In your message, please specify the email address + used to generate the [API tokens](https://globalfishingwatch.org/our-apis/tokens) + (i.e., the email address associated with your [Global Fishing Watch account](https://globalfishingwatch.org/our-apis/tokens/signup)). + Args: includes (Union[List[VesselInsightInclude], List[str]], default=["FISHING"]): List of insight types to include in the response.