From 03cb982cef407c79bf49fbada08e4647227e4060 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 28 Oct 2025 19:53:04 +0300 Subject: [PATCH 01/22] chore(deps): update to latest versions --- pyproject.toml | 58 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a0ca847..f33e3b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,44 +62,44 @@ classifiers = [ ] dependencies = [ "httpx~=0.28", # Making HTTP requests - "typing-extensions~=4.13", # Backported Type Hints for Python 3.8+ - "pydantic~=2.10", # Data validation and serialization - "pydantic-settings~=2.8", # Type-hinted configurations or settings - "geojson-pydantic~=1.2", # Data models for the GeoJSON specification - "mapbox-vector-tile~=2.1", # Encoding and decoding Mapbox Vector Tiles (MVT) + "typing-extensions~=4.15", # Backported Type Hints for Python 3.8+ + "pydantic~=2.12", # Data validation and serialization + "pydantic-settings~=2.11", # Type-hinted configurations or settings + "geojson-pydantic~=2.1", # Data models for the GeoJSON specification + "mapbox-vector-tile~=2.2", # Encoding and decoding Mapbox Vector Tiles (MVT) "mercantile~=1.2", # Web mercator XYZ tile utilities - "pandas~=2.2", # Data analysis and manipulation - "geopandas~=1.0", # Geospatial data analysis and manipulation + "pandas~=2.3", # Data analysis and manipulation + "geopandas~=1.1", # Geospatial data analysis and manipulation ] [project.optional-dependencies] # Linting and code quality tools lint = [ - "black>=25.1.0", # Code formatting tool - "isort>=6.0.1", # Python imports sorting tool - "mypy>=1.15.0", # Static type checker + "black>=25.9.0", # Code formatting tool + "isort>=7.0.0", # Python imports sorting tool + "mypy>=1.18.2", # Static type checker "pydocstyle>=6.3.0", # Python docstring style checker - "ruff>=0.11.2", # Linter and code analysis tool + "ruff>=0.14.2", # Linter and code analysis tool "codespell[toml]>=2.4.1", # Spell checker for code ] # Testing tools test = [ - "pytest>=8.3.5", # Core testing framework - "pytest-asyncio>=0.26.0", # Asyncio plugin for pytest - "pytest-cov>=6.0.0", # Coverage plugin for pytest - "pytest-mock>=3.14.0", # Mocking plugin for pytest - "pytest-xdist>=3.6.1", # Parallel test execution for pytest - "pytest-timeout>=2.3.1", # Timeout support for pytest - "coverage[toml]>=7.7.1", # Code coverage reporting + "pytest>=8.4.2", # Core testing framework + "pytest-asyncio>=1.2.0", # Asyncio plugin for pytest + "pytest-cov>=7.0.0", # Coverage plugin for pytest + "pytest-mock>=3.15.1", # Mocking plugin for pytest + "pytest-xdist>=3.8.0", # Parallel test execution for pytest + "pytest-timeout>=2.4.0", # Timeout support for pytest + "coverage[toml]>=7.11.0", # Code coverage reporting "respx>=0.22.0", # Utility for mocking httpx ] # Development workflow and tools dev = [ - "commitizen>=4.4.1", # Standardized commit messages and versioning - "pre-commit>=4.2.0", # Framework for managing pre-commit hooks - "pip-audit>=2.8.0", # Audit for finding vulnerabilities in dependencies + "commitizen>=4.9.1", # Standardized commit messages and versioning + "pre-commit>=4.3.0", # Framework for managing pre-commit hooks + "pip-audit>=2.9.0", # Audit for finding vulnerabilities in dependencies ] # Build tools @@ -108,27 +108,27 @@ build = [ "check-wheel-contents>=0.6.3", # Check wheels have the right contents "pydistcheck>=0.10.0", # Inspect Python package distributions for common problems "pyroma>=5.0", # Test project's packaging friendliness - "setuptools>=78.1.0", # Python packaging library - "twine>=6.1.0", # For uploading Python packages to PyPI + "setuptools>=80.9.0", # Python packaging library + "twine>=6.2.0", # For uploading Python packages to PyPI ] # Documentation tools docs = [ "sphinx>=8.2.3", # Tool for generating documentation - "furo>=2024.8.6", # Sphinx theme for beautiful documentation + "furo>=2025.9.25", # Sphinx theme for beautiful documentation "myst-parser>=4.0.1", # Writing documentation with Markdown in Sphinx - "myst-nb>=1.2.0", # Writing documentation with Jupyter Notebook in Sphinx + "myst-nb>=1.3.0", # Writing documentation with Jupyter Notebook in Sphinx "sphinx-copybutton>=0.5.2", # Add a "copy" button to code blocks in Sphinx - "sphinx-autobuild>=2024.10.3", # Build, watch and serve documentation with live reload in the browser + "sphinx-autobuild>=2025.8.25", # Build, watch and serve documentation with live reload in the browser "sphinx-inline-tabs>=2023.4.21", # Add inline tabbed content to documentation "sphinx-autodoc2>=0.5.0", # Generates API documentation for Python packages ] # Jupyter notebook and interactive tools notebooks = [ - "ipykernel>=6.29.5", # Jupyter kernel for Python - "ipython>=9.0.2", # Enhanced interactive Python shell - "jupyterlab>=4.3.6", # Jupyter's next-generation web-based interface + "ipykernel>=7.1.0", # Jupyter kernel for Python + "ipython>=9.6.0", # Enhanced interactive Python shell + "jupyterlab>=4.4.10", # Jupyter's next-generation web-based interface "watermark>=2.5.0", # Add timestamps and version info to Jupyter notebook ] From 3861d54d5e64286dfba09f572950905cb718583f Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Mon, 10 Nov 2025 21:54:58 +0300 Subject: [PATCH 02/22] docs(fourwings): update wording and links for clarity in reports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This: - clarify descriptions for reports - add explicit "learn more" links alongside data caveats in documentation and notebooks - include note highlighting differences between AIS vessel presence and SAR vessel detection - update Python version in notebooks metadata (3.11.11 → 3.11.14) --- docs/source/usage-guides/4wings-api.md | 10 ++++++---- notebooks/getting-started.ipynb | 2 +- notebooks/usage-guides/4wings-api.ipynb | 16 ++++++++++++---- notebooks/usage-guides/datasets-api.ipynb | 2 +- notebooks/usage-guides/events-api.ipynb | 2 +- notebooks/usage-guides/insights-api.ipynb | 2 +- .../usage-guides/references-data-api.ipynb | 2 +- notebooks/usage-guides/vessels-api.ipynb | 2 +- .../resources/fourwings/resources.py | 19 ++++++++++++++++--- .../resources/vessels/list/models/request.py | 2 -- 10 files changed, 40 insertions(+), 19 deletions(-) diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 657acab..068bcee 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -34,7 +34,7 @@ The `gfw_client.fourwings` object provides methods to generate reports, retrieve ## Creating a Fishing Effort Report (`create_fishing_effort_report`) -Generates **AIS (Automatic Identification System) apparent fishing effort** reports to visualize fishing activity. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort). +Generates **AIS (Automatic Identification System) apparent fishing effort** reports to visualize fishing activity. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort). ```python fishing_effort_report_result = await gfw_client.fourwings.create_fishing_effort_report( @@ -116,7 +116,7 @@ memory usage: 6.4+ MB ## Creating an AIS Presence Report (`create_ais_presence_report`) -Generates **AIS (Automatic Identification System) vessel presence** reports to visualize movement patterns of any vessel type. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats). +Generates **AIS (Automatic Identification System) vessel presence** reports to visualize movement patterns of any vessel type. Please [learn more about AIS vessel presence here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats). > **Disclaimer:** AIS vessel presence is one of the largest datasets available. To prevent timeouts and ensure optimal performance, keep requests manageable: prefer simple, small regions and shorter time ranges (e.g., a few days). @@ -197,9 +197,11 @@ dtypes: float64(3), int64(1), object(16) memory usage: 22.0+ MB ``` -## Creating a SAR Presence Report (`create_sar_presence_report`) +## Creating a SAR Vessel Detections Report (`create_sar_presence_report`) -Generates **SAR (Synthetic-Aperture Radar) vessel detections** reports to identify vessels detected via radar, including non-broadcasting (possible `"dark"`) vessels. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats). +Generates **SAR (Synthetic-Aperture Radar) vessel detections** reports to identify vessels detected via radar, including non-broadcasting (possible `"dark"`) vessels. Please [learn more about SAR vessel detections here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats). + +> **Important:** **AIS vessel presence** shows where vessels **reported their positions** via the **Automatic Identification System (AIS)**. **SAR vessel detection** shows where **Synthetic Aperture Radar (SAR) satellites detected** vessels on the ocean surface, even if they **weren't transmitting AIS**. ```python sar_presence_report_result = await gfw_client.fourwings.create_sar_presence_report( diff --git a/notebooks/getting-started.ipynb b/notebooks/getting-started.ipynb index 02ed293..1705966 100644 --- a/notebooks/getting-started.ipynb +++ b/notebooks/getting-started.ipynb @@ -503,7 +503,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index f625004..db1850b 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -160,7 +160,7 @@ "id": "d5f9e8ad-f137-446b-a38f-9caa4f233925", "metadata": {}, "source": [ - "Generates **AIS (Automatic Identification System) apparent fishing effort** reports to visualize fishing activity. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + "Generates **AIS (Automatic Identification System) apparent fishing effort** reports to visualize fishing activity. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." ] }, { @@ -478,7 +478,7 @@ "id": "c0a1a577-fd6c-447d-b661-74f77aabb317", "metadata": {}, "source": [ - "Generates **AIS (Automatic Identification System) vessel presence** reports to visualize movement patterns of any vessel type. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats)." + "Generates **AIS (Automatic Identification System) vessel presence** reports to visualize movement patterns of any vessel type. Please [learn more about AIS vessel presence here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats)." ] }, { @@ -803,7 +803,15 @@ "id": "be214b01-e4f9-45b0-8d54-c993d0d04d05", "metadata": {}, "source": [ - "Generates **SAR (Synthetic-Aperture Radar) vessel detections** reports to identify vessels detected via radar, including non-broadcasting (possible `\"dark\"`) vessels. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats)." + "Generates **SAR (Synthetic-Aperture Radar) vessel detections** reports to identify vessels detected via radar, including non-broadcasting (possible `\"dark\"`) vessels. Please [learn more about SAR vessel detections here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats)." + ] + }, + { + "cell_type": "markdown", + "id": "b4cb7d5a-65cb-42cd-a254-759399b7bb05", + "metadata": {}, + "source": [ + "**Important:** **AIS vessel presence** shows where vessels **reported their positions** via the **Automatic Identification System (AIS)**. **SAR vessel detection** shows where **Synthetic Aperture Radar (SAR) satellites detected** vessels on the ocean surface, even if they **weren't transmitting AIS**." ] }, { @@ -1474,7 +1482,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/datasets-api.ipynb b/notebooks/usage-guides/datasets-api.ipynb index 3673b3a..73d0fa9 100644 --- a/notebooks/usage-guides/datasets-api.ipynb +++ b/notebooks/usage-guides/datasets-api.ipynb @@ -665,7 +665,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/events-api.ipynb b/notebooks/usage-guides/events-api.ipynb index db372f3..f8ade5a 100644 --- a/notebooks/usage-guides/events-api.ipynb +++ b/notebooks/usage-guides/events-api.ipynb @@ -876,7 +876,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 166b42b..84a4629 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -351,7 +351,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/references-data-api.ipynb b/notebooks/usage-guides/references-data-api.ipynb index 3827efd..1827ea3 100644 --- a/notebooks/usage-guides/references-data-api.ipynb +++ b/notebooks/usage-guides/references-data-api.ipynb @@ -790,7 +790,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index ec7425e..d1302cd 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -782,7 +782,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.14" } }, "nbformat": 4, diff --git a/src/gfwapiclient/resources/fourwings/resources.py b/src/gfwapiclient/resources/fourwings/resources.py index 565c32c..ceb097c 100644 --- a/src/gfwapiclient/resources/fourwings/resources.py +++ b/src/gfwapiclient/resources/fourwings/resources.py @@ -87,9 +87,11 @@ async def create_fishing_effort_report( - Fleet management - Supply chain visibility - For more details on the 4Wings AIS apparent fishing effort data caveats, + For more details on the 4Wings AIS apparent fishing effort and it data caveats, please refer to the official Global Fishing Watch API documentation: + See: https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort + See: https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort Args: @@ -204,9 +206,11 @@ async def create_ais_presence_report( - Fleet management - Supply chain visibility - For more details on the 4Wings AIS vessel presence data caveats, + For more details on the 4Wings AIS vessel presence and its data caveats, please refer to the official Global Fishing Watch API documentation: + See: https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence + See: https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats **Disclaimer:** @@ -318,11 +322,20 @@ async def create_sar_presence_report( - Dark vessel detection - Remote area surveillance - For more details on the 4Wings SAR vessel detections data caveats, + For more details on the 4Wings SAR vessel detections and its data caveats, please refer to the official Global Fishing Watch API documentation: + See: https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections + See: https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats + **Important:** + + **AIS vessel presence** shows where vessels **reported their positions** via + the **Automatic Identification System (AIS)**. **SAR vessel detection** shows + where **Synthetic Aperture Radar (SAR) satellites detected** vessels on the + ocean surface, even if they **weren't transmitting AIS**. + Args: spatial_resolution (Optional[Union[FourWingsReportSpatialResolution, str]], default="HIGH"): Spatial resolution of the report. Defaults to `"HIGH"`. diff --git a/src/gfwapiclient/resources/vessels/list/models/request.py b/src/gfwapiclient/resources/vessels/list/models/request.py index 4f7f181..d18af9c 100644 --- a/src/gfwapiclient/resources/vessels/list/models/request.py +++ b/src/gfwapiclient/resources/vessels/list/models/request.py @@ -22,8 +22,6 @@ class VesselListParams(VesselBaseDetailParams): - """Request query parameters for get list of vessels filtered by ids API endpoint.""" - """Request query parameters for the get list of vessels filtered by IDs API endpoint. Attributes: From caa040d21e3fba661d069804628dc84482944b01 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 12 Nov 2025 07:40:42 +0300 Subject: [PATCH 03/22] style(fourwings): correct typo in resource docstrings --- src/gfwapiclient/resources/fourwings/resources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gfwapiclient/resources/fourwings/resources.py b/src/gfwapiclient/resources/fourwings/resources.py index ceb097c..6551647 100644 --- a/src/gfwapiclient/resources/fourwings/resources.py +++ b/src/gfwapiclient/resources/fourwings/resources.py @@ -87,7 +87,7 @@ async def create_fishing_effort_report( - Fleet management - Supply chain visibility - For more details on the 4Wings AIS apparent fishing effort and it data caveats, + For more details on the 4Wings AIS apparent fishing effort and its data caveats, please refer to the official Global Fishing Watch API documentation: See: https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort From a6844936f8eaab80b02ab6fbf281725d5d9272ac Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 25 Nov 2025 14:59:15 +0300 Subject: [PATCH 04/22] feat(bulk-downloads): add base request and response models for Bulk Download API This: - add `BulkReportItem`, `BulkReportGeography`, and `BulkReportStatus` Pydantic models for API response data - add `BulkReportDataset`, and `BulkReportFileType` Pydantic models for request parameters - add `BulkReportFormat`, `BulkReportGeometry`, and `BulkReportRegion` Pydantic models for request parameters - add unit tests and fixtures validating model serialization and data handling --- .../resources/bulk_downloads/__init__.py | 21 +++ .../resources/bulk_downloads/base/__init__.py | 15 ++ .../bulk_downloads/base/models/__init__.py | 16 ++ .../bulk_downloads/base/models/request.py | 133 ++++++++++++++ .../bulk_downloads/base/models/response.py | 171 ++++++++++++++++++ .../bulk_downloads/bulk_report_item.json | 20 ++ tests/resources/bulk_downloads/__init__.py | 1 + .../resources/bulk_downloads/base/__init__.py | 1 + .../bulk_downloads/base/models/__init__.py | 1 + .../base/models/test_request_models.py | 138 ++++++++++++++ .../base/models/test_response_models.py | 117 ++++++++++++ tests/resources/bulk_downloads/conftest.py | 40 ++++ 12 files changed, 674 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/base/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/base/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/base/models/request.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/base/models/response.py create mode 100644 tests/fixtures/bulk_downloads/bulk_report_item.json create mode 100644 tests/resources/bulk_downloads/__init__.py create mode 100644 tests/resources/bulk_downloads/base/__init__.py create mode 100644 tests/resources/bulk_downloads/base/models/__init__.py create mode 100644 tests/resources/bulk_downloads/base/models/test_request_models.py create mode 100644 tests/resources/bulk_downloads/base/models/test_response_models.py create mode 100644 tests/resources/bulk_downloads/conftest.py diff --git a/src/gfwapiclient/resources/bulk_downloads/__init__.py b/src/gfwapiclient/resources/bulk_downloads/__init__.py new file mode 100644 index 0000000..e47cf7b --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/__init__.py @@ -0,0 +1,21 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Resource. + +This module provides the `BulkDownloadResource` class, which allows to interact with +the Bulk Download API to: + +- Create bulk reports based on specific filters and spatial parameters. +- Monitor previously created bulk report generation status. +- Get signed URL to download previously created bulk report data, metadata and +region geometry (in GeoJSON format) files. +- Query previously created bulk report data records in JSON format. + +For detailed information about the Bulk Download API, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#bulk-download-api + +For more details on the Bulk Download data caveats, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/base/__init__.py b/src/gfwapiclient/resources/bulk_downloads/base/__init__.py new file mode 100644 index 0000000..2c21d8b --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/base/__init__.py @@ -0,0 +1,15 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Base. + +This module provides base classes used across the Bulk Download API endpoints to ensure +consistent behavior. + +For detailed information about the Bulk Download API, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#bulk-download-api + +For more details on the Bulk Download data caveats, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/base/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/base/models/__init__.py new file mode 100644 index 0000000..9dc6f22 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/base/models/__init__.py @@ -0,0 +1,16 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Base Models. + +This module defines base Pydantic models used across the Bulk Download API endpoints. +These models provide common structures for request parameters, request bodies and +response data, facilitating consistent data handling, type safety and validation. + +For detailed information about the Bulk Download API, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#bulk-download-api + +For more details on the Bulk Download data caveats, please refer to the official +Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/base/models/request.py b/src/gfwapiclient/resources/bulk_downloads/base/models/request.py new file mode 100644 index 0000000..233b0fd --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/base/models/request.py @@ -0,0 +1,133 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Base Request Models. + +This module defines base Pydantic request models, parameters and enumerations for +various Bulk Download API endpoints. +""" + +from enum import Enum +from typing import Any, Optional, Union + +from pydantic import Field + +from gfwapiclient.base.models import BaseModel + + +__all__ = [ + "BulkReportDataset", + "BulkReportFileType", + "BulkReportFormat", + "BulkReportGeometry", + "BulkReportRegion", +] + + +class BulkReportDataset(str, Enum): + """Bulk report dataset. + + For more details on the Bulk Download API supported datasets, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-body-only-for-post-request + + See: https://globalfishingwatch.org/our-apis/documentation#supported-bulk-download-api-datasets + + See: https://globalfishingwatch.org/our-apis/documentation#api-dataset + + Attributes: + FIXED_INFRASTRUCTURE_DATA_LATEST (str): + Latest public fixed infrastructure data dataset. + See data caveats: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + """ + + FIXED_INFRASTRUCTURE_DATA_LATEST = "public-fixed-infrastructure-data:latest" + + +class BulkReportFormat(str, Enum): + """Bulk report result format. + + For more details on the Bulk Download API supported result formats, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-body-only-for-post-request + + Attributes: + CSV (str): + CSV (Comma Separated Values) result format. + + JSON (str): + JSON (JavaScript Object Notation) result format. + """ + + CSV = "CSV" + JSON = "JSON" + + +class BulkReportGeometry(BaseModel): + """Bulk report GeoJSON-like geometry input. + + Represents a GeoJSON-compatible custom area of interest used for filtering + bulk report data. + + For more details on the Bulk Download API supported geojson/geometries, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-body-only-for-post-request + + Attributes: + type (str): + The type of geometry (e.g., "Polygon"). + + coordinates (Any): + Geometry coordinates as a list or nested lists. + """ + + type: str = Field(...) + coordinates: Any = Field(...) + + +class BulkReportRegion(BaseModel): + """Bulk report region of interest. + + Represents a predefined area of interest used for filtering bulk report data. + + For more details on the Bulk Download API supported regions, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-body-only-for-post-request + + See: https://globalfishingwatch.org/our-apis/documentation#regions + + Attributes: + dataset (Optional[str]): + Dataset containing the region of interest (e.g. `"public-eez-areas"`). + + id (Optional[Union[str, int]]): + Region of interest identifier (ID) (e.g. `8466`). + """ + + dataset: Optional[str] = Field(None, alias="dataset") + id: Optional[Union[str, int]] = Field(None, alias="id") + + +class BulkReportFileType(str, Enum): + """Bulk report file type. + + For more details on the Bulk Download API supported file types, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-parameters-for-get-requests + + Attributes: + DATA (str): + Bulk report dataset file. + + README (str): + Bulk report metadata documentation file. + + GEOM (str): + Bulk report region geometry (in GeoJSON format) file. + """ + + DATA = "DATA" + README = "README" + GEOM = "GEOM" diff --git a/src/gfwapiclient/resources/bulk_downloads/base/models/response.py b/src/gfwapiclient/resources/bulk_downloads/base/models/response.py new file mode 100644 index 0000000..03fc8a3 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/base/models/response.py @@ -0,0 +1,171 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Base Response Models. + +This module defines base Pydantic response models, parameters and enumerations for +various Bulk Download API endpoints. +""" + +import datetime + +from enum import Enum +from typing import Any, List, Optional, Union + +from pydantic import Field, field_validator + +from gfwapiclient.base.models import BaseModel +from gfwapiclient.http.models import ResultItem +from gfwapiclient.resources.bulk_downloads.base.models.request import BulkReportFormat + + +__all__ = ["BulkReportItem"] + + +class BulkReportStatus(str, Enum): + """Bulk report current generation process status. + + For more details on the Bulk Download API supported report statuses, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + + Attributes: + PENDING (str): + Bulk report has been created but processing has not yet started. + + PROCESSING (str): + Bulk report generation is currently in progress. + + DONE (str): + Bulk report has been successfully generated and is ready for use. + + FAILED (str): + Bulk report generation encountered an error or was unable to complete. + """ + + PENDING = "pending" + PROCESSING = "processing" + DONE = "done" + FAILED = "failed" + + +class BulkReportGeography(BaseModel): + """Bulk report geography. + + For more details on the Bulk Download API supported geographies, please refer to + the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + + Attributes: + type (Optional[str]): + Type of geometry input (e.g. `"dataset"` or `"custom"`). + + dataset (Optional[str]): + Dataset associated with the bulk report region of interest, if using + reference geometry (e.g. `"public-eez-areas"`). + + id (Optional[Union[str, int]]): + Identifier (ID) of the geometry used to define the bulk report region of + interest (e.g. `8466`). + """ + + type: Optional[str] = Field(None, alias="type") + dataset: Optional[str] = Field(None, alias="dataset") + id: Optional[Union[str, int]] = Field(None, alias="id") + + +class BulkReportItem(ResultItem): + """Bulk report entry. + + Represents a single entry in the bulk report result. Each entry captures metadata + and status of the previously created bulk report. + + For more details on the Bulk Download API supported response bodies, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + + Attributes: + id (Optional[str]): + Unique identifier (ID) of the bulk report (e.g., + `"adbb9b62-5c08-4142-82e0-b2b575f3e058"`). + + name (Optional[str]): + Human-readable name of the bulk report (e.g., + `"sar-fixed-infrastructure-data-202409"`). + + file_path (Optional[str]): + Name of the output file generated by the bulk report (e.g., + `"sar_fixed_infrastructure_data_202409.json"` or + `"sar_fixed_infrastructure_data_202409.csv"`). + + format (Optional[BulkReportFormat]): + Format of the generated bulk report file (e.g., `"JSON"` or `"CSV"`). + + filters (Optional[List[str]]): + List of applied filters used when generating the bulk report + (e.g., `["label = 'oil'"]`). + + geom (Optional[BulkReportGeography]): + Geography used when generating the bulk report (e.g., + `{"type": "dataset", "dataset": "public-eez-areas", "id": 8466}`). + + status (Optional[BulkReportStatus]): + Current status of the bulk report generation process (e.g., `"done"`). + + owner_id (Optional[Union[str, int]]): + Identifier (ID) of the entity that created the bulk report (e.g., `509`). + + owner_type (Optional[str]): + Type of entity that created the bulk report (e.g., `"user-application"`). + + created_at (Optional[datetime.datetime]): + Timestamp when the bulk report was created in ISO-8601 format + (e.g., `"2025-06-24T14:21:27.517Z"`). + + updated_at (Optional[datetime.datetime]): + Timestamp when the bulk report was last updated in ISO-8601 format + (e.g., `"2025-06-24T14:21:27.517Z"`). + + file_size (Optional[float]): + Size of the bulk report output file in bytes (e.g., `1207`). + """ + + id: Optional[str] = Field(None, alias="id") + name: Optional[str] = Field(None, alias="name") + file_path: Optional[str] = Field(None, alias="filepath") + format: Optional[BulkReportFormat] = Field(None, alias="format") + filters: Optional[List[str]] = Field(None, alias="filters") + geom: Optional[BulkReportGeography] = Field(None, alias="geom") + status: Optional[BulkReportStatus] = Field(None, alias="status") + owner_id: Optional[Union[str, int]] = Field(None, alias="ownerId") + owner_type: Optional[str] = Field(None, alias="ownerType") + created_at: Optional[datetime.datetime] = Field(None, alias="createdAt") + updated_at: Optional[datetime.datetime] = Field(None, alias="updatedAt") + file_size: Optional[float] = Field(None, alias="fileSize") + + @field_validator( + "created_at", + "updated_at", + mode="before", + ) + @classmethod + def empty_datetime_str_to_none(cls, value: Any) -> Optional[Any]: + """Convert any empty datetime string to `None`. + + Args: + value (Any): + The value to validate. + + Returns: + Optional[datetime.datetime]: + The validated datetime object or `None` if input is empty. + """ + if isinstance(value, str) and value.strip() == "": + return None + return value diff --git a/tests/fixtures/bulk_downloads/bulk_report_item.json b/tests/fixtures/bulk_downloads/bulk_report_item.json new file mode 100644 index 0000000..5083448 --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_item.json @@ -0,0 +1,20 @@ +{ + "id": "adbb9b62-5c08-4142-82e0-b2b575f3e058", + "name": "sar-fixed-infrastructure-data-202409", + "filepath": "sar_fixed_infrastructure_data_202409.json", + "format": "JSON", + "filters": [ + "label = 'oil'" + ], + "geom": { + "type": "dataset", + "dataset": "public-eez-areas", + "id": 8466 + }, + "status": "done", + "ownerId": 509, + "ownerType": "user-application", + "createdAt": "2025-06-24T14:21:27.517Z", + "updatedAt": "2025-06-24T14:21:27.517Z", + "fileSize": 1207.0 +} diff --git a/tests/resources/bulk_downloads/__init__.py b/tests/resources/bulk_downloads/__init__.py new file mode 100644 index 0000000..6487cc7 --- /dev/null +++ b/tests/resources/bulk_downloads/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads`.""" diff --git a/tests/resources/bulk_downloads/base/__init__.py b/tests/resources/bulk_downloads/base/__init__.py new file mode 100644 index 0000000..a840ac2 --- /dev/null +++ b/tests/resources/bulk_downloads/base/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.base`.""" diff --git a/tests/resources/bulk_downloads/base/models/__init__.py b/tests/resources/bulk_downloads/base/models/__init__.py new file mode 100644 index 0000000..014bc9a --- /dev/null +++ b/tests/resources/bulk_downloads/base/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.base.models`.""" diff --git a/tests/resources/bulk_downloads/base/models/test_request_models.py b/tests/resources/bulk_downloads/base/models/test_request_models.py new file mode 100644 index 0000000..150fdc4 --- /dev/null +++ b/tests/resources/bulk_downloads/base/models/test_request_models.py @@ -0,0 +1,138 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.base.models.request`.""" + +from typing import Any, Dict + +import pytest + +from pydantic import ValidationError + +from gfwapiclient.resources.bulk_downloads.base.models.request import ( + BulkReportDataset, + BulkReportFileType, + BulkReportFormat, + BulkReportGeometry, + BulkReportRegion, +) + +from ...conftest import geometry, region_dataset, region_id + + +@pytest.mark.parametrize( + "dataset,value", + [ + ( + BulkReportDataset.FIXED_INFRASTRUCTURE_DATA_LATEST, + "public-fixed-infrastructure-data:latest", + ), + ], +) +def test_bulk_report_dataset_enum_correct_values( + dataset: BulkReportDataset, value: str +) -> None: + """Test that correct `BulkReportDataset` enum values can be instantiated.""" + dataset_instance = BulkReportDataset(value) + assert dataset_instance == dataset + + +@pytest.mark.parametrize( + "invalid_value", + ["INVALID_DATASET", ""], +) +def test_bulk_report_dataset_enum_invalid_value_raises_value_error( + invalid_value: str, +) -> None: + """Test that invalid `BulkReportDataset` enum values raise a `ValueError`.""" + with pytest.raises(ValueError): + BulkReportDataset(invalid_value) + + +@pytest.mark.parametrize( + "format,value", + [ + (BulkReportFormat.CSV, "CSV"), + (BulkReportFormat.JSON, "JSON"), + ], +) +def test_bulk_report_format_enum_correct_values( + format: BulkReportFormat, value: str +) -> None: + """Test that correct `BulkReportFormat` enum values can be instantiated.""" + format_instance = BulkReportFormat(value) + assert format_instance == format + + +@pytest.mark.parametrize( + "invalid_value", + ["INVALID_FORMAT", ""], +) +def test_bulk_report_format_enum_invalid_value_raises_value_error( + invalid_value: str, +) -> None: + """Test that invalid `BulkReportFormat` enum values raise a `ValueError`.""" + with pytest.raises(ValueError): + BulkReportFormat(invalid_value) + + +@pytest.mark.parametrize( + "file_type,value", + [ + (BulkReportFileType.DATA, "DATA"), + (BulkReportFileType.README, "README"), + (BulkReportFileType.GEOM, "GEOM"), + ], +) +def test_bulk_report_file_type_enum_correct_values( + file_type: BulkReportFileType, value: str +) -> None: + """Test that correct `BulkReportFileType` enum values can be instantiated.""" + file_type_instance = BulkReportFileType(value) + assert file_type_instance == file_type + + +@pytest.mark.parametrize( + "invalid_value", + ["INVALID_FILE_TYPE", ""], +) +def test_bulk_report_file_type_enum_invalid_value_raises_value_error( + invalid_value: str, +) -> None: + """Test that invalid `BulkReportFileType` enum values raise a `ValueError`.""" + with pytest.raises(ValueError): + BulkReportFileType(invalid_value) + + +def test_bulk_report_geometry_serializes_all_fields() -> None: + """Test that `BulkReportGeometry` serializes all required fields correctly.""" + geom: BulkReportGeometry = BulkReportGeometry(**geometry) + assert geom.type == "Polygon" + assert geom.coordinates == geometry.get("coordinates") + + +@pytest.mark.parametrize( + "invalid_input", + [ + {}, # missing required fields + {"type": "Polygon"}, # missing coordinates + {"coordinates": [[[0, 0]]]}, # missing type + ], +) +def test_bulk_report_geometry_invalid_inputs_raise_validation_erro( + invalid_input: Dict[str, Any], +) -> None: + """Test that invalid `BulkReportGeometry` inputs raise a `ValidationError`.""" + with pytest.raises(ValidationError): + BulkReportGeometry(**invalid_input) + + +def test_bulk_report_region_serializes_all_fields() -> None: + """Test that `BulkReportRegion` serializes all required fields correctly.""" + region: BulkReportRegion = BulkReportRegion(dataset=region_dataset, id=region_id) + assert region.dataset == region_dataset + assert region.id == region_id + + +def test_bulk_report_region_optional_fields_default_to_none() -> None: + """Test that `BulkReportRegion` sets missing optional fields to `None`.""" + region: BulkReportRegion = BulkReportRegion() # type: ignore[call-arg] + assert region.dataset is None + assert region.id is None diff --git a/tests/resources/bulk_downloads/base/models/test_response_models.py b/tests/resources/bulk_downloads/base/models/test_response_models.py new file mode 100644 index 0000000..c75bab1 --- /dev/null +++ b/tests/resources/bulk_downloads/base/models/test_response_models.py @@ -0,0 +1,117 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.base.models.response`.""" + +from typing import Any, Dict + +import pytest + +from gfwapiclient.resources.bulk_downloads.base.models.response import ( + BulkReportGeography, + BulkReportItem, + BulkReportStatus, +) + +from ...conftest import region_dataset, region_id + + +@pytest.mark.parametrize( + "status,value", + [ + (BulkReportStatus.PENDING, "pending"), + (BulkReportStatus.PROCESSING, "processing"), + (BulkReportStatus.DONE, "done"), + (BulkReportStatus.FAILED, "failed"), + ], +) +def test_bulk_report_status_enum_correct_values( + status: BulkReportStatus, value: str +) -> None: + """Test that correct `BulkReportStatus` enum values can be instantiated.""" + status_instance = BulkReportStatus(value) + assert status_instance == status + + +@pytest.mark.parametrize( + "invalid_value", + ["invalid", ""], +) +def test_bulk_report_status_enum_invalid_value_raises_value_error( + invalid_value: str, +) -> None: + """Test that invalid `BulkReportStatus` enum values raise a `ValueError`.""" + with pytest.raises(ValueError): + BulkReportStatus(invalid_value) + + +def test_bulk_report_geography_deserializes_all_fields() -> None: + """Test that `BulkReportGeography` deserializes all fields correctly.""" + input: Dict[str, Any] = { + "type": "dataset", + "dataset": region_dataset, + "id": region_id, + } + geo: BulkReportGeography = BulkReportGeography(**input) + assert geo.type == "dataset" + assert geo.dataset == region_dataset + assert geo.id == region_id + + +def test_bulk_report_geography_deserializes_optional_fields_to_none() -> None: + """Test that `BulkReportGeography` sets missing optional fields to `None`.""" + geo: BulkReportGeography = BulkReportGeography() # type: ignore[call-arg] + assert geo.type is None + assert geo.dataset is None + assert geo.id is None + + +def test_bulk_report_item_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportItem` deserializes all fields correctly.""" + bulk_report_item: BulkReportItem = BulkReportItem(**mock_raw_bulk_report_item) + assert bulk_report_item.id is not None + assert bulk_report_item.name is not None + assert bulk_report_item.file_path is not None + assert bulk_report_item.format is not None + assert bulk_report_item.filters is not None + assert bulk_report_item.geom is not None + assert bulk_report_item.status is not None + assert bulk_report_item.owner_id is not None + assert bulk_report_item.owner_type is not None + assert bulk_report_item.created_at is not None + assert bulk_report_item.updated_at is not None + assert bulk_report_item.file_size is not None + + +def test_bulk_report_item_deserializes_optional_fields_to_none() -> None: + """Test that `BulkReportItem` sets missing optional fields to `None`.""" + bulk_report_item: BulkReportItem = BulkReportItem() # type: ignore[call-arg] + assert bulk_report_item.id is None + assert bulk_report_item.name is None + assert bulk_report_item.file_path is None + assert bulk_report_item.format is None + assert bulk_report_item.filters is None + assert bulk_report_item.geom is None + assert bulk_report_item.status is None + assert bulk_report_item.owner_id is None + assert bulk_report_item.owner_type is None + assert bulk_report_item.created_at is None + assert bulk_report_item.updated_at is None + assert bulk_report_item.file_size is None + + +@pytest.mark.parametrize( + "empty_datetime_field", + ["", " "], +) +def test_bulk_report_item_deserializes_empty_datetime_strings_to_none( + mock_raw_bulk_report_item: Dict[str, Any], empty_datetime_field: str +) -> None: + """Test that `BulkReportItem` empty strings for datetime fields (`createdAt`, `updatedAt`) are converted to `None`.""" + raw_bulk_report_item: Dict[str, Any] = { + **mock_raw_bulk_report_item, + "createdAt": empty_datetime_field, + "updatedAt": empty_datetime_field, + } + report_item: BulkReportItem = BulkReportItem(**raw_bulk_report_item) + assert report_item.created_at is None + assert report_item.updated_at is None diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py new file mode 100644 index 0000000..2811af3 --- /dev/null +++ b/tests/resources/bulk_downloads/conftest.py @@ -0,0 +1,40 @@ +"""Test configurations for `gfwapiclient.resources.bulk_downloads`.""" + +from typing import Any, Callable, Dict, Final + +import pytest + + +region_dataset: Final[str] = "public-eez-areas" +region_id: Final[int] = 8466 +geometry: Final[Dict[str, Any]] = { + "type": "Polygon", + "coordinates": [ + [ + [-180.0, -85.0511287798066], + [-180.0, 0.0], + [0.0, 0.0], + [0.0, -85.0511287798066], + [-180.0, -85.0511287798066], + ] + ], +} + + +@pytest.fixture +def mock_raw_bulk_report_item( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for a mock raw bulk report item. + + This fixture loads sample JSON data representing a single + `BulkReportItem` from a fixture file. + + Returns: + Dict[str, Any]: + Raw `BulkReportItem` sample data as a dictionary. + """ + raw_bulk_report_item: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_item.json" + ) + return raw_bulk_report_item From 6c61fc18c4c9554288eecee6f3b3285e5116754d Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 26 Nov 2025 11:39:23 +0300 Subject: [PATCH 05/22] feat(bulk-downloads): implement bulk report create API endpoints and models This: - add `BulkReportCreateEndPoint`, an endpoint class for handling specific bulk report create requests - add `BulkReportCreateBody` for serializing and validating request bodies - add `BulkReportCreateItem` and `BulkReportCreateResult` for deserializing and validating API responses --- .../bulk_downloads/create/__init__.py | 17 +++++ .../bulk_downloads/create/endpoints.py | 58 ++++++++++++++++ .../bulk_downloads/create/models/__init__.py | 16 +++++ .../bulk_downloads/create/models/request.py | 66 +++++++++++++++++++ .../bulk_downloads/create/models/response.py | 56 ++++++++++++++++ .../bulk_report_create_request_body.json | 39 +++++++++++ tests/resources/bulk_downloads/conftest.py | 16 +++++ .../bulk_downloads/create/__init__.py | 1 + .../bulk_downloads/create/models/__init__.py | 1 + .../create/models/test_request_models.py | 26 ++++++++ .../create/models/test_response_models.py | 38 +++++++++++ .../bulk_downloads/create/test_endpoints.py | 65 ++++++++++++++++++ 12 files changed, 399 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/create/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/create/endpoints.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/create/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/create/models/request.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/create/models/response.py create mode 100644 tests/fixtures/bulk_downloads/bulk_report_create_request_body.json create mode 100644 tests/resources/bulk_downloads/create/__init__.py create mode 100644 tests/resources/bulk_downloads/create/models/__init__.py create mode 100644 tests/resources/bulk_downloads/create/models/test_request_models.py create mode 100644 tests/resources/bulk_downloads/create/models/test_response_models.py create mode 100644 tests/resources/bulk_downloads/create/test_endpoints.py diff --git a/src/gfwapiclient/resources/bulk_downloads/create/__init__.py b/src/gfwapiclient/resources/bulk_downloads/create/__init__.py new file mode 100644 index 0000000..e296c8a --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/create/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Create a Bulk Report. + +This module provides the endpoint and associated functionalities for creating +bulk report. It defines the `BulkReportCreateEndPoint` class, which handles the +construction and execution of API requests and the parsing of API responses for +Create a Bulk Report API endpoint. + +For detailed information about the Create a Bulk Report API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report + +For more details on the Create a Bulk Report data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/create/endpoints.py b/src/gfwapiclient/resources/bulk_downloads/create/endpoints.py new file mode 100644 index 0000000..852631d --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/create/endpoints.py @@ -0,0 +1,58 @@ +"""Global Fishing Watch (GFW) API Python Client - Create a Bulk Report API endpoint.""" + +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.http.endpoints import PostEndPoint +from gfwapiclient.http.models import RequestParams +from gfwapiclient.resources.bulk_downloads.create.models.request import ( + BulkReportCreateBody, +) +from gfwapiclient.resources.bulk_downloads.create.models.response import ( + BulkReportCreateItem, + BulkReportCreateResult, +) + + +__all__ = ["BulkReportCreateEndPoint"] + + +class BulkReportCreateEndPoint( + PostEndPoint[ + RequestParams, + BulkReportCreateBody, + BulkReportCreateItem, + BulkReportCreateResult, + ] +): + """Create a Bulk Report API endpoint. + + This endpoint is used to create bulk reports based on the provided request body. + + For more details on the Create a Bulk Report API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report + """ + + def __init__( + self, + *, + request_body: BulkReportCreateBody, + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkReportCreateEndPoint`. + + Args: + request_body (BulkReportCreateBody): + The request body. + + http_client (HTTPClient): + The HTTP client for making API requests. + """ + super().__init__( + path="bulk-reports", + request_params=None, + request_body=request_body, + result_item_class=BulkReportCreateItem, + result_class=BulkReportCreateResult, + http_client=http_client, + ) diff --git a/src/gfwapiclient/resources/bulk_downloads/create/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/create/models/__init__.py new file mode 100644 index 0000000..7a009ba --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/create/models/__init__.py @@ -0,0 +1,16 @@ +"""Global Fishing Watch (GFW) API Python Client - Create a Bulk Report Models. + +This module defines Pydantic data models used for interacting with the +Create a Bulk Report API endpoint. These models are used to represent request bodies +and response data when creating bulk reports. + +For detailed information about the Create a Bulk Report API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file + +For more details on the Create a Bulk Report data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/create/models/request.py b/src/gfwapiclient/resources/bulk_downloads/create/models/request.py new file mode 100644 index 0000000..fd7f06f --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/create/models/request.py @@ -0,0 +1,66 @@ +"""Global Fishing Watch (GFW) API Python Client - Create a Bulk Report Request Models.""" + +from typing import Final, List, Optional + +from pydantic import Field + +from gfwapiclient.http.models import RequestBody +from gfwapiclient.resources.bulk_downloads.base.models.request import ( + BulkReportDataset, + BulkReportFormat, + BulkReportGeometry, + BulkReportRegion, +) + + +__all__ = ["BulkReportCreateBody"] + + +BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE: Final[str] = ( + "Create bulk report request body validation failed." +) + + +class BulkReportCreateBody(RequestBody): + """Request body for Create a Bulk Report API endpoint. + + Represents dataset, filters, spatial parameters etc. for creating bulk reports. + + For more details on the Create a Bulk Report API endpoint supported request body, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-body-only-for-post-request + + See: https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report + + Attributes: + name (Optional[str]): + Human-readable name of the bulk report. + If not provided, it will be generate using format + `"{dataset}-{uuidv4}"`. + + dataset (Optional[BulkReportDataset]): + Dataset that will be used to create the bulk report. + Defaults to `"public-fixed-infrastructure-data:v1.1"`. + + geojson (Optional[BulkReportGeometry]): + Custom GeoJSON geometry to filter the bulk report. + + format (Optional[BulkReportFormat]): + Bulk report result format. + + region (Optional[BulkReportRegion]): + Predefined region information to filter the bulk report. + + filters (Optional[List[str]]): + List of filters to apply when generating the bulk report. + """ + + name: Optional[str] = Field(None, alias="name") + dataset: Optional[BulkReportDataset] = Field( + BulkReportDataset.FIXED_INFRASTRUCTURE_DATA_LATEST, alias="dataset" + ) + geojson: Optional[BulkReportGeometry] = Field(None, alias="geojson") + format: Optional[BulkReportFormat] = Field(BulkReportFormat.JSON, alias="format") + region: Optional[BulkReportRegion] = Field(None, alias="region") + filters: Optional[List[str]] = Field(None, alias="filters") diff --git a/src/gfwapiclient/resources/bulk_downloads/create/models/response.py b/src/gfwapiclient/resources/bulk_downloads/create/models/response.py new file mode 100644 index 0000000..c0df35f --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/create/models/response.py @@ -0,0 +1,56 @@ +"""Global Fishing Watch (GFW) API Python Client - Create a Bulk Report Response Models.""" + +from typing import Type + +from gfwapiclient.http.models import Result +from gfwapiclient.resources.bulk_downloads.base.models.response import BulkReportItem + + +__all__ = ["BulkReportCreateItem", "BulkReportCreateResult"] + + +class BulkReportCreateItem(BulkReportItem): + """Result item for the Create a Bulk Report API endpoint. + + Represents metadata and status of the created bulk report. + + For more details on the Create a Bulk Report API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + """ + + pass + + +class BulkReportCreateResult(Result[BulkReportCreateItem]): + """Result for the Create a Bulk Report API endpoint. + + For more details on the Create a Bulk Report API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + Attributes: + _result_item_class (Type[BulkReportFileItem]): + The model used for individual result items. + + _data (BulkReportCreateItem): + The bulk report item returned in the response. + """ + + _result_item_class: Type[BulkReportCreateItem] + _data: BulkReportCreateItem + + def __init__(self, data: BulkReportCreateItem) -> None: + """Initializes a new `BulkReportCreateResult`. + + Args: + data (BulkReportCreateItem): + The created bulk report details. + """ + super().__init__(data=data) diff --git a/tests/fixtures/bulk_downloads/bulk_report_create_request_body.json b/tests/fixtures/bulk_downloads/bulk_report_create_request_body.json new file mode 100644 index 0000000..99bd05d --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_create_request_body.json @@ -0,0 +1,39 @@ +{ + "name": "sar-fixed-infrastructure-data-202409", + "dataset": "public-fixed-infrastructure-data:latest", + "format": "JSON", + "filters": [ + "label = 'oil'" + ], + "region": { + "dataset": "public-eez-areas", + "id": 8466 + }, + "geojson": { + "type": "Polygon", + "coordinates": [ + [ + [ + -180.0, + -85.0511287798066 + ], + [ + -180.0, + 0.0 + ], + [ + 0.0, + 0.0 + ], + [ + 0.0, + -85.0511287798066 + ], + [ + -180.0, + -85.0511287798066 + ] + ] + ] + } +} diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py index 2811af3..588ba74 100644 --- a/tests/resources/bulk_downloads/conftest.py +++ b/tests/resources/bulk_downloads/conftest.py @@ -38,3 +38,19 @@ def mock_raw_bulk_report_item( "bulk_downloads/bulk_report_item.json" ) return raw_bulk_report_item + + +@pytest.fixture +def mock_raw_bulk_report_create_request_body( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for mock raw bulk report create request body. + + Returns: + Dict[str, Any]: + Raw `BulkReportCreateBody` sample data as dictionary. + """ + raw_bulk_report_create_request_body: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_create_request_body.json" + ) + return raw_bulk_report_create_request_body diff --git a/tests/resources/bulk_downloads/create/__init__.py b/tests/resources/bulk_downloads/create/__init__.py new file mode 100644 index 0000000..219734c --- /dev/null +++ b/tests/resources/bulk_downloads/create/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create`.""" diff --git a/tests/resources/bulk_downloads/create/models/__init__.py b/tests/resources/bulk_downloads/create/models/__init__.py new file mode 100644 index 0000000..4647785 --- /dev/null +++ b/tests/resources/bulk_downloads/create/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create.models`.""" diff --git a/tests/resources/bulk_downloads/create/models/test_request_models.py b/tests/resources/bulk_downloads/create/models/test_request_models.py new file mode 100644 index 0000000..3dae2db --- /dev/null +++ b/tests/resources/bulk_downloads/create/models/test_request_models.py @@ -0,0 +1,26 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create.models.request`.""" + +from typing import Any, Dict + +from gfwapiclient.resources.bulk_downloads.create.models.request import ( + BulkReportCreateBody, +) + + +def test_bulk_report_create_request_body_serializes_all_fields( + mock_raw_bulk_report_create_request_body: Dict[str, Any], +) -> None: + """Test that `BulkReportCreateBody` serializes all fields correctly.""" + bulk_report_create_request_body: BulkReportCreateBody = BulkReportCreateBody( + **mock_raw_bulk_report_create_request_body + ) + assert bulk_report_create_request_body.name is not None + assert bulk_report_create_request_body.dataset is not None + assert bulk_report_create_request_body.geojson is not None + assert bulk_report_create_request_body.format is not None + assert bulk_report_create_request_body.region is not None + assert bulk_report_create_request_body.filters is not None + assert ( + bulk_report_create_request_body.to_json_body() + == mock_raw_bulk_report_create_request_body + ) diff --git a/tests/resources/bulk_downloads/create/models/test_response_models.py b/tests/resources/bulk_downloads/create/models/test_response_models.py new file mode 100644 index 0000000..5dd47b3 --- /dev/null +++ b/tests/resources/bulk_downloads/create/models/test_response_models.py @@ -0,0 +1,38 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create.models.response`.""" + +from typing import Any, Dict, cast + +from gfwapiclient.resources.bulk_downloads.create.models.response import ( + BulkReportCreateItem, + BulkReportCreateResult, +) + + +def test_bulk_report_create_item_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportCreateItem` deserializes all fields correctly.""" + bulk_report_item: BulkReportCreateItem = BulkReportCreateItem( + **mock_raw_bulk_report_item + ) + assert bulk_report_item.id is not None + assert bulk_report_item.name is not None + assert bulk_report_item.file_path is not None + assert bulk_report_item.format is not None + assert bulk_report_item.filters is not None + assert bulk_report_item.geom is not None + assert bulk_report_item.status is not None + assert bulk_report_item.owner_id is not None + assert bulk_report_item.owner_type is not None + assert bulk_report_item.created_at is not None + assert bulk_report_item.updated_at is not None + assert bulk_report_item.file_size is not None + + +def test_bulk_report_create_result_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportCreateResult` deserializes all fields correctly.""" + data: BulkReportCreateItem = BulkReportCreateItem(**mock_raw_bulk_report_item) + result = BulkReportCreateResult(data=data) + assert cast(BulkReportCreateItem, result.data()) == data diff --git a/tests/resources/bulk_downloads/create/test_endpoints.py b/tests/resources/bulk_downloads/create/test_endpoints.py new file mode 100644 index 0000000..dc64276 --- /dev/null +++ b/tests/resources/bulk_downloads/create/test_endpoints.py @@ -0,0 +1,65 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create.endpoints`.""" + +from typing import Any, Dict, cast + +import httpx +import pytest +import respx + +from gfwapiclient.exceptions.base import GFWAPIClientError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.create.endpoints import ( + BulkReportCreateEndPoint, +) +from gfwapiclient.resources.bulk_downloads.create.models.request import ( + BulkReportCreateBody, +) +from gfwapiclient.resources.bulk_downloads.create.models.response import ( + BulkReportCreateItem, + BulkReportCreateResult, +) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_create_endpoint_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_create_request_body: Dict[str, Any], + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportCreateEndPoint` request succeeds with a valid response.""" + mock_responsex.post("/bulk-reports").respond(201, json=mock_raw_bulk_report_item) + request_body: BulkReportCreateBody = BulkReportCreateBody( + **mock_raw_bulk_report_create_request_body + ) + endpoint: BulkReportCreateEndPoint = BulkReportCreateEndPoint( + request_body=request_body, + http_client=mock_http_client, + ) + result: BulkReportCreateResult = await endpoint.request() + data = cast(BulkReportCreateItem, result.data()) + assert isinstance(result, BulkReportCreateResult) + assert isinstance(data, BulkReportCreateItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_create_endpoint_request_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_create_request_body: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportCreateEndPoint` request fails with an invalid response.""" + mock_responsex.post("/bulk-reports").mock( + return_value=httpx.Response(status_code=400, json={"error": "Bad Request"}) + ) + request_body: BulkReportCreateBody = BulkReportCreateBody( + **mock_raw_bulk_report_create_request_body + ) + endpoint: BulkReportCreateEndPoint = BulkReportCreateEndPoint( + request_body=request_body, + http_client=mock_http_client, + ) + with pytest.raises(GFWAPIClientError): + await endpoint.request() From f0a44b053430f3b8756dd5b56ed19e940dc74290 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 26 Nov 2025 12:06:00 +0300 Subject: [PATCH 06/22] feat(bulk-downloads): implement bulk report detail API endpoints and models This: - add `BulkReportDetailEndPoint`, an endpoint class for handling specific bulk report detail requests - add `BulkReportDetailItem` and `BulkReportDetailResult` for deserializing and validating API responses --- .../bulk_downloads/detail/__init__.py | 17 ++++++ .../bulk_downloads/detail/endpoints.py | 57 ++++++++++++++++++ .../bulk_downloads/detail/models/__init__.py | 16 +++++ .../bulk_downloads/detail/models/response.py | 58 ++++++++++++++++++ .../bulk_downloads/detail/__init__.py | 1 + .../bulk_downloads/detail/models/__init__.py | 1 + .../detail/models/test_response_models.py | 38 ++++++++++++ .../bulk_downloads/detail/test_endpoints.py | 59 +++++++++++++++++++ 8 files changed, 247 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/detail/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/detail/endpoints.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/detail/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/detail/models/response.py create mode 100644 tests/resources/bulk_downloads/detail/__init__.py create mode 100644 tests/resources/bulk_downloads/detail/models/__init__.py create mode 100644 tests/resources/bulk_downloads/detail/models/test_response_models.py create mode 100644 tests/resources/bulk_downloads/detail/test_endpoints.py diff --git a/src/gfwapiclient/resources/bulk_downloads/detail/__init__.py b/src/gfwapiclient/resources/bulk_downloads/detail/__init__.py new file mode 100644 index 0000000..78e81d3 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/detail/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Get Bulk Report by ID. + +This module provides the endpoint and associated functionalities for retrieving details +of the previously created bulk report. It defines the `BulkReportDetailEndPoint` class, +which handles the construction and execution of API requests, and the parsing of API +responses for Get Bulk Report by ID API endpoint. + +For detailed information about the Get Bulk Report by ID API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id + +For more details on the Get Bulk Report by ID data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/detail/endpoints.py b/src/gfwapiclient/resources/bulk_downloads/detail/endpoints.py new file mode 100644 index 0000000..c95609f --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/detail/endpoints.py @@ -0,0 +1,57 @@ +"""Global Fishing Watch (GFW) API Python Client - Get Bulk Report by ID API endpoint.""" + +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.http.endpoints import GetEndPoint +from gfwapiclient.http.models import RequestBody, RequestParams +from gfwapiclient.resources.bulk_downloads.detail.models.response import ( + BulkReportDetailItem, + BulkReportDetailResult, +) + + +__all__ = ["BulkReportDetailEndPoint"] + + +class BulkReportDetailEndPoint( + GetEndPoint[ + RequestParams, RequestBody, BulkReportDetailItem, BulkReportDetailResult + ], +): + """Get Bulk Report by ID API endpoint. + + This endpoint retrieves metadata and status of the previously created bulk report + based on the provided bulk report ID. + + For more details on the Get Bulk Report by ID API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id + + For more details on the Get Bulk Report by ID data caveats, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + """ + + def __init__( + self, + *, + bulk_report_id: str, + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkReportDetailEndPoint`. + + Args: + bulk_report_id (str): + Unique identifier (ID) of the bulk report. + + http_client (HTTPClient): + The HTTP client used to make the API call. + """ + super().__init__( + path=f"bulk-reports/{bulk_report_id}", + request_params=None, + result_item_class=BulkReportDetailItem, + result_class=BulkReportDetailResult, + http_client=http_client, + ) diff --git a/src/gfwapiclient/resources/bulk_downloads/detail/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/detail/models/__init__.py new file mode 100644 index 0000000..df48054 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/detail/models/__init__.py @@ -0,0 +1,16 @@ +"""Global Fishing Watch (GFW) API Python Client - Get Bulk Report by ID Models. + +This module defines Pydantic data models used for interacting with the +Get Bulk Report by ID API endpoint. These models are used to represent response data +when retrieving detailed metadata and status of previously created bulk report. + +For detailed information about the Get Bulk Report by ID API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id + +For more details on the Get Bulk Report by ID data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/detail/models/response.py b/src/gfwapiclient/resources/bulk_downloads/detail/models/response.py new file mode 100644 index 0000000..9638b31 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/detail/models/response.py @@ -0,0 +1,58 @@ +"""Global Fishing Watch (GFW) API Python Client - Get Bulk Report by ID Response Models.""" + +from typing import Type + +from gfwapiclient.http.models import Result +from gfwapiclient.resources.bulk_downloads.base.models.response import BulkReportItem + + +__all__ = ["BulkReportDetailItem", "BulkReportDetailResult"] + + +class BulkReportDetailItem(BulkReportItem): + """Result item for the Get Bulk Report by ID API endpoint. + + Represents metadata and status of the previously created bulk report. + + For more details on the Get Bulk Report by ID API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id-http-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + """ + + pass + + +class BulkReportDetailResult(Result[BulkReportDetailItem]): + """Result for the Get Bulk Report by ID API endpoint. + + For more details on the Get Bulk Report by ID API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id-http-response + + Attributes: + _result_item_class (Type[BulkReportDetailItem]): + The model used for individual result items. + + _data (BulkReportDetailItem): + The bulk report item returned in the response. + """ + + _result_item_class: Type[BulkReportDetailItem] + _data: BulkReportDetailItem + + def __init__(self, data: BulkReportDetailItem) -> None: + """Initializes a new `BulkReportDetailResult`. + + Args: + data (BulkReportDetailItem): + The bulk report details. + """ + super().__init__(data=data) diff --git a/tests/resources/bulk_downloads/detail/__init__.py b/tests/resources/bulk_downloads/detail/__init__.py new file mode 100644 index 0000000..e440277 --- /dev/null +++ b/tests/resources/bulk_downloads/detail/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.detail`.""" diff --git a/tests/resources/bulk_downloads/detail/models/__init__.py b/tests/resources/bulk_downloads/detail/models/__init__.py new file mode 100644 index 0000000..017b125 --- /dev/null +++ b/tests/resources/bulk_downloads/detail/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.detail.models`.""" diff --git a/tests/resources/bulk_downloads/detail/models/test_response_models.py b/tests/resources/bulk_downloads/detail/models/test_response_models.py new file mode 100644 index 0000000..b034cf9 --- /dev/null +++ b/tests/resources/bulk_downloads/detail/models/test_response_models.py @@ -0,0 +1,38 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.detail.models.response`.""" + +from typing import Any, Dict, cast + +from gfwapiclient.resources.bulk_downloads.detail.models.response import ( + BulkReportDetailItem, + BulkReportDetailResult, +) + + +def test_bulk_report_detail_item_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportDetailItem` deserializes all fields correctly.""" + bulk_report_item: BulkReportDetailItem = BulkReportDetailItem( + **mock_raw_bulk_report_item + ) + assert bulk_report_item.id is not None + assert bulk_report_item.name is not None + assert bulk_report_item.file_path is not None + assert bulk_report_item.format is not None + assert bulk_report_item.filters is not None + assert bulk_report_item.geom is not None + assert bulk_report_item.status is not None + assert bulk_report_item.owner_id is not None + assert bulk_report_item.owner_type is not None + assert bulk_report_item.created_at is not None + assert bulk_report_item.updated_at is not None + assert bulk_report_item.file_size is not None + + +def test_bulk_report_detail_result_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportDetailResult` deserializes all fields correctly.""" + data: BulkReportDetailItem = BulkReportDetailItem(**mock_raw_bulk_report_item) + result = BulkReportDetailResult(data=data) + assert cast(BulkReportDetailItem, result.data()) == data diff --git a/tests/resources/bulk_downloads/detail/test_endpoints.py b/tests/resources/bulk_downloads/detail/test_endpoints.py new file mode 100644 index 0000000..3d4969b --- /dev/null +++ b/tests/resources/bulk_downloads/detail/test_endpoints.py @@ -0,0 +1,59 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.detail.endpoints`.""" + +from typing import Any, Dict, Final, cast + +import httpx +import pytest +import respx + +from gfwapiclient.exceptions.base import GFWAPIClientError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.detail.endpoints import ( + BulkReportDetailEndPoint, +) +from gfwapiclient.resources.bulk_downloads.detail.models.response import ( + BulkReportDetailItem, + BulkReportDetailResult, +) + + +bulk_report_id: Final[str] = "adbb9b62-5c08-4142-82e0-b2b575f3e058" + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_detail_endpoint_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportDetailEndPoint` request succeeds with a valid response.""" + mock_responsex.get(f"/bulk-reports/{bulk_report_id}").respond( + 200, json=mock_raw_bulk_report_item + ) + endpoint: BulkReportDetailEndPoint = BulkReportDetailEndPoint( + bulk_report_id=bulk_report_id, + http_client=mock_http_client, + ) + result: BulkReportDetailResult = await endpoint.request() + data = cast(BulkReportDetailItem, result.data()) + assert isinstance(result, BulkReportDetailResult) + assert isinstance(data, BulkReportDetailItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_detail_endpoint_request_failure( + mock_http_client: HTTPClient, + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportDetailEndPoint` request fails with an invalid response.""" + mock_responsex.get(f"/bulk-reports/{bulk_report_id}").mock( + return_value=httpx.Response(status_code=400, json={"error": "Bad Request"}) + ) + endpoint: BulkReportDetailEndPoint = BulkReportDetailEndPoint( + bulk_report_id=bulk_report_id, + http_client=mock_http_client, + ) + with pytest.raises(GFWAPIClientError): + await endpoint.request() From 4dc68f553ee692b5d8089eda25c9154c767ea232 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 26 Nov 2025 12:42:52 +0300 Subject: [PATCH 07/22] feat(bulk-downloads): implement bulk report list API endpoints and models This: - add `BulkReportListEndPoint`, an endpoint class for handling specific bulk report list requests - add `BulkReportListParams` for serializing and validating request parameters - add `BulkReportListItem` and `BulkReportListResult` for deserializing and validating API responses --- .../resources/bulk_downloads/list/__init__.py | 17 +++ .../bulk_downloads/list/endpoints.py | 104 ++++++++++++++++++ .../bulk_downloads/list/models/__init__.py | 17 +++ .../bulk_downloads/list/models/request.py | 50 +++++++++ .../bulk_downloads/list/models/response.py | 58 ++++++++++ .../bulk_report_list_request_params.json | 6 + tests/resources/bulk_downloads/conftest.py | 16 +++ .../resources/bulk_downloads/list/__init__.py | 1 + .../bulk_downloads/list/models/__init__.py | 1 + .../list/models/test_request_models.py | 21 ++++ .../list/models/test_response_models.py | 38 +++++++ .../bulk_downloads/list/test_endpoints.py | 89 +++++++++++++++ 12 files changed, 418 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/list/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/list/endpoints.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/list/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/list/models/request.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/list/models/response.py create mode 100644 tests/fixtures/bulk_downloads/bulk_report_list_request_params.json create mode 100644 tests/resources/bulk_downloads/list/__init__.py create mode 100644 tests/resources/bulk_downloads/list/models/__init__.py create mode 100644 tests/resources/bulk_downloads/list/models/test_request_models.py create mode 100644 tests/resources/bulk_downloads/list/models/test_response_models.py create mode 100644 tests/resources/bulk_downloads/list/test_endpoints.py diff --git a/src/gfwapiclient/resources/bulk_downloads/list/__init__.py b/src/gfwapiclient/resources/bulk_downloads/list/__init__.py new file mode 100644 index 0000000..dc9a306 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/list/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Get All Bulk Reports. + +This module provides the endpoint and associated functionalities for retrieving details +of multiple previously created bulk reports. It defines the `BulkReportListEndPoint` +class, which handles the construction and execution of API requests, and the parsing +of API responses for Get All Bulk Reports API endpoint. + +For detailed information about the Get All Bulk Reports API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + +For more details on the Get All Bulk Reports data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/list/endpoints.py b/src/gfwapiclient/resources/bulk_downloads/list/endpoints.py new file mode 100644 index 0000000..6831f12 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/list/endpoints.py @@ -0,0 +1,104 @@ +"""Global Fishing Watch (GFW) API Python Client - Get All Bulk Reports API endpoint.""" + +from typing import Any, Dict, List, Union + +from typing_extensions import override + +from gfwapiclient.exceptions.validation import ResultValidationError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.http.endpoints import GetEndPoint +from gfwapiclient.http.models import RequestBody +from gfwapiclient.resources.bulk_downloads.list.models.request import ( + BulkReportListParams, +) +from gfwapiclient.resources.bulk_downloads.list.models.response import ( + BulkReportListItem, + BulkReportListResult, +) + + +__all__ = ["BulkReportListEndPoint"] + + +class BulkReportListEndPoint( + GetEndPoint[ + BulkReportListParams, RequestBody, BulkReportListItem, BulkReportListResult + ], +): + """Get All Bulk Reports API endpoint. + + This endpoint retrieves a list of metadata and status of the previously created + bulk reports based on the provided request parameters. + + For more details on the Get All Bulk Reports API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + """ + + def __init__( + self, + *, + request_params: BulkReportListParams, + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkReportListEndPoint`. + + Args: + request_params (BulkReportListParams): + The request parameters. + + http_client (HTTPClient): + The HTTP client used to make the API call. + """ + super().__init__( + path="bulk-reports", + request_params=request_params, + result_item_class=BulkReportListItem, + result_class=BulkReportListResult, + http_client=http_client, + ) + + @override + def _transform_response_data( + self, + *, + body: Union[List[Dict[str, Any]], Dict[str, Any]], + ) -> Union[List[Dict[str, Any]], Dict[str, Any]]: + """Transform and reshape response body and yield data. + + This method transforms the raw response body from the API into a format + suitable for the `BulkReportListResult` model. + + The expected response structure is: `{"entries": [{...}]}`. + + Args: + body (Union[List[Dict[str, Any]], Dict[str, Any]]): + The raw response body. + + Returns: + Union[List[Dict[str, Any]], Dict[str, Any]]: + The transformed response data. + + Raises: + ResultValidationError: + If the response body does not match the expected format. + """ + # expected: {"entries": [{"key": ...}, ...], ...} + if not isinstance(body, dict) or "entries" not in body: + raise ResultValidationError( + message="Expected a list of entries, but got an empty list.", + body=body, + ) + + # Transforming and reshaping entries + bulk_report_entries: List[Dict[str, Any]] = body.get("entries", []) + transformed_data: List[Dict[str, Any]] = [] + + # Loop through "entries" list i.e [{"key": ..., ...}, ...] + for bulk_report_entry in bulk_report_entries: + # Append extracted dictionaries, if not empty + if bulk_report_entry: + transformed_data.append(dict(**bulk_report_entry)) + + return transformed_data diff --git a/src/gfwapiclient/resources/bulk_downloads/list/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/list/models/__init__.py new file mode 100644 index 0000000..05acc60 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/list/models/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Get All Bulk Reports Models. + +This module defines Pydantic data models used for interacting with the +Get All Bulk Reports API endpoint. These models are used to represent +request parameters, and response data when retrieving detailed metadata and status of +multiple previously created bulk report + +For detailed information about the Get All Bulk Reports API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + +For more details on the Get All Bulk Reports data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/list/models/request.py b/src/gfwapiclient/resources/bulk_downloads/list/models/request.py new file mode 100644 index 0000000..fb6b45f --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/list/models/request.py @@ -0,0 +1,50 @@ +"""Global Fishing Watch (GFW) API Python Client - Get All Bulk Reports Request Models.""" + +from typing import Final, Optional + +from pydantic import Field + +from gfwapiclient.http.models import RequestParams +from gfwapiclient.resources.bulk_downloads.base.models.response import BulkReportStatus + + +__all__ = ["BulkReportListParams"] + + +BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE: Final[str] = ( + "Get bulk reports request parameters validation failed." +) + + +class BulkReportListParams(RequestParams): + """Request query parameters for Get All Bulk Reports API endpoint. + + Represents pagination, sorting, filtering parameters etc. for retrieving + previously created bulk reports. + + For more details on the Get All Bulk Reports API endpoint supported + request parameters, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + + Attributes: + limit (Optional[int]): + Maximum number of bulk reports to return. + Defaults to `99999`. + + offset (Optional[int]): + Number of bulk reports to skip before returning results. + Used for pagination. Defaults to `0`. + + sort (Optional[str]): + Property to sort the bulk reports by (e.g., `"-createdAt"`). + + status (Optional[BulkReportStatus]): + Current status of the bulk report generation process (e.g., `"done"` etc.). + """ + + limit: Optional[int] = Field(99999, ge=0, alias="limit") + offset: Optional[int] = Field(0, ge=0, alias="offset") + sort: Optional[str] = Field("-createdAt", alias="sort") + status: Optional[BulkReportStatus] = Field(None, alias="status") diff --git a/src/gfwapiclient/resources/bulk_downloads/list/models/response.py b/src/gfwapiclient/resources/bulk_downloads/list/models/response.py new file mode 100644 index 0000000..2cdad94 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/list/models/response.py @@ -0,0 +1,58 @@ +"""Global Fishing Watch (GFW) API Python Client - Get All Bulk Reports Response Models.""" + +from typing import List, Type + +from gfwapiclient.http.models import Result +from gfwapiclient.resources.bulk_downloads.base.models.response import BulkReportItem + + +__all__ = ["BulkReportListItem", "BulkReportListResult"] + + +class BulkReportListItem(BulkReportItem): + """Result item for the Get All Bulk Reports API endpoint. + + Represents metadata and status of the previously created bulk report. + + For more details on the Get All Bulk Reports API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-reports-get-http-response + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-report-object-schema + """ + + pass + + +class BulkReportListResult(Result[BulkReportListItem]): + """Result for the Get All Bulk Reports API endpoint. + + For more details on the Get All Bulk Reports API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + + Attributes: + _result_item_class (Type[BulkReportListItem]): + The model used for individual result items. + + _data (BulkReportListItem): + The bulk report item returned in the response. + """ + + _result_item_class: Type[BulkReportListItem] + _data: List[BulkReportListItem] + + def __init__(self, data: List[BulkReportListItem]) -> None: + """Initializes a new `BulkReportListResult`. + + Args: + data (List[BulkReportListItem]): + The list of bulk report items. + """ + super().__init__(data=data) diff --git a/tests/fixtures/bulk_downloads/bulk_report_list_request_params.json b/tests/fixtures/bulk_downloads/bulk_report_list_request_params.json new file mode 100644 index 0000000..20bade6 --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_list_request_params.json @@ -0,0 +1,6 @@ +{ + "limit": 99999, + "offset": 0, + "sort": "-createdAt", + "status": "done" +} diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py index 588ba74..d258ac9 100644 --- a/tests/resources/bulk_downloads/conftest.py +++ b/tests/resources/bulk_downloads/conftest.py @@ -54,3 +54,19 @@ def mock_raw_bulk_report_create_request_body( "bulk_downloads/bulk_report_create_request_body.json" ) return raw_bulk_report_create_request_body + + +@pytest.fixture +def mock_raw_bulk_report_list_request_params( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for mock raw bulk report list request parameters. + + Returns: + Dict[str, Any]: + Raw `BulkReportListParams` sample data as dictionary. + """ + raw_bulk_report_list_request_params: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_list_request_params.json" + ) + return raw_bulk_report_list_request_params diff --git a/tests/resources/bulk_downloads/list/__init__.py b/tests/resources/bulk_downloads/list/__init__.py new file mode 100644 index 0000000..a16ecf3 --- /dev/null +++ b/tests/resources/bulk_downloads/list/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.list`.""" diff --git a/tests/resources/bulk_downloads/list/models/__init__.py b/tests/resources/bulk_downloads/list/models/__init__.py new file mode 100644 index 0000000..4647785 --- /dev/null +++ b/tests/resources/bulk_downloads/list/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.create.models`.""" diff --git a/tests/resources/bulk_downloads/list/models/test_request_models.py b/tests/resources/bulk_downloads/list/models/test_request_models.py new file mode 100644 index 0000000..43bf184 --- /dev/null +++ b/tests/resources/bulk_downloads/list/models/test_request_models.py @@ -0,0 +1,21 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.list.models.request`.""" + +from typing import Any, Dict + +from gfwapiclient.resources.bulk_downloads.list.models.request import ( + BulkReportListParams, +) + + +def test_bulk_report_list_request_params_serializes_all_fields( + mock_raw_bulk_report_list_request_params: Dict[str, Any], +) -> None: + """Test that `BulkReportListParams` serializes all fields correctly.""" + bulk_report_list_request_params: BulkReportListParams = BulkReportListParams( + **mock_raw_bulk_report_list_request_params + ) + assert bulk_report_list_request_params.limit is not None + assert bulk_report_list_request_params.offset is not None + assert bulk_report_list_request_params.sort is not None + assert bulk_report_list_request_params.status is not None + assert bulk_report_list_request_params.to_query_params() is not None diff --git a/tests/resources/bulk_downloads/list/models/test_response_models.py b/tests/resources/bulk_downloads/list/models/test_response_models.py new file mode 100644 index 0000000..b379487 --- /dev/null +++ b/tests/resources/bulk_downloads/list/models/test_response_models.py @@ -0,0 +1,38 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.list.models.response`.""" + +from typing import Any, Dict, List, cast + +from gfwapiclient.resources.bulk_downloads.list.models.response import ( + BulkReportListItem, + BulkReportListResult, +) + + +def test_bulk_report_list_item_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportListItem` deserializes all fields correctly.""" + bulk_report_list_item: BulkReportListItem = BulkReportListItem( + **mock_raw_bulk_report_item + ) + assert bulk_report_list_item.id is not None + assert bulk_report_list_item.name is not None + assert bulk_report_list_item.file_path is not None + assert bulk_report_list_item.format is not None + assert bulk_report_list_item.filters is not None + assert bulk_report_list_item.geom is not None + assert bulk_report_list_item.status is not None + assert bulk_report_list_item.owner_id is not None + assert bulk_report_list_item.owner_type is not None + assert bulk_report_list_item.created_at is not None + assert bulk_report_list_item.updated_at is not None + assert bulk_report_list_item.file_size is not None + + +def test_bulk_report_list_result_deserializes_all_fields( + mock_raw_bulk_report_item: Dict[str, Any], +) -> None: + """Test that `BulkReportListResult` deserializes all fields correctly.""" + data: List[BulkReportListItem] = [BulkReportListItem(**mock_raw_bulk_report_item)] + result = BulkReportListResult(data=data) + assert cast(List[BulkReportListItem], result.data()) == data diff --git a/tests/resources/bulk_downloads/list/test_endpoints.py b/tests/resources/bulk_downloads/list/test_endpoints.py new file mode 100644 index 0000000..cd36038 --- /dev/null +++ b/tests/resources/bulk_downloads/list/test_endpoints.py @@ -0,0 +1,89 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.list.endpoints`.""" + +from typing import Any, Dict, List, cast + +import httpx +import pytest +import respx + +from gfwapiclient.exceptions.base import GFWAPIClientError +from gfwapiclient.exceptions.validation import ResultValidationError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.list.endpoints import ( + BulkReportListEndPoint, +) +from gfwapiclient.resources.bulk_downloads.list.models.request import ( + BulkReportListParams, +) +from gfwapiclient.resources.bulk_downloads.list.models.response import ( + BulkReportListItem, + BulkReportListResult, +) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_list_endpoint_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_list_request_params: Dict[str, Any], + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportListEndPoint` request succeeds with a valid response.""" + mock_responsex.get("/bulk-reports").respond( + 200, json={"entries": [mock_raw_bulk_report_item, {}]} + ) + request_params: BulkReportListParams = BulkReportListParams( + **mock_raw_bulk_report_list_request_params + ) + endpoint: BulkReportListEndPoint = BulkReportListEndPoint( + request_params=request_params, + http_client=mock_http_client, + ) + result: BulkReportListResult = await endpoint.request() + data: List[BulkReportListItem] = cast(List[BulkReportListItem], result.data()) + assert isinstance(result, BulkReportListResult) + assert isinstance(data[0], BulkReportListItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_list_endpoint_invalid_response_body_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_list_request_params: Dict[str, Any], + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportListEndPoint` request fails with an invalid response body.""" + mock_responsex.get("/bulk-reports").respond(200, json=[mock_raw_bulk_report_item]) + request_params: BulkReportListParams = BulkReportListParams( + **mock_raw_bulk_report_list_request_params + ) + endpoint: BulkReportListEndPoint = BulkReportListEndPoint( + request_params=request_params, + http_client=mock_http_client, + ) + with pytest.raises(ResultValidationError): + await endpoint.request() + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_list_endpoint_request_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_list_request_params: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportListEndPoint` request fails with an invalid response.""" + mock_responsex.get("/bulk-reports").mock( + return_value=httpx.Response(status_code=400, json={"error": "Bad Request"}) + ) + request_params: BulkReportListParams = BulkReportListParams( + **mock_raw_bulk_report_list_request_params + ) + endpoint: BulkReportListEndPoint = BulkReportListEndPoint( + request_params=request_params, + http_client=mock_http_client, + ) + with pytest.raises(GFWAPIClientError): + await endpoint.request() From edb4cdfc7d6cc75d60ce285eb4e9a59af4a22942 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 26 Nov 2025 13:08:39 +0300 Subject: [PATCH 08/22] feat(bulk-downloads): implement bulk report file API endpoints and models This: - add `BulkReportFileEndPoint`, an endpoint class for handling specific bulk report file requests - add `BulkReportFileParams` for serializing and validating request parameters - add `BulkReportFileItem` and `BulkReportFileResult` for deserializing and validating API responses --- .../resources/bulk_downloads/file/__init__.py | 18 +++++ .../bulk_downloads/file/endpoints.py | 64 +++++++++++++++++ .../bulk_downloads/file/models/__init__.py | 17 +++++ .../bulk_downloads/file/models/request.py | 36 ++++++++++ .../bulk_downloads/file/models/response.py | 60 ++++++++++++++++ .../bulk_downloads/bulk_report_file_item.json | 3 + .../bulk_report_file_request_params.json | 3 + tests/resources/bulk_downloads/conftest.py | 35 +++++++++ .../resources/bulk_downloads/file/__init__.py | 1 + .../bulk_downloads/file/models/__init__.py | 1 + .../file/models/test_request_models.py | 18 +++++ .../file/models/test_response_models.py | 27 +++++++ .../bulk_downloads/file/test_endpoints.py | 72 +++++++++++++++++++ 13 files changed, 355 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/file/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/file/endpoints.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/file/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/file/models/request.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/file/models/response.py create mode 100644 tests/fixtures/bulk_downloads/bulk_report_file_item.json create mode 100644 tests/fixtures/bulk_downloads/bulk_report_file_request_params.json create mode 100644 tests/resources/bulk_downloads/file/__init__.py create mode 100644 tests/resources/bulk_downloads/file/models/__init__.py create mode 100644 tests/resources/bulk_downloads/file/models/test_request_models.py create mode 100644 tests/resources/bulk_downloads/file/models/test_response_models.py create mode 100644 tests/resources/bulk_downloads/file/test_endpoints.py diff --git a/src/gfwapiclient/resources/bulk_downloads/file/__init__.py b/src/gfwapiclient/resources/bulk_downloads/file/__init__.py new file mode 100644 index 0000000..e5f94d8 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/file/__init__.py @@ -0,0 +1,18 @@ +"""Global Fishing Watch (GFW) API Python Client - Download bulk Report (URL File). + +This module provides the endpoint and associated functionalities for retrieving signed +URL to download file(s) (i.e., `"DATA"`, `"README"`, or `"GEOM"`) of the previously +created bulk report. It defines the `BulkReportFileEndPoint` class, which handles the +construction and execution of API requests, and the parsing of API responses for +Download bulk Report (URL File) API endpoint. + +For detailed information about the Download bulk Report (URL File) API endpoint, +please refer to the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file + +For more details on the Download bulk Report (URL File) data caveats, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/file/endpoints.py b/src/gfwapiclient/resources/bulk_downloads/file/endpoints.py new file mode 100644 index 0000000..cd58a56 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/file/endpoints.py @@ -0,0 +1,64 @@ +"""Global Fishing Watch (GFW) API Python Client - Download bulk Report (URL File) API endpoint.""" + +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.http.endpoints import GetEndPoint +from gfwapiclient.http.models import RequestBody +from gfwapiclient.resources.bulk_downloads.file.models.request import ( + BulkReportFileParams, +) +from gfwapiclient.resources.bulk_downloads.file.models.response import ( + BulkReportFileItem, + BulkReportFileResult, +) + + +__all__ = ["BulkReportFileEndPoint"] + + +class BulkReportFileEndPoint( + GetEndPoint[ + BulkReportFileParams, RequestBody, BulkReportFileItem, BulkReportFileResult + ], +): + """Download bulk Report (URL File) API endpoint. + + This endpoint is used to retrieve signed URL to download file(s) (i.e., `"DATA"`, + `"README"`, or `"GEOM"`) of the previously created bulk report. + + For more details on the Download bulk Report (URL File) API endpoint, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file + + For more details on the Download bulk Report (URL File) data caveats, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + """ + + def __init__( + self, + *, + bulk_report_id: str, + request_params: BulkReportFileParams, + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkReportFileEndPoint`. + + Args: + bulk_report_id (str): + Unique identifier (ID) of the bulk report. + + request_params (BulkReportFileParams): + The request query parameters. + + http_client (HTTPClient): + The HTTP client used to make the API call. + """ + super().__init__( + path=f"bulk-reports/{bulk_report_id}/download-file-url", + request_params=request_params, + result_item_class=BulkReportFileItem, + result_class=BulkReportFileResult, + http_client=http_client, + ) diff --git a/src/gfwapiclient/resources/bulk_downloads/file/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/file/models/__init__.py new file mode 100644 index 0000000..25cdf99 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/file/models/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Download bulk Report (URL File) Models. + +This module defines Pydantic data models used for interacting with the Download bulk +Report (URL File) API endpoint. These models are used to represent request parameters +and response data when obtaining signed URL to download file(s) (i.e., `"DATA"`, +`"README"`, or `"GEOM"`) of the previously created bulk report. + +For detailed information about the Download bulk Report (URL File) API endpoint, +please refer to the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file + +For more details on the Download bulk Report (URL File) data caveats, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/file/models/request.py b/src/gfwapiclient/resources/bulk_downloads/file/models/request.py new file mode 100644 index 0000000..095c89a --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/file/models/request.py @@ -0,0 +1,36 @@ +"""Global Fishing Watch (GFW) API Python Client - Download bulk Report (URL File) Request Models.""" + +from typing import Final, Optional + +from pydantic import Field + +from gfwapiclient.http.models import RequestParams +from gfwapiclient.resources.bulk_downloads.base.models.request import BulkReportFileType + + +__all__ = ["BulkReportFileParams"] + + +BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE: Final[str] = ( + "Get bulk report file download URL request parameters validation failed." +) + + +class BulkReportFileParams(RequestParams): + """Request query parameters for Download bulk Report (URL File) API endpoint. + + Represents request query parameters to obtain signed URL to download the file + (i.e., `"DATA"`, `"README"`, or `"GEOM"`) of the previously created bulk report. + + For more details on the Download bulk Report (URL File) API endpoint supported + request parameters, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-parameters-for-get-requests + + Attributes: + file (Optional[BulkReportFileType]): + Type of bulk report file (i.e., `"DATA"`, `"README"`, or `"GEOM"`). + """ + + file: Optional[BulkReportFileType] = Field(BulkReportFileType.DATA, alias="file") diff --git a/src/gfwapiclient/resources/bulk_downloads/file/models/response.py b/src/gfwapiclient/resources/bulk_downloads/file/models/response.py new file mode 100644 index 0000000..d9b622a --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/file/models/response.py @@ -0,0 +1,60 @@ +"""Global Fishing Watch (GFW) API Python Client - Download bulk Report (URL File) Response Models.""" + +from typing import Optional, Type + +from pydantic import Field + +from gfwapiclient.http.models import Result, ResultItem + + +__all__ = ["BulkReportFileItem", "BulkReportFileResult"] + + +class BulkReportFileItem(ResultItem): + """Result item for the Download bulk Report (URL File) API endpoint. + + Represents signed URL to download the file (i.e., `"DATA"`, `"README"`, + or `"GEOM"`) of the previously created bulk report. + + For more details on the Download bulk Report (URL File) API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-http-response + + Attributes: + url (Optional[str]): + Signed URL to download the file. + """ + + url: Optional[str] = Field(None, alias="url") + + +class BulkReportFileResult(Result[BulkReportFileItem]): + """Result for the Download bulk Report (URL File) API endpoint. + + For more details on the Download bulk Report (URL File) API endpoint supported + response bodies, please refer to the official Global Fishing Watch API + documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-http-response + + Attributes: + _result_item_class (Type[BulkReportFileItem]): + The model used for individual result items. + + _data (BulkReportFileItem): + The bulk report file item returned in the response. + """ + + _result_item_class: Type[BulkReportFileItem] + _data: BulkReportFileItem + + def __init__(self, data: BulkReportFileItem) -> None: + """Initializes a new `BulkReportFileResult`. + + Args: + data (BulkReportFileItem): + The bulk report file download details. + """ + super().__init__(data=data) diff --git a/tests/fixtures/bulk_downloads/bulk_report_file_item.json b/tests/fixtures/bulk_downloads/bulk_report_file_item.json new file mode 100644 index 0000000..80d9b1e --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_file_item.json @@ -0,0 +1,3 @@ +{ + "url": "https://storage.googleapis.com/api-bulk-release-us-central1/adbb9b62-5c08-4142-82e0-b2b575f3e058/data.gz" +} diff --git a/tests/fixtures/bulk_downloads/bulk_report_file_request_params.json b/tests/fixtures/bulk_downloads/bulk_report_file_request_params.json new file mode 100644 index 0000000..fdeb926 --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_file_request_params.json @@ -0,0 +1,3 @@ +{ + "file": "DATA" +} diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py index d258ac9..d188b40 100644 --- a/tests/resources/bulk_downloads/conftest.py +++ b/tests/resources/bulk_downloads/conftest.py @@ -70,3 +70,38 @@ def mock_raw_bulk_report_list_request_params( "bulk_downloads/bulk_report_list_request_params.json" ) return raw_bulk_report_list_request_params + + +@pytest.fixture +def mock_raw_bulk_report_file_request_params( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for mock raw bulk report file request parameters. + + Returns: + Dict[str, Any]: + Raw `BulkReportFileParams` sample data as dictionary. + """ + raw_bulk_report_file_request_params: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_file_request_params.json" + ) + return raw_bulk_report_file_request_params + + +@pytest.fixture +def mock_raw_bulk_report_file_item( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for a mock raw bulk report file item. + + This fixture loads sample JSON data representing a single + `BulkReportFileItem` from a fixture file. + + Returns: + Dict[str, Any]: + Raw `BulkReportFileItem` sample data as a dictionary. + """ + raw_bulk_report_file_item: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_file_item.json" + ) + return raw_bulk_report_file_item diff --git a/tests/resources/bulk_downloads/file/__init__.py b/tests/resources/bulk_downloads/file/__init__.py new file mode 100644 index 0000000..747face --- /dev/null +++ b/tests/resources/bulk_downloads/file/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.file`.""" diff --git a/tests/resources/bulk_downloads/file/models/__init__.py b/tests/resources/bulk_downloads/file/models/__init__.py new file mode 100644 index 0000000..6ece48a --- /dev/null +++ b/tests/resources/bulk_downloads/file/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.file.models`.""" diff --git a/tests/resources/bulk_downloads/file/models/test_request_models.py b/tests/resources/bulk_downloads/file/models/test_request_models.py new file mode 100644 index 0000000..ffd9867 --- /dev/null +++ b/tests/resources/bulk_downloads/file/models/test_request_models.py @@ -0,0 +1,18 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.file.models.request`.""" + +from typing import Any, Dict + +from gfwapiclient.resources.bulk_downloads.file.models.request import ( + BulkReportFileParams, +) + + +def test_bulk_report_file_request_params_serializes_all_fields( + mock_raw_bulk_report_file_request_params: Dict[str, Any], +) -> None: + """Test that `BulkReportFileParams` serializes all fields correctly.""" + bulk_report_file_request_params: BulkReportFileParams = BulkReportFileParams( + **mock_raw_bulk_report_file_request_params + ) + assert bulk_report_file_request_params.file is not None + assert bulk_report_file_request_params.to_query_params() is not None diff --git a/tests/resources/bulk_downloads/file/models/test_response_models.py b/tests/resources/bulk_downloads/file/models/test_response_models.py new file mode 100644 index 0000000..654a774 --- /dev/null +++ b/tests/resources/bulk_downloads/file/models/test_response_models.py @@ -0,0 +1,27 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.file.models.response`.""" + +from typing import Any, Dict, cast + +from gfwapiclient.resources.bulk_downloads.file.models.response import ( + BulkReportFileItem, + BulkReportFileResult, +) + + +def test_bulk_report_detail_item_deserializes_all_fields( + mock_raw_bulk_report_file_item: Dict[str, Any], +) -> None: + """Test that `BulkReportFileItem` deserializes all fields correctly.""" + bulk_report_file_item: BulkReportFileItem = BulkReportFileItem( + **mock_raw_bulk_report_file_item + ) + assert bulk_report_file_item.url is not None + + +def test_bulk_report_detail_result_deserializes_all_fields( + mock_raw_bulk_report_file_item: Dict[str, Any], +) -> None: + """Test that `BulkReportFileResult` deserializes all fields correctly.""" + data: BulkReportFileItem = BulkReportFileItem(**mock_raw_bulk_report_file_item) + result = BulkReportFileResult(data=data) + assert cast(BulkReportFileItem, result.data()) == data diff --git a/tests/resources/bulk_downloads/file/test_endpoints.py b/tests/resources/bulk_downloads/file/test_endpoints.py new file mode 100644 index 0000000..a1836da --- /dev/null +++ b/tests/resources/bulk_downloads/file/test_endpoints.py @@ -0,0 +1,72 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.file.endpoints`.""" + +from typing import Any, Dict, Final, cast + +import httpx +import pytest +import respx + +from gfwapiclient.exceptions.base import GFWAPIClientError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.file.endpoints import ( + BulkReportFileEndPoint, +) +from gfwapiclient.resources.bulk_downloads.file.models.request import ( + BulkReportFileParams, +) +from gfwapiclient.resources.bulk_downloads.file.models.response import ( + BulkReportFileItem, + BulkReportFileResult, +) + + +bulk_report_id: Final[str] = "adbb9b62-5c08-4142-82e0-b2b575f3e058" + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_file_endpoint_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_file_request_params: Dict[str, Any], + mock_raw_bulk_report_file_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportFileEndPoint` request succeeds with a valid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/download-file-url").respond( + 200, json=mock_raw_bulk_report_file_item + ) + request_params: BulkReportFileParams = BulkReportFileParams( + **mock_raw_bulk_report_file_request_params + ) + endpoint: BulkReportFileEndPoint = BulkReportFileEndPoint( + bulk_report_id=bulk_report_id, + request_params=request_params, + http_client=mock_http_client, + ) + result: BulkReportFileResult = await endpoint.request() + data = cast(BulkReportFileItem, result.data()) + assert isinstance(result, BulkReportFileResult) + assert isinstance(data, BulkReportFileItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_report_file_endpoint_request_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_file_request_params: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkReportFileEndPoint` request fails with an invalid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/download-file-url").mock( + return_value=httpx.Response(status_code=400, json={"error": "Bad Request"}) + ) + request_params: BulkReportFileParams = BulkReportFileParams( + **mock_raw_bulk_report_file_request_params + ) + endpoint: BulkReportFileEndPoint = BulkReportFileEndPoint( + bulk_report_id=bulk_report_id, + request_params=request_params, + http_client=mock_http_client, + ) + with pytest.raises(GFWAPIClientError): + await endpoint.request() From b805062a020b169fc5932d95671151b658cf60f6 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Wed, 26 Nov 2025 19:00:04 +0300 Subject: [PATCH 09/22] feat(bulk-downloads): implement bulk report API endpoints This: - implement `BulkDownloadResource` class for high-level API interaction - implement `create_bulk_report` API endpoint - implement `get_bulk_report_by_id` API endpoint - implement `get_all_bulk_reports` API endpoint - implement `get_bulk_report_file_download_url` API endpoint --- README.md | 2 + src/gfwapiclient/__init__.py | 51 ++- src/gfwapiclient/client/client.py | 25 + src/gfwapiclient/resources/__init__.py | 2 + .../resources/bulk_downloads/__init__.py | 5 + .../resources/bulk_downloads/resources.py | 433 ++++++++++++++++++ tests/client/test_client.py | 12 + tests/resources/bulk_downloads/conftest.py | 1 + .../bulk_downloads/detail/test_endpoints.py | 5 +- .../bulk_downloads/file/test_endpoints.py | 5 +- .../bulk_downloads/test_resources.py | 176 +++++++ 11 files changed, 699 insertions(+), 18 deletions(-) create mode 100644 src/gfwapiclient/resources/bulk_downloads/resources.py create mode 100644 tests/resources/bulk_downloads/test_resources.py diff --git a/README.md b/README.md index 828158a..342a448 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ The Global Fishing Watch Python package currently works with the following APIs: - [Datasets API](https://globalfishingwatch.org/our-apis/documentation#datasets-api): Retrieve fixed offshore infrastructure detections (e.g., oil platforms, wind farms) from Sentinel-1 and Sentinel-2 satellite imagery, from 2017 up to 3 months ago, classified using deep learning. +- [Bulk Download API](https://globalfishingwatch.org/our-apis/documentation#bulk-download-api): Efficiently access and download large-scale datasets to integrate with big data platforms and tools used by data engineers and researchers. Unlike our other APIs ([Map Visualization (4Wings API)](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), [Datasets API](https://globalfishingwatch.org/our-apis/documentation#datasets-api) etc.), these datasets may include some **noisy** that are not filtered out. + - [References API](https://globalfishingwatch.org/our-apis/documentation#regions): Access metadata for EEZs, MPAs, and RFMOs to use in [Events API](https://globalfishingwatch.org/our-apis/documentation#events-api) and [Map Visualization (4Wings API)](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) requests and analyses. > **Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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. diff --git a/src/gfwapiclient/__init__.py b/src/gfwapiclient/__init__.py index 5fe6bb9..31e66e3 100644 --- a/src/gfwapiclient/__init__.py +++ b/src/gfwapiclient/__init__.py @@ -1,25 +1,52 @@ """Global Fishing Watch (GFW) API Python Client. -This package provides a Python client for interacting with the Global Fishing Watch (GFW) API, -specifically `version 3 `_. -It enables access to publicly available API resources, and facilitating the retrieval of the data. +This package provides a Python client for interacting with the Global Fishing Watch +(GFW) API version 3. -Features: +See: https://globalfishingwatch.org/our-apis/documentation#version-3-api -- **4Wings**: Access AIS apparent fishing effort, AIS vessel presence, and SAR vessel detections between 2017 to ~5 days ago. +See: https://globalfishingwatch.org/our-apis/documentation#in-api-version-3 -- **Vessels**: Search and retrieve vessel identity based on AIS self-reported data, combined with authorization and registry data from regional and national registries. +It enables access to publicly available API resources, and facilitating the retrieval +of the following APIs data: -- **Events**: Retrieve vessel activity events such as encounters, loitering, port visits, fishing events, and AIS off (aka GAPs). +- **Map Visualization (4Wings API)**: Access AIS apparent fishing effort, +AIS vessel presence, and SAR vessel detections between 2017 to ~5 days ago. -- **Insights**: Access vessel insights that combine AIS activity, vessel identity, and public authorizations. Designed to support risk-based decision-making, operational planning, and due diligence—particularly for assessing risks of IUU (Illegal, Unreported, or Unregulated) fishing. +- **Vessels API**: Search and retrieve vessel identity based on AIS self-reported data, +combined with authorization and registry data from regional and national registries. -- **Datasets**: Retrieve fixed offshore infrastructure detections (e.g., oil platforms, wind farms) from Sentinel-1 and Sentinel-2 satellite imagery, from 2017 up to 3 months ago, classified using deep learning. +- **Events API**: Retrieve vessel activity events such as encounters, loitering, port +visits, fishing events, and AIS off (aka GAPs). -- **References**: Access metadata for EEZs, MPAs, and RFMOs to use in `Events API `_ and `Map Visualization (4Wings API) `_ requests and analyses. +- **Insights API**: Access vessel insights that combine AIS activity, vessel identity, +and public authorizations. Designed to support risk-based decision-making, operational +planning, and due diligence—particularly for assessing risks of +IUU (Illegal, Unreported, or Unregulated) fishing. -For comprehensive details, please refer to the official -`Global Fishing Watch API Documentation `_. +- **Datasets API**: Retrieve fixed offshore infrastructure detections (e.g., +oil platforms, wind farms etc.) from Sentinel-1 and Sentinel-2 satellite imagery, +from 2017 up to 3 months ago, classified using deep learning. + +- **Bulk Download API**: Efficiently access and download large-scale datasets to +integrate with big data platforms and tools used by data engineers and researchers. +Unlike our other APIs (4Wings API, Datasets API, etc.), these datasets may include +some **noisy** that are not filtered out. + +- **References**: Access metadata for EEZs, MPAs, and RFMOs to use in Events API and +4Wings API requests and analyses. + +For more details on the data, API licenses, and rate limits, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#introduction + +For more details on the data caveats and terms of use, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#data-caveat + +See: https://globalfishingwatch.org/our-apis/documentation#terms-of-use """ from gfwapiclient.__version__ import __version__ diff --git a/src/gfwapiclient/client/client.py b/src/gfwapiclient/client/client.py index 68bef6a..270de6e 100644 --- a/src/gfwapiclient/client/client.py +++ b/src/gfwapiclient/client/client.py @@ -8,6 +8,7 @@ from gfwapiclient.http import HTTPClient from gfwapiclient.resources import ( + BulkDownloadResource, DatasetResource, EventResource, FourWingsResource, @@ -55,6 +56,9 @@ class Client: datasets (DatasetResource): Access to the datasets data resources. + bulk_downloads (BulkDownloadResource): + Access to the Bulk download API resources. + references (ReferenceResource): Access to the reference data resources. """ @@ -64,6 +68,7 @@ class Client: _events: EventResource _insights: InsightResource _datasets: DatasetResource + _bulk_downloads: BulkDownloadResource _references: ReferenceResource def __init__( @@ -245,6 +250,26 @@ def datasets(self) -> DatasetResource: self._datasets = DatasetResource(http_client=self._http_client) return self._datasets + @property + def bulk_downloads(self) -> BulkDownloadResource: + """Bulk download API resource. + + Provides access to the Bulk Download API resources, which allow to + efficiently create, retrieve, and download bulk reports data and files. + + For more details on the Bulk Download API, please refer to the official + Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-download-api + + Returns: + BulkDownloadResource: + The bulk download resource instance. + """ + if not hasattr(self, "_bulk_downloads"): + self._bulk_downloads = BulkDownloadResource(http_client=self._http_client) + return self._bulk_downloads + @property def references(self) -> ReferenceResource: """References data API resource. diff --git a/src/gfwapiclient/resources/__init__.py b/src/gfwapiclient/resources/__init__.py index a41b12b..b1aaad8 100644 --- a/src/gfwapiclient/resources/__init__.py +++ b/src/gfwapiclient/resources/__init__.py @@ -1,5 +1,6 @@ """Global Fishing Watch (GFW) API Python Client - Resources.""" +from gfwapiclient.resources.bulk_downloads import BulkDownloadResource from gfwapiclient.resources.datasets import DatasetResource from gfwapiclient.resources.events import EventResource from gfwapiclient.resources.fourwings import FourWingsResource @@ -9,6 +10,7 @@ __all__ = [ + "BulkDownloadResource", "DatasetResource", "EventResource", "FourWingsResource", diff --git a/src/gfwapiclient/resources/bulk_downloads/__init__.py b/src/gfwapiclient/resources/bulk_downloads/__init__.py index e47cf7b..da5c6cf 100644 --- a/src/gfwapiclient/resources/bulk_downloads/__init__.py +++ b/src/gfwapiclient/resources/bulk_downloads/__init__.py @@ -19,3 +19,8 @@ See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats """ + +from gfwapiclient.resources.bulk_downloads.resources import BulkDownloadResource + + +__all__ = ["BulkDownloadResource"] diff --git a/src/gfwapiclient/resources/bulk_downloads/resources.py b/src/gfwapiclient/resources/bulk_downloads/resources.py new file mode 100644 index 0000000..0bff5d5 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/resources.py @@ -0,0 +1,433 @@ +"""Global Fishing Watch (GFW) API Python Client - Bulk Download API Resource.""" + +from typing import Any, Dict, List, Optional, Union + +import pydantic + +from gfwapiclient.exceptions import ( + RequestBodyValidationError, + RequestParamsValidationError, +) +from gfwapiclient.http.resources import BaseResource +from gfwapiclient.resources.bulk_downloads.base.models.request import ( + BulkReportDataset, + BulkReportFileType, + BulkReportFormat, + BulkReportGeometry, + BulkReportRegion, +) +from gfwapiclient.resources.bulk_downloads.base.models.response import BulkReportStatus +from gfwapiclient.resources.bulk_downloads.create.endpoints import ( + BulkReportCreateEndPoint, +) +from gfwapiclient.resources.bulk_downloads.create.models.request import ( + BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE, + BulkReportCreateBody, +) +from gfwapiclient.resources.bulk_downloads.create.models.response import ( + BulkReportCreateResult, +) +from gfwapiclient.resources.bulk_downloads.detail.endpoints import ( + BulkReportDetailEndPoint, +) +from gfwapiclient.resources.bulk_downloads.detail.models.response import ( + BulkReportDetailResult, +) +from gfwapiclient.resources.bulk_downloads.file.endpoints import BulkReportFileEndPoint +from gfwapiclient.resources.bulk_downloads.file.models.request import ( + BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE, + BulkReportFileParams, +) +from gfwapiclient.resources.bulk_downloads.file.models.response import ( + BulkReportFileResult, +) +from gfwapiclient.resources.bulk_downloads.list.endpoints import BulkReportListEndPoint +from gfwapiclient.resources.bulk_downloads.list.models.request import ( + BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE, + BulkReportListParams, +) +from gfwapiclient.resources.bulk_downloads.list.models.response import ( + BulkReportListResult, +) + + +__all__ = ["BulkDownloadResource"] + + +class BulkDownloadResource(BaseResource): + """Bulk download API resource. + + This resource provides methods to interact with the Bulk Download API, + specifically to: + + - Create bulk reports based on specific filters and spatial parameters. + - Monitor previously created bulk report generation status. + - Get signed URL to download previously created bulk report data, metadata and + region geometry (in GeoJSON format) files. + - Query previously created bulk report data records in JSON format. + + For detailed information about the Bulk Download API, please refer to the official + Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#bulk-download-api + + For more details on the Bulk Download API data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + """ + + async def create_bulk_report( + self, + *, + name: str, + dataset: Optional[Union[BulkReportDataset, str]] = None, + geojson: Optional[Union[BulkReportGeometry, Dict[str, Any]]] = None, + format: Optional[Union[BulkReportFormat, str]] = None, + region: Optional[Union[BulkReportRegion, Dict[str, Any]]] = None, + filters: Optional[List[str]] = None, + **kwargs: Dict[str, Any], + ) -> BulkReportCreateResult: + """Create a bulk report based on specified filters and spatial parameters. + + For detailed information about the Create a Bulk Report API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report + + For more details on the Create a Bulk Report data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + + **Disclaimer:** + + Depending on the complexity and size of your request (e.g., large geojson or region, + long date range etc), generating the bulk report can take several minutes to + several hours. + + Attributes: + name (str): + Human-readable name of the bulk report. + Example: `"sar-fixed-infrastructure-data-20240903"`. + + dataset (Optional[Union[BulkReportDataset, str]], default="public-fixed-infrastructure-data:latest"): + Dataset that will be used to create the bulk report. + Defaults to `"public-fixed-infrastructure-data:latest"`. + Allowed values: `"public-fixed-infrastructure-data:latest"`. + Example: `"public-fixed-infrastructure-data:latest"`. + + geojson (Optional[Union[BulkReportGeometry, Dict[str, Any]]], default=None): + Custom GeoJSON geometry to filter the bulk report. Defaults to `None`. + Example: `{"type": "Polygon", "coordinates": [...]}`. + + format (Optional[Union[BulkReportFormat, str]], default="JSON"): + Bulk report result format. Defaults to `"JSON"`. + Allowed values: `"JSON"`, `"CSV"`. + Example: `"JSON"`. + + region (Optional[Union[BulkReportRegion, Dict[str, Any]]], default=None): + Predefined region information to filter the bulk report. + Defaults to `None`. + Example: `{"dataset": "public-eez-areas", "id": 8466}`. + + filters (Optional[List[str]], default=None): + Filters to apply when generating the bulk report. Default to `None`. + Example: `["label = 'oil'"]` + + **kwargs (Dict[str, Any]): + Additional keyword arguments. + + Returns: + BulkReportCreateResult: + The created bulk report metadata and status. + + Raises: + GFWAPIClientError: + If the API request fails. + + RequestBodyValidationError: + If the request body is invalid. + """ + request_body: BulkReportCreateBody = ( + self._prepare_create_bulk_report_request_body( + name=name, + dataset=dataset, + geojson=geojson, + format=format, + region=region, + filters=filters, + ) + ) + + endpoint: BulkReportCreateEndPoint = BulkReportCreateEndPoint( + request_body=request_body, + http_client=self._http_client, + ) + + result: BulkReportCreateResult = await endpoint.request() + return result + + async def get_bulk_report_by_id( + self, + *, + id: str, + **kwargs: Dict[ + str, Any + ], # TODO: polling logics (throttled retry based on status) + ) -> BulkReportDetailResult: + """Get a bulk report by ID. + + Retrieves metadata and status of the previously created bulk report based on the + provided bulk report ID. + + For more details on the Get Bulk Report by ID API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id + + For more details on the Get Bulk Report by ID data caveats, please refer + to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + + **Important:** + + We recommend to use this method to poll the status of previously created + bulk report, if it takes several minutes or hours to generate until it status + is `"done"` or `"failed"`. + + Args: + id (str): + Unique identifier (ID) of the bulk report. + Example: `"adbb9b62-5c08-4142-82e0-b2b575f3e058"` + + **kwargs (Dict[str, Any]): + Additional keyword arguments. + + Returns: + BulkReportDetailResult: + The previously created bulk report metadata and status. + + Raises: + GFWAPIClientError: + If the API request fails. + """ + endpoint: BulkReportDetailEndPoint = BulkReportDetailEndPoint( + bulk_report_id=id, http_client=self._http_client + ) + + result: BulkReportDetailResult = await endpoint.request() + return result + + async def get_all_bulk_reports( + self, + *, + limit: Optional[int] = None, + offset: Optional[int] = None, + sort: Optional[str] = None, + status: Optional[Union[BulkReportStatus, str]] = None, + **kwargs: Dict[str, Any], + ) -> BulkReportListResult: + """Get all bulk reports created by user or application. + + Retrieves a list of metadata and status of the previously created + bulk reports based on specified pagination, sorting, and filtering criteria. + + For detailed information about the Get All Bulk Reports API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user + + For more details on the Get All Bulk Reports data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + + Args: + limit (Optional[int], default=99999): + Maximum number of bulk reports to return. Defaults to `99999`. + Example: `99999`. + + offset (Optional[int], default=0): + Number of bulk reports to skip before returning results. + Defaults to `0`. + Example: `0`. + + sort (Optional[str], default="-createdAt"): + Property to sort the bulk reports by. Defaults to `"-createdAt"`. + Example: `"-createdAt"`. + + status (Optional[Union[BulkReportStatus, str]], default=None): + Current status of the bulk report generation process. + Defaults to `None`. + Allowed values: `"pending"`, `"processing"`, `"done"`, `"failed"`. + Example: `"done"`. + + **kwargs (Dict[str, Any]): + Additional keyword arguments. + + Returns: + BulkReportListResult: + The result containing the list of previously created bulk report + metadata and status. + + Raises: + GFWAPIClientError: + If the API request fails. + + RequestParamsValidationError: + If the request parameters are invalid. + """ + request_params: BulkReportListParams = self._prepare_get_all_bulk_report_params( + limit=limit, + offset=offset, + sort=sort, + status=status, + ) + + endpoint: BulkReportListEndPoint = BulkReportListEndPoint( + request_params=request_params, + http_client=self._http_client, + ) + + result: BulkReportListResult = await endpoint.request() + return result + + async def get_bulk_report_file_download_url( + self, + *, + id: str, + file: Optional[Union[BulkReportFileType, str]] = None, + **kwargs: Dict[str, Any], + ) -> BulkReportFileResult: + """Get signed URL to download file of the previously created bulk report. + + Retrieves signed URL that points to a downloadable file hosted on Global Fishing + Watch's cloud infrastructure to download file(s) (i.e., `"DATA"`, `"README"`, or + `"GEOM"`) of the previously created bulk report. + + For more details on the Download bulk Report (URL File) API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file + + For more details on the Download bulk Report (URL File) data caveats, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + + Args: + id (str): + Unique identifier (ID) of the bulk report. + Example: `"adbb9b62-5c08-4142-82e0-b2b575f3e058"`. + + file (Optional[Union[BulkReportFileType, str]], default="DATA"): + Type of bulk report file. Defaults to `"DATA"`. + Allowed values: `"DATA"`, `"README"`, `"GEOM"`. + Example: `"DATA"` + + **kwargs (Dict[str, Any]): + Additional keyword arguments. + + Returns: + BulkReportFileResult: + The signed URL to download bulk report file. + + Raises: + GFWAPIClientError: + If the API request fails. + + RequestParamsValidationError: + If the request parameters are invalid. + """ + request_params: BulkReportFileParams = ( + self._prepare_get_bulk_report_file_download_url_params(file=file) + ) + + endpoint: BulkReportFileEndPoint = BulkReportFileEndPoint( + bulk_report_id=id, + request_params=request_params, + http_client=self._http_client, + ) + + result: BulkReportFileResult = await endpoint.request() + return result + + def _prepare_create_bulk_report_request_body( + self, + *, + name: str, + dataset: Optional[Union[BulkReportDataset, str]] = None, + geojson: Optional[Union[BulkReportGeometry, Dict[str, Any]]] = None, + format: Optional[Union[BulkReportFormat, str]] = None, + region: Optional[Union[BulkReportRegion, Dict[str, Any]]] = None, + filters: Optional[List[str]] = None, + ) -> BulkReportCreateBody: + """Prepare and return create a bulk report request body.""" + try: + _dataset: Union[BulkReportDataset, str] = ( + dataset or BulkReportDataset.FIXED_INFRASTRUCTURE_DATA_LATEST + ) + _request_body: Dict[str, Any] = { + "name": name, # TODO: generate based on dataset name and timestamp (YYYMMDDHHmmss) / uuidv4 + "dataset": _dataset, + "geojson": geojson or None, + "format": format or BulkReportFormat.JSON, + "region": region or None, + "filters": filters or None, + } + request_body: BulkReportCreateBody = BulkReportCreateBody(**_request_body) + except pydantic.ValidationError as exc: + raise RequestBodyValidationError( + message=BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE, + error=exc, + ) from exc + + return request_body + + def _prepare_get_all_bulk_report_params( + self, + *, + limit: Optional[int] = None, + offset: Optional[int] = None, + sort: Optional[str] = None, + status: Optional[Union[BulkReportStatus, str]] = None, + ) -> BulkReportListParams: + """Prepare and return get all bulk report request parameters.""" + try: + _request_params: Dict[str, Any] = { + "limit": limit or 99999, + "offset": offset or 0, + "sort": sort or "-createdAt", + "status": status or None, + } + request_params: BulkReportListParams = BulkReportListParams( + **_request_params + ) + except pydantic.ValidationError as exc: + raise RequestParamsValidationError( + message=BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE, + error=exc, + ) from exc + + return request_params + + def _prepare_get_bulk_report_file_download_url_params( + self, *, file: Optional[Union[BulkReportFileType, str]] = None + ) -> BulkReportFileParams: + """Prepare and return get bulk report file download url request parameters.""" + try: + _request_params: Dict[str, Any] = { + "file": file or BulkReportFileType.DATA, + } + request_params: BulkReportFileParams = BulkReportFileParams( + **_request_params + ) + except pydantic.ValidationError as exc: + raise RequestParamsValidationError( + message=BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE, + error=exc, + ) from exc + + return request_params diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 46f9f41..05b40c9 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -6,6 +6,7 @@ from gfwapiclient.client.client import GFW_API_BASE_URL, Client from gfwapiclient.exceptions.client import AccessTokenError from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.resources import BulkDownloadResource from gfwapiclient.resources.datasets.resources import DatasetResource from gfwapiclient.resources.events.resources import EventResource from gfwapiclient.resources.fourwings.resources import FourWingsResource @@ -145,6 +146,17 @@ def test_client_datasets_property_returns_dataset_resource_and_is_cached( assert client.datasets is client.datasets +def test_client_bulk_downloads_property_returns_bulk_download_resource_and_is_cached( + mock_base_url: str, + mock_access_token: str, +) -> None: + """Test `Client.bulk_downloads` returns `BulkDownloadResource` and caches the instance.""" + client = Client() + assert isinstance(client.bulk_downloads, BulkDownloadResource) + # Test that the property is cached + assert client.bulk_downloads is client.bulk_downloads + + def test_client_references_property_returns_reference_resource_and_is_cached( mock_base_url: str, mock_access_token: str, diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py index d188b40..fe41b74 100644 --- a/tests/resources/bulk_downloads/conftest.py +++ b/tests/resources/bulk_downloads/conftest.py @@ -5,6 +5,7 @@ import pytest +bulk_report_id: Final[str] = "adbb9b62-5c08-4142-82e0-b2b575f3e058" region_dataset: Final[str] = "public-eez-areas" region_id: Final[int] = 8466 geometry: Final[Dict[str, Any]] = { diff --git a/tests/resources/bulk_downloads/detail/test_endpoints.py b/tests/resources/bulk_downloads/detail/test_endpoints.py index 3d4969b..13798b5 100644 --- a/tests/resources/bulk_downloads/detail/test_endpoints.py +++ b/tests/resources/bulk_downloads/detail/test_endpoints.py @@ -1,6 +1,6 @@ """Tests for `gfwapiclient.resources.bulk_downloads.detail.endpoints`.""" -from typing import Any, Dict, Final, cast +from typing import Any, Dict, cast import httpx import pytest @@ -16,8 +16,7 @@ BulkReportDetailResult, ) - -bulk_report_id: Final[str] = "adbb9b62-5c08-4142-82e0-b2b575f3e058" +from ..conftest import bulk_report_id @pytest.mark.asyncio diff --git a/tests/resources/bulk_downloads/file/test_endpoints.py b/tests/resources/bulk_downloads/file/test_endpoints.py index a1836da..49ab6d4 100644 --- a/tests/resources/bulk_downloads/file/test_endpoints.py +++ b/tests/resources/bulk_downloads/file/test_endpoints.py @@ -1,6 +1,6 @@ """Tests for `gfwapiclient.resources.bulk_downloads.file.endpoints`.""" -from typing import Any, Dict, Final, cast +from typing import Any, Dict, cast import httpx import pytest @@ -19,8 +19,7 @@ BulkReportFileResult, ) - -bulk_report_id: Final[str] = "adbb9b62-5c08-4142-82e0-b2b575f3e058" +from ..conftest import bulk_report_id @pytest.mark.asyncio diff --git a/tests/resources/bulk_downloads/test_resources.py b/tests/resources/bulk_downloads/test_resources.py new file mode 100644 index 0000000..3b7e391 --- /dev/null +++ b/tests/resources/bulk_downloads/test_resources.py @@ -0,0 +1,176 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.resources`.""" + +from typing import Any, Dict, List, cast + +import pytest +import respx + +from gfwapiclient.exceptions.validation import ( + RequestBodyValidationError, + RequestParamsValidationError, +) +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.create.models.request import ( + BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE, +) +from gfwapiclient.resources.bulk_downloads.create.models.response import ( + BulkReportCreateItem, + BulkReportCreateResult, +) +from gfwapiclient.resources.bulk_downloads.detail.models.response import ( + BulkReportDetailItem, + BulkReportDetailResult, +) +from gfwapiclient.resources.bulk_downloads.file.models.request import ( + BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE, +) +from gfwapiclient.resources.bulk_downloads.file.models.response import ( + BulkReportFileItem, + BulkReportFileResult, +) +from gfwapiclient.resources.bulk_downloads.list.models.request import ( + BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE, +) +from gfwapiclient.resources.bulk_downloads.list.models.response import ( + BulkReportListItem, + BulkReportListResult, +) +from gfwapiclient.resources.bulk_downloads.resources import BulkDownloadResource + +from .conftest import bulk_report_id + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_download_resource_create_bulk_report_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_create_request_body: Dict[str, Any], + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkDownloadResource`create bulk report succeeds with a valid response.""" + mock_responsex.post("/bulk-reports").respond(201, json=mock_raw_bulk_report_item) + resource = BulkDownloadResource(http_client=mock_http_client) + + result: BulkReportCreateResult = await resource.create_bulk_report( + **mock_raw_bulk_report_create_request_body + ) + data = cast(BulkReportCreateItem, result.data()) + assert isinstance(result, BulkReportCreateResult) + assert isinstance(data, BulkReportCreateItem) + + +@pytest.mark.asyncio +async def test_bulk_download_resource_create_bulk_report_request_body_validation_error_raises( + mock_http_client: HTTPClient, + mock_raw_bulk_report_create_request_body: Dict[str, Any], +) -> None: + """Test `BulkDownloadResource`create bulk report raises `RequestBodyValidationError` with invalid bodies.""" + resource = BulkDownloadResource(http_client=mock_http_client) + + with pytest.raises( + RequestBodyValidationError, + match=BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE, + ): + await resource.create_bulk_report( + **{ + **mock_raw_bulk_report_create_request_body, + "dataset": "INVALID_DATASET", + } + ) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_download_resource_get_bulk_report_by_id_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkDownloadResource` get bulk report by ID succeeds with a valid response.""" + mock_responsex.get(f"/bulk-reports/{bulk_report_id}").respond( + 200, json=mock_raw_bulk_report_item + ) + resource = BulkDownloadResource(http_client=mock_http_client) + + result: BulkReportDetailResult = await resource.get_bulk_report_by_id( + id=bulk_report_id, + ) + data = cast(BulkReportDetailItem, result.data()) + assert isinstance(result, BulkReportDetailResult) + assert isinstance(data, BulkReportDetailItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_download_resource_get_all_bulk_reports_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_list_request_params: Dict[str, Any], + mock_raw_bulk_report_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkDownloadResource` get all bulk reports succeeds with a valid response.""" + mock_responsex.get("/bulk-reports").respond( + 200, json={"entries": [mock_raw_bulk_report_item, {}]} + ) + resource = BulkDownloadResource(http_client=mock_http_client) + result: BulkReportListResult = await resource.get_all_bulk_reports( + **mock_raw_bulk_report_list_request_params + ) + data = cast(List[BulkReportListItem], result.data()) + assert isinstance(result, BulkReportListResult) + assert isinstance(data[0], BulkReportListItem) + + +@pytest.mark.asyncio +async def test_bulk_download_resource_get_all_bulk_reports_request_params_validation_error_raises( + mock_http_client: HTTPClient, +) -> None: + """Test `BulkDownloadResource` get all bulk reports raises `RequestParamsValidationError` with invalid parameters.""" + resource = BulkDownloadResource(http_client=mock_http_client) + + with pytest.raises( + RequestParamsValidationError, + match=BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE, + ): + await resource.get_all_bulk_reports(limit=-1, offset=-1) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_download_resource_get_bulk_report_file_download_url_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_file_request_params: Dict[str, Any], + mock_raw_bulk_report_file_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkDownloadResource` get bulk report file download url succeeds with a valid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/download-file-url").respond( + 200, json=mock_raw_bulk_report_file_item + ) + resource = BulkDownloadResource(http_client=mock_http_client) + result: BulkReportFileResult = await resource.get_bulk_report_file_download_url( + **{ + **mock_raw_bulk_report_file_request_params, + "id": bulk_report_id, + } + ) + data = cast(BulkReportFileItem, result.data()) + assert isinstance(result, BulkReportFileResult) + assert isinstance(data, BulkReportFileItem) + + +@pytest.mark.asyncio +async def test_bulk_download_resource_get_bulk_report_file_download_url_request_params_validation_error_raises( + mock_http_client: HTTPClient, +) -> None: + """Test `BulkDownloadResource` get bulk report file download url raises `RequestParamsValidationError` with invalid parameters.""" + resource = BulkDownloadResource(http_client=mock_http_client) + + with pytest.raises( + RequestParamsValidationError, + match=BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE, + ): + await resource.get_bulk_report_file_download_url( + id=bulk_report_id, file="INVALID_FILE_TYPE" + ) From a8826ecf9a767645f59431e4fc9a59f72d5fda27 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 9 Dec 2025 01:33:08 +0300 Subject: [PATCH 10/22] feat(bulk-downloads): implement bulk report query API endpoints and models This: - add `BulkReportQueryEndPoint`, an endpoint class for handling specific bulk report query requests - add `BulkReportQueryParams` for serializing and validating request parameters - add `BulkReportQueryItem` and `BulkReportQueryResult` for deserializing and validating API responses - add `BulkFixedInfrastructureDataQueryEndPoint` for handling fixed infrastructure bulk report query requests - add `fixtures` and `unit tests` for `BulkReportQueryParams`, and `BulkFixedInfrastructureDataQueryEndPoint` --- .../bulk_downloads/query/__init__.py | 18 ++ .../bulk_downloads/query/endpoints.py | 169 ++++++++++++++++++ .../bulk_downloads/query/models/__init__.py | 17 ++ .../query/models/base/__init__.py | 16 ++ .../query/models/base/request.py | 51 ++++++ .../query/models/base/response.py | 66 +++++++ .../fixed_infrastructure_data/__init__.py | 17 ++ .../fixed_infrastructure_data/response.py | 133 ++++++++++++++ .../resources/bulk_downloads/resources.py | 124 +++++++++++++ ..._fixed_infrastructure_data_query_item.json | 11 ++ .../bulk_report_query_request_params.json | 12 ++ tests/resources/bulk_downloads/conftest.py | 35 ++++ .../bulk_downloads/query/__init__.py | 1 + .../bulk_downloads/query/models/__init__.py | 1 + .../query/models/base/__init__.py | 1 + .../query/models/base/test_request_models.py | 21 +++ .../fixed_infrastructure_data/__init__.py | 1 + .../test_response_models.py | 65 +++++++ .../bulk_downloads/query/test_endpoints.py | 104 +++++++++++ .../bulk_downloads/test_resources.py | 49 +++++ 20 files changed, 912 insertions(+) create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/endpoints.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/base/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/base/request.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/base/response.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py create mode 100644 src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py create mode 100644 tests/fixtures/bulk_downloads/bulk_fixed_infrastructure_data_query_item.json create mode 100644 tests/fixtures/bulk_downloads/bulk_report_query_request_params.json create mode 100644 tests/resources/bulk_downloads/query/__init__.py create mode 100644 tests/resources/bulk_downloads/query/models/__init__.py create mode 100644 tests/resources/bulk_downloads/query/models/base/__init__.py create mode 100644 tests/resources/bulk_downloads/query/models/base/test_request_models.py create mode 100644 tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py create mode 100644 tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/test_response_models.py create mode 100644 tests/resources/bulk_downloads/query/test_endpoints.py diff --git a/src/gfwapiclient/resources/bulk_downloads/query/__init__.py b/src/gfwapiclient/resources/bulk_downloads/query/__init__.py new file mode 100644 index 0000000..b209bc4 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/__init__.py @@ -0,0 +1,18 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report. + +This module provides the endpoint and associated functionalities for querying +the previously created bulk report structured data in JSON format. +It defines the `BulkReportQueryEndPoint` class, which handles the construction +and execution of API requests and the parsing of API responses for +Query Bulk Report API endpoint. + +For detailed information about the Query Bulk Report API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + +For more details on the Query Bulk Report data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/query/endpoints.py b/src/gfwapiclient/resources/bulk_downloads/query/endpoints.py new file mode 100644 index 0000000..bc08f4f --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/endpoints.py @@ -0,0 +1,169 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report API endpoints.""" + +from typing import Any, Dict, List, Type, Union + +from typing_extensions import override + +from gfwapiclient.exceptions.validation import ResultValidationError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.http.endpoints import GetEndPoint +from gfwapiclient.http.models import RequestBody +from gfwapiclient.resources.bulk_downloads.query.models.base.request import ( + BulkReportQueryParams, +) +from gfwapiclient.resources.bulk_downloads.query.models.base.response import ( + _BulkReportQueryItemT, + _BulkReportQueryResultT, +) +from gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response import ( + BulkFixedInfrastructureDataQueryItem, + BulkFixedInfrastructureDataQueryResult, +) + + +__all__ = ["BulkFixedInfrastructureDataQueryEndPoint", "BulkReportQueryEndPoint"] + + +class BulkReportQueryEndPoint( + GetEndPoint[ + BulkReportQueryParams, + RequestBody, + _BulkReportQueryItemT, + _BulkReportQueryResultT, + ], +): + """Query Bulk Report API endpoint. + + This endpoint query the previously created bulk report data in JSON format + based on the provided request parameters. + + For more details on the Query Bulk Report API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + """ + + def __init__( + self, + *, + bulk_report_id: str, + request_params: BulkReportQueryParams, + result_item_class: Type[_BulkReportQueryItemT], + result_class: Type[_BulkReportQueryResultT], + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkReportQueryEndPoint`. + + Args: + bulk_report_id (str): + Unique identifier (ID) of the bulk report. + + request_params (BulkReportQueryParams): + The request parameters. + + result_item_class (Type[_BulkReportQueryItemT]): + Pydantic model for the expected response item. + + result_class (Type[_BulkReportQueryResultT]): + Pydantic model for the expected response result. + + http_client (HTTPClient): + The HTTP client used to make the API call. + """ + super().__init__( + path=f"bulk-reports/{bulk_report_id}/query", + request_params=request_params, + result_item_class=result_item_class, + result_class=result_class, + http_client=http_client, + ) + + @override + def _transform_response_data( + self, + *, + body: Union[List[Dict[str, Any]], Dict[str, Any]], + ) -> Union[List[Dict[str, Any]], Dict[str, Any]]: + """Transform and reshape response body and yield data. + + This method transforms the raw response body from the API into a format + suitable for the `BulkReportQueryResult` model. + + The expected response structure is: `{"entries": [{...}]}`. + + Args: + body (Union[List[Dict[str, Any]], Dict[str, Any]]): + The raw response body. + + Returns: + Union[List[Dict[str, Any]], Dict[str, Any]]: + The transformed response data. + + Raises: + ResultValidationError: + If the response body does not match the expected format. + """ + # expected: {"entries": [{"key": ...}, ...], ...} + if not isinstance(body, dict) or "entries" not in body: + raise ResultValidationError( + message="Expected a list of entries, but got an empty list.", + body=body, + ) + + # Transforming and reshaping entries + bulk_report_data_entries: List[Dict[str, Any]] = body.get("entries", []) + transformed_data: List[Dict[str, Any]] = [] + + # Loop through "entries" list i.e [{"key": ..., ...}, ...] + for bulk_report_data_entry in bulk_report_data_entries: + # Append extracted dictionaries, if not empty + if bulk_report_data_entry: + transformed_data.append(dict(**bulk_report_data_entry)) + + return transformed_data + + +class BulkFixedInfrastructureDataQueryEndPoint( + BulkReportQueryEndPoint[ + BulkFixedInfrastructureDataQueryItem, + BulkFixedInfrastructureDataQueryResult, + ], +): + """Query Bulk fixed infrastructure data API endpoint. + + This endpoint query the previously created fixed infrastructure data (i.e., + `public-fixed-infrastructure-data:latest` dataset) bulk report data in JSON format + based on the provided request parameters. + + For more details on the Query Bulk Report API endpoint, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + """ + + def __init__( + self, + *, + bulk_report_id: str, + request_params: BulkReportQueryParams, + http_client: HTTPClient, + ) -> None: + """Initializes a new `BulkFixedInfrastructureDataQueryEndPoint`. + + Args: + bulk_report_id (str): + Unique identifier (ID) of the bulk report. + + request_params (BulkReportQueryParams): + The request parameters. + + http_client (HTTPClient): + The HTTP client used to make the API call. + """ + super().__init__( + bulk_report_id=bulk_report_id, + request_params=request_params, + result_item_class=BulkFixedInfrastructureDataQueryItem, + result_class=BulkFixedInfrastructureDataQueryResult, + http_client=http_client, + ) diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/__init__.py b/src/gfwapiclient/resources/bulk_downloads/query/models/__init__.py new file mode 100644 index 0000000..e1d4829 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report Data Models. + +This module defines Pydantic data models used for interacting with the +Query Bulk Report Data API endpoint. These models are used to represent +request parameters, and response data when querying data in JSON format of the +previously created bulk report. + +For detailed information about the Query Bulk Report Data API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + +For more details on the Query Bulk Report Data data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/base/__init__.py b/src/gfwapiclient/resources/bulk_downloads/query/models/base/__init__.py new file mode 100644 index 0000000..2f6f270 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/base/__init__.py @@ -0,0 +1,16 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report Base Models. + +This module defines base Pydantic models used across the Query Bulk Report API +endpoint. These models provide common structures for request parameters, and response +data when querying data in JSON format of the previously created bulk report. + +For detailed information about the Query Bulk Report API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + +For more details on the Query Bulk Report data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/base/request.py b/src/gfwapiclient/resources/bulk_downloads/query/models/base/request.py new file mode 100644 index 0000000..e7e1e26 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/base/request.py @@ -0,0 +1,51 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report Base Request Models.""" + +from typing import ClassVar, Final, List, Optional + +from pydantic import Field + +from gfwapiclient.http.models import RequestParams + + +__all__ = ["BulkReportQueryParams"] + + +BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE: Final[str] = ( + "Query bulk report request parameters validation failed." +) + + +class BulkReportQueryParams(RequestParams): + """Request query parameters for Query Bulk Report API endpoint. + + Represents pagination, sorting, filtering parameters etc. for querying previously + created bulk report data. + + For more details on the Query Bulk Report API endpoint supported request parameters, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + + Attributes: + limit (Optional[int]): + Maximum number of bulk report records to return. + Defaults to `99999`. + + offset (Optional[int]): + Number of bulk report records to skip before returning results. + Used for pagination. Defaults to `0`. + + sort (Optional[str]): + Property to sort the bulk report records by (e.g. + `"-structure_start_date"`). + + includes (Optional[List[str]]): + List of bulk report record fields to include in the result. + """ + + indexed_fields: ClassVar[Optional[List[str]]] = ["includes"] + + limit: Optional[int] = Field(99999, ge=0, alias="limit") + offset: Optional[int] = Field(0, ge=0, alias="offset") + sort: Optional[str] = Field(None, alias="sort") + includes: Optional[List[str]] = Field(None, alias="includes") diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/base/response.py b/src/gfwapiclient/resources/bulk_downloads/query/models/base/response.py new file mode 100644 index 0000000..315e5f8 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/base/response.py @@ -0,0 +1,66 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Report Base Response Models.""" + +from typing import Any, List, Type, TypeVar + +from gfwapiclient.http.models import Result, ResultItem + + +__all__ = [ + "BulkReportQueryItem", + "BulkReportQueryResult", + "_BulkReportQueryItemT", + "_BulkReportQueryResultT", +] + + +class BulkReportQueryItem(ResultItem): + """Result item for the Query Bulk Report API endpoint. + + Represents a data record of a previously created bulk report. + + For more details on the Query Bulk Report API endpoint supported response bodies, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + """ + + pass + + +_BulkReportQueryItemT = TypeVar("_BulkReportQueryItemT", bound=BulkReportQueryItem) + + +class BulkReportQueryResult(Result[_BulkReportQueryItemT]): + """Result for the Query Bulk Report API endpoint. + + Represents data records of a previously created bulk report. + + For more details on the Query Bulk Report API endpoint supported response bodies, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + + Attributes: + _result_item_class (Type[_BulkReportQueryItemT]): + The model used for individual result items. + + _data (List[_BulkReportQueryItemT]): + The bulk report data item returned in the response. + """ + + _result_item_class: Type[_BulkReportQueryItemT] + _data: List[_BulkReportQueryItemT] + + def __init__(self, data: List[_BulkReportQueryItemT]) -> None: + """Initializes a new `BulkReportQueryResult`. + + Args: + data (List[_BulkReportQueryItemT]): + The list of bulk report data items. + """ + super().__init__(data=data) + + +_BulkReportQueryResultT = TypeVar( + "_BulkReportQueryResultT", bound=BulkReportQueryResult[Any] +) diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py new file mode 100644 index 0000000..da5ae6b --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py @@ -0,0 +1,17 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Fixed Infrastructure Data Models. + +This module defines Pydantic data models used for interacting with the Query Bulk +Report API endpoint. These models are used to represent request parameters, and +response data when querying data in JSON format of the previously created +fixed infrastructure data (i.e `public-fixed-infrastructure-data:latest` dataset) bulk report. + +For detailed information about the Query Bulk Report - API endpoint, please refer to +the official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + +For more details on the Query Bulk Report - data caveats, please refer to the +official Global Fishing Watch API documentation: + +See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats +""" diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py new file mode 100644 index 0000000..85318c1 --- /dev/null +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py @@ -0,0 +1,133 @@ +"""Global Fishing Watch (GFW) API Python Client - Query Bulk Fixed Infrastructure Data Response Models.""" + +import datetime + +from typing import Any, List, Optional, Type, Union + +from pydantic import Field, field_validator + +from gfwapiclient.resources.bulk_downloads.query.models.base.response import ( + BulkReportQueryItem, + BulkReportQueryResult, +) + + +__all__ = [ + "BulkFixedInfrastructureDataQueryItem", + "BulkFixedInfrastructureDataQueryResult", +] + + +class BulkFixedInfrastructureDataQueryItem(BulkReportQueryItem): + """Result item for the fixed infrastructure data dataset. + + Represents a data record of a previously created fixed infrastructure data (i.e., + `public-fixed-infrastructure-data:latest` dataset) bulk report. + + For more details on the Query Bulk Report API endpoint supported response bodies, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format-http-response + + Attributes: + detection_id (Optional[str]): + Unique identifier (ID) of the satellite detection (e.g., + `"1AB_AD_MEDIAN_COMP"`). + + detection_date (Optional[datetime.datetime]): + Date of the detection (e.g., `"2021-07-01"`). + + structure_id (Optional[Union[str, int]]): + Unique identifier (ID) for all detections of the same structure (e.g., + `"162013"`). + + lat (Optional[float]): + Latitude of the structure (e.g., `-151.608786096245`). + + lon (Optional[float]): + Longitude of the structure (e.g., `60.8646485096125`). + + structure_start_date (Optional[datetime.datetime]): + The first date the structure was detected (e.g., `"2017-01-01"`). + + structure_end_date (Optional[datetime.datetime]): + The last date the structure was detected (e.g., `"2021-10-01"`). + + label (Optional[str]): + Predicted structure type: `oil`, `wind`, or `unknown` (e.g., `"oil"`). + + label_confidence (Optional[str]): + Label classification confidence level: `high`, `medium`, or `low` (e.g., `"high"`). + """ + + detection_id: Optional[str] = Field(None, alias="detection_id") + detection_date: Optional[datetime.datetime] = Field(None, alias="detection_date") + structure_id: Optional[Union[str, int]] = Field(None, alias="structure_id") + lat: Optional[float] = Field(None, alias="lat") + lon: Optional[float] = Field(None, alias="lon") + structure_start_date: Optional[datetime.datetime] = Field( + None, alias="structure_start_date" + ) + structure_end_date: Optional[datetime.datetime] = Field( + None, alias="structure_end_date" + ) + label: Optional[str] = Field(None, alias="label") + label_confidence: Optional[str] = Field(None, alias="label_confidence") + + @field_validator( + "detection_date", + "structure_start_date", + "structure_end_date", + mode="before", + ) + @classmethod + def empty_datetime_str_to_none(cls, value: Any) -> Optional[Any]: + """Convert any empty datetime string to `None`. + + Args: + value (Any): + The value to validate. + + Returns: + Optional[datetime.datetime]: + The validated datetime object or `None` if input is empty. + """ + if isinstance(value, str) and value.strip() == "": + return None + return value + + +class BulkFixedInfrastructureDataQueryResult( + BulkReportQueryResult[BulkFixedInfrastructureDataQueryItem] +): + """Result for the Query Bulk fixed infrastructure data. + + Represents data records of a previously created fixed infrastructure data (i.e., + `public-fixed-infrastructure-data:latest` dataset) bulk report. + + For more details on the Query Bulk Report API endpoint supported response bodies, + please refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + + Attributes: + _result_item_class (Type[FixedInfrastructureDataItem]): + The model used for individual result items. + + _data (List[FixedInfrastructureDataItem]): + The bulk fixed infrastructure data report items returned in the response. + """ + + _result_item_class: Type[BulkFixedInfrastructureDataQueryItem] + _data: List[BulkFixedInfrastructureDataQueryItem] + + def __init__(self, data: List[BulkFixedInfrastructureDataQueryItem]) -> None: + """Initializes a new `FixedInfrastructureDataResult`. + + Args: + data (List[FixedInfrastructureDataItem]): + The list of bulk fixed infrastructure data report items. + """ + super().__init__(data=data) diff --git a/src/gfwapiclient/resources/bulk_downloads/resources.py b/src/gfwapiclient/resources/bulk_downloads/resources.py index 0bff5d5..c0d093e 100644 --- a/src/gfwapiclient/resources/bulk_downloads/resources.py +++ b/src/gfwapiclient/resources/bulk_downloads/resources.py @@ -49,6 +49,16 @@ from gfwapiclient.resources.bulk_downloads.list.models.response import ( BulkReportListResult, ) +from gfwapiclient.resources.bulk_downloads.query.endpoints import ( + BulkFixedInfrastructureDataQueryEndPoint, +) +from gfwapiclient.resources.bulk_downloads.query.models.base.request import ( + BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE, + BulkReportQueryParams, +) +from gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response import ( + BulkFixedInfrastructureDataQueryResult, +) __all__ = ["BulkDownloadResource"] @@ -354,6 +364,93 @@ async def get_bulk_report_file_download_url( result: BulkReportFileResult = await endpoint.request() return result + async def query_bulk_fixed_infrastructure_data_report( + self, + *, + id: str, + limit: Optional[int] = None, + offset: Optional[int] = None, + sort: Optional[str] = None, + includes: Optional[List[str]] = None, + **kwargs: Dict[str, Any], + ) -> BulkFixedInfrastructureDataQueryResult: + """Get bulk fixed infrastructure data report in JSON Format. + + Retrieves data records of a previously created fixed infrastructure data (i.e., + `public-fixed-infrastructure-data:latest` dataset) bulk report data in JSON format + based on specified pagination, sorting, and including criteria. + + For detailed information about the Query Bulk Report API endpoint, please + refer to the official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format + + For more details on the Query Bulk Report data caveats, please refer to the + official Global Fishing Watch API documentation: + + See: https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats + + Args: + id (str): + Unique identifier (ID) of the bulk report. + Example: `"adbb9b62-5c08-4142-82e0-b2b575f3e058"`. + + limit (Optional[int], default=99999): + Maximum number of bulk report records to return. Defaults to `99999`. + Example: `99999`. + + offset (Optional[int], default=0): + Number of bulk report records to skip before returning results. + Defaults to `0`. + Example: `0`. + + sort (Optional[str], default=None): + Property to sort the bulk report records by. Defaults to `None`. + Allowed fields: `"detection_date"`, `"structure_start_date"`, + `"structure_end_date"`, `"label"`, `"label_confidence"`. Use `-` prefix + for descending order. + Example: `"-structure_start_date"`. + + includes (Optional[List[str]], default=None): + List of bulk report record fields to include in the result. + Defaults to `None`. + Allowed values: `"detection_id"`, `"detection_date"`, `"structure_id"`, + `"lon"`, `"lat"`, `"structure_start_date"`, `"structure_end_date"`, + `"label"`, `"label_confidence"`. + Example: `["structure_id", "lat", "lon", "label", "label_confidence"]`. + + **kwargs (Dict[str, Any]): + Additional keyword arguments. + + Returns: + FixedInfrastructureDataResult: + The result containing the list of bulk fixed infrastructure data report items. + + Raises: + GFWAPIClientError: + If the API request fails. + + RequestParamsValidationError: + If the request parameters are invalid. + """ + request_params: BulkReportQueryParams = self._prepare_query_bulk_report_params( + limit=limit, + offset=offset, + sort=sort, + includes=includes, + ) + + endpoint: BulkFixedInfrastructureDataQueryEndPoint = ( + BulkFixedInfrastructureDataQueryEndPoint( + bulk_report_id=id, + request_params=request_params, + http_client=self._http_client, + ) + ) + + result: BulkFixedInfrastructureDataQueryResult = await endpoint.request() + return result + def _prepare_create_bulk_report_request_body( self, *, @@ -431,3 +528,30 @@ def _prepare_get_bulk_report_file_download_url_params( ) from exc return request_params + + def _prepare_query_bulk_report_params( + self, + *, + limit: Optional[int] = None, + offset: Optional[int] = None, + sort: Optional[str] = None, + includes: Optional[List[str]] = None, + ) -> BulkReportQueryParams: + """Prepare and return query bulk report request parameters.""" + try: + _request_params: Dict[str, Any] = { + "limit": limit or 99999, + "offset": offset or 0, + "sort": sort or None, + "includes": includes or None, + } + request_params: BulkReportQueryParams = BulkReportQueryParams( + **_request_params + ) + except pydantic.ValidationError as exc: + raise RequestParamsValidationError( + message=BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE, + error=exc, + ) from exc + + return request_params diff --git a/tests/fixtures/bulk_downloads/bulk_fixed_infrastructure_data_query_item.json b/tests/fixtures/bulk_downloads/bulk_fixed_infrastructure_data_query_item.json new file mode 100644 index 0000000..5426c6d --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_fixed_infrastructure_data_query_item.json @@ -0,0 +1,11 @@ +{ + "detection_id": "S1AB_AD_MEDIAN_COMP_20210402T000000_20210929T000000_WEST_64_TILE_208;-151.608850;60.8645440", + "detection_date": "2021-07-01", + "structure_id": "162013", + "lon": -151.608786096245, + "lat": 60.8646485096125, + "structure_start_date": "2017-01-01", + "structure_end_date": "2021-10-01", + "label": "oil", + "label_confidence": "high" +} diff --git a/tests/fixtures/bulk_downloads/bulk_report_query_request_params.json b/tests/fixtures/bulk_downloads/bulk_report_query_request_params.json new file mode 100644 index 0000000..1484d8b --- /dev/null +++ b/tests/fixtures/bulk_downloads/bulk_report_query_request_params.json @@ -0,0 +1,12 @@ +{ + "limit": 99999, + "offset": 0, + "sort": "-structure_start_date", + "includes": [ + "structure_id", + "lat", + "lon", + "label", + "label_confidence" + ] +} diff --git a/tests/resources/bulk_downloads/conftest.py b/tests/resources/bulk_downloads/conftest.py index fe41b74..112666c 100644 --- a/tests/resources/bulk_downloads/conftest.py +++ b/tests/resources/bulk_downloads/conftest.py @@ -106,3 +106,38 @@ def mock_raw_bulk_report_file_item( "bulk_downloads/bulk_report_file_item.json" ) return raw_bulk_report_file_item + + +@pytest.fixture +def mock_raw_bulk_report_query_request_params( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for mock raw bulk report query request parameters. + + Returns: + Dict[str, Any]: + Raw `BulkReportQueryParams` sample data as dictionary. + """ + raw_bulk_report_query_request_params: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_report_query_request_params.json" + ) + return raw_bulk_report_query_request_params + + +@pytest.fixture +def mock_raw_bulk_fixed_infrastructure_data_query_item( + load_json_fixture: Callable[[str], Dict[str, Any]], +) -> Dict[str, Any]: + """Fixture for a mock raw bulk fixed infrastructure data query item. + + This fixture loads sample JSON data representing a single + `FixedInfrastructureDataItem` from a fixture file. + + Returns: + Dict[str, Any]: + Raw `BulkFixedInfrastructureDataQueryItem` sample data as a dictionary. + """ + raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any] = load_json_fixture( + "bulk_downloads/bulk_fixed_infrastructure_data_query_item.json" + ) + return raw_bulk_fixed_infrastructure_data_query_item diff --git a/tests/resources/bulk_downloads/query/__init__.py b/tests/resources/bulk_downloads/query/__init__.py new file mode 100644 index 0000000..71cf28a --- /dev/null +++ b/tests/resources/bulk_downloads/query/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query`.""" diff --git a/tests/resources/bulk_downloads/query/models/__init__.py b/tests/resources/bulk_downloads/query/models/__init__.py new file mode 100644 index 0000000..86716b3 --- /dev/null +++ b/tests/resources/bulk_downloads/query/models/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.models`.""" diff --git a/tests/resources/bulk_downloads/query/models/base/__init__.py b/tests/resources/bulk_downloads/query/models/base/__init__.py new file mode 100644 index 0000000..3a49bd7 --- /dev/null +++ b/tests/resources/bulk_downloads/query/models/base/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.models.base`.""" diff --git a/tests/resources/bulk_downloads/query/models/base/test_request_models.py b/tests/resources/bulk_downloads/query/models/base/test_request_models.py new file mode 100644 index 0000000..670edab --- /dev/null +++ b/tests/resources/bulk_downloads/query/models/base/test_request_models.py @@ -0,0 +1,21 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.models.base.request`.""" + +from typing import Any, Dict + +from gfwapiclient.resources.bulk_downloads.query.models.base.request import ( + BulkReportQueryParams, +) + + +def test_bulk_report_query_request_params_serializes_all_fields( + mock_raw_bulk_report_query_request_params: Dict[str, Any], +) -> None: + """Test that `BulkReportQueryParams` serializes all fields correctly.""" + bulk_report_query_params: BulkReportQueryParams = BulkReportQueryParams( + **mock_raw_bulk_report_query_request_params + ) + assert bulk_report_query_params.limit is not None + assert bulk_report_query_params.offset is not None + assert bulk_report_query_params.sort is not None + assert bulk_report_query_params.includes is not None + assert bulk_report_query_params.to_query_params() is not None diff --git a/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py b/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py new file mode 100644 index 0000000..2fbf224 --- /dev/null +++ b/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/__init__.py @@ -0,0 +1 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data`.""" diff --git a/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/test_response_models.py b/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/test_response_models.py new file mode 100644 index 0000000..f269b15 --- /dev/null +++ b/tests/resources/bulk_downloads/query/models/fixed_infrastructure_data/test_response_models.py @@ -0,0 +1,65 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response`.""" + +from typing import Any, Dict, List, cast + +from gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response import ( + BulkFixedInfrastructureDataQueryItem, + BulkFixedInfrastructureDataQueryResult, +) + + +def test_bulk_fixed_infrastructure_data_query_item_deserializes_all_fields( + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], +) -> None: + """Test that `BulkFixedInfrastructureDataQueryItem` deserializes all fields correctly.""" + fixed_infrastructure_data_item: BulkFixedInfrastructureDataQueryItem = ( + BulkFixedInfrastructureDataQueryItem( + **mock_raw_bulk_fixed_infrastructure_data_query_item + ) + ) + assert fixed_infrastructure_data_item.detection_id is not None + assert fixed_infrastructure_data_item.detection_date is not None + assert fixed_infrastructure_data_item.structure_id is not None + assert fixed_infrastructure_data_item.lon is not None + assert fixed_infrastructure_data_item.lat is not None + assert fixed_infrastructure_data_item.structure_start_date is not None + assert fixed_infrastructure_data_item.structure_end_date is not None + assert fixed_infrastructure_data_item.label is not None + assert fixed_infrastructure_data_item.label_confidence is not None + + +def test_bulk_fixed_infrastructure_data_query_item_deserializes_empty_date_fields( + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], +) -> None: + """Test that `BulkFixedInfrastructureDataQueryItem` deserializes empty date fields correctly.""" + fixed_infrastructure_data_item: BulkFixedInfrastructureDataQueryItem = ( + BulkFixedInfrastructureDataQueryItem( + **{ + **mock_raw_bulk_fixed_infrastructure_data_query_item, + "structure_start_date": " ", + "structure_end_date": None, + } + ) + ) + assert fixed_infrastructure_data_item.detection_id is not None + assert fixed_infrastructure_data_item.detection_date is not None + assert fixed_infrastructure_data_item.structure_id is not None + assert fixed_infrastructure_data_item.lon is not None + assert fixed_infrastructure_data_item.lat is not None + assert fixed_infrastructure_data_item.structure_start_date is None + assert fixed_infrastructure_data_item.structure_end_date is None + assert fixed_infrastructure_data_item.label is not None + assert fixed_infrastructure_data_item.label_confidence is not None + + +def test_bulk_fixed_infrastructure_data_query_result_deserializes_all_fields( + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], +) -> None: + """Test that `BulkFixedInfrastructureDataQueryResult` deserializes all fields correctly.""" + data: List[BulkFixedInfrastructureDataQueryItem] = [ + BulkFixedInfrastructureDataQueryItem( + **mock_raw_bulk_fixed_infrastructure_data_query_item + ) + ] + result = BulkFixedInfrastructureDataQueryResult(data=data) + assert cast(List[BulkFixedInfrastructureDataQueryItem], result.data()) == data diff --git a/tests/resources/bulk_downloads/query/test_endpoints.py b/tests/resources/bulk_downloads/query/test_endpoints.py new file mode 100644 index 0000000..a0b7b71 --- /dev/null +++ b/tests/resources/bulk_downloads/query/test_endpoints.py @@ -0,0 +1,104 @@ +"""Tests for `gfwapiclient.resources.bulk_downloads.query.endpoints`.""" + +from typing import Any, Dict, List, cast + +import httpx +import pytest +import respx + +from gfwapiclient.exceptions.base import GFWAPIClientError +from gfwapiclient.exceptions.validation import ResultValidationError +from gfwapiclient.http.client import HTTPClient +from gfwapiclient.resources.bulk_downloads.query.endpoints import ( + BulkFixedInfrastructureDataQueryEndPoint, +) +from gfwapiclient.resources.bulk_downloads.query.models.base.request import ( + BulkReportQueryParams, +) +from gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response import ( + BulkFixedInfrastructureDataQueryItem, + BulkFixedInfrastructureDataQueryResult, +) + +from ..conftest import bulk_report_id + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_fixed_infrastructure_data_query_endpoint_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_query_request_params: Dict[str, Any], + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkFixedInfrastructureDataQueryEndPoint` request succeeds with a valid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/query").respond( + 200, json={"entries": [mock_raw_bulk_fixed_infrastructure_data_query_item, {}]} + ) + request_params: BulkReportQueryParams = BulkReportQueryParams( + **mock_raw_bulk_report_query_request_params + ) + endpoint: BulkFixedInfrastructureDataQueryEndPoint = ( + BulkFixedInfrastructureDataQueryEndPoint( + bulk_report_id=bulk_report_id, + request_params=request_params, + http_client=mock_http_client, + ) + ) + result: BulkFixedInfrastructureDataQueryResult = await endpoint.request() + data: List[BulkFixedInfrastructureDataQueryItem] = cast( + List[BulkFixedInfrastructureDataQueryItem], result.data() + ) + assert isinstance(result, BulkFixedInfrastructureDataQueryResult) + assert isinstance(data[0], BulkFixedInfrastructureDataQueryItem) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_fixed_infrastructure_data_query_endpoint_invalid_response_body_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_query_request_params: Dict[str, Any], + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkFixedInfrastructureDataQueryEndPoint` request fails with an invalid response body.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/query").respond( + 200, json=[mock_raw_bulk_fixed_infrastructure_data_query_item] + ) + request_params: BulkReportQueryParams = BulkReportQueryParams( + **mock_raw_bulk_report_query_request_params + ) + endpoint: BulkFixedInfrastructureDataQueryEndPoint = ( + BulkFixedInfrastructureDataQueryEndPoint( + bulk_report_id=bulk_report_id, + request_params=request_params, + http_client=mock_http_client, + ) + ) + with pytest.raises(ResultValidationError): + await endpoint.request() + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_fixed_infrastructure_data_query_endpoint_request_failure( + mock_http_client: HTTPClient, + mock_raw_bulk_report_query_request_params: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkFixedInfrastructureDataQueryEndPoint` request fails with an invalid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/query").mock( + return_value=httpx.Response(status_code=400, json={"error": "Bad Request"}) + ) + request_params: BulkReportQueryParams = BulkReportQueryParams( + **mock_raw_bulk_report_query_request_params + ) + endpoint: BulkFixedInfrastructureDataQueryEndPoint = ( + BulkFixedInfrastructureDataQueryEndPoint( + bulk_report_id=bulk_report_id, + request_params=request_params, + http_client=mock_http_client, + ) + ) + with pytest.raises(GFWAPIClientError): + await endpoint.request() diff --git a/tests/resources/bulk_downloads/test_resources.py b/tests/resources/bulk_downloads/test_resources.py index 3b7e391..d7bde1d 100644 --- a/tests/resources/bulk_downloads/test_resources.py +++ b/tests/resources/bulk_downloads/test_resources.py @@ -35,6 +35,13 @@ BulkReportListItem, BulkReportListResult, ) +from gfwapiclient.resources.bulk_downloads.query.models.base.request import ( + BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE, +) +from gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response import ( + BulkFixedInfrastructureDataQueryItem, + BulkFixedInfrastructureDataQueryResult, +) from gfwapiclient.resources.bulk_downloads.resources import BulkDownloadResource from .conftest import bulk_report_id @@ -174,3 +181,45 @@ async def test_bulk_download_resource_get_bulk_report_file_download_url_request_ await resource.get_bulk_report_file_download_url( id=bulk_report_id, file="INVALID_FILE_TYPE" ) + + +@pytest.mark.asyncio +@pytest.mark.respx +async def test_bulk_download_resource_query_bulk_fixed_infrastructure_data_report_request_success( + mock_http_client: HTTPClient, + mock_raw_bulk_report_query_request_params: Dict[str, Any], + mock_raw_bulk_fixed_infrastructure_data_query_item: Dict[str, Any], + mock_responsex: respx.MockRouter, +) -> None: + """Test `BulkDownloadResource` query bulk fixed infrastructure data report succeeds with a valid response.""" + mock_responsex.get(f"bulk-reports/{bulk_report_id}/query").respond( + 200, json={"entries": [mock_raw_bulk_fixed_infrastructure_data_query_item, {}]} + ) + resource = BulkDownloadResource(http_client=mock_http_client) + result: BulkFixedInfrastructureDataQueryResult = ( + await resource.query_bulk_fixed_infrastructure_data_report( + **{ + **mock_raw_bulk_report_query_request_params, + "id": bulk_report_id, + } + ) + ) + data = cast(List[BulkFixedInfrastructureDataQueryItem], result.data()) + assert isinstance(result, BulkFixedInfrastructureDataQueryResult) + assert isinstance(data[0], BulkFixedInfrastructureDataQueryItem) + + +@pytest.mark.asyncio +async def test_bulk_download_resource_query_bulk_fixed_infrastructure_data_report_request_params_validation_error_raises( + mock_http_client: HTTPClient, +) -> None: + """Test `BulkDownloadResource` query bulk fixed infrastructure data report raises `RequestParamsValidationError` with invalid parameters.""" + resource = BulkDownloadResource(http_client=mock_http_client) + + with pytest.raises( + RequestParamsValidationError, + match=BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE, + ): + await resource.query_bulk_fixed_infrastructure_data_report( + id=bulk_report_id, limit=-1, offset=-1 + ) From 954e1e4797196a5177b727e557ce11d1bab9ae25 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 6 Jan 2026 14:16:43 +0300 Subject: [PATCH 11/22] fix(bulk-downloads): correct typehints in docstrings --- .../resources/bulk_downloads/base/models/response.py | 2 +- .../query/models/fixed_infrastructure_data/response.py | 8 ++++---- src/gfwapiclient/resources/bulk_downloads/resources.py | 2 +- .../resources/fourwings/report/models/response.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gfwapiclient/resources/bulk_downloads/base/models/response.py b/src/gfwapiclient/resources/bulk_downloads/base/models/response.py index 03fc8a3..652b53c 100644 --- a/src/gfwapiclient/resources/bulk_downloads/base/models/response.py +++ b/src/gfwapiclient/resources/bulk_downloads/base/models/response.py @@ -163,7 +163,7 @@ def empty_datetime_str_to_none(cls, value: Any) -> Optional[Any]: The value to validate. Returns: - Optional[datetime.datetime]: + Optional[Any]: The validated datetime object or `None` if input is empty. """ if isinstance(value, str) and value.strip() == "": diff --git a/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py index 85318c1..3fa50c1 100644 --- a/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py +++ b/src/gfwapiclient/resources/bulk_downloads/query/models/fixed_infrastructure_data/response.py @@ -91,7 +91,7 @@ def empty_datetime_str_to_none(cls, value: Any) -> Optional[Any]: The value to validate. Returns: - Optional[datetime.datetime]: + Optional[Any]: The validated datetime object or `None` if input is empty. """ if isinstance(value, str) and value.strip() == "": @@ -113,10 +113,10 @@ class BulkFixedInfrastructureDataQueryResult( See: https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format Attributes: - _result_item_class (Type[FixedInfrastructureDataItem]): + _result_item_class (Type[BulkFixedInfrastructureDataQueryItem]): The model used for individual result items. - _data (List[FixedInfrastructureDataItem]): + _data (List[BulkFixedInfrastructureDataQueryItem]): The bulk fixed infrastructure data report items returned in the response. """ @@ -127,7 +127,7 @@ def __init__(self, data: List[BulkFixedInfrastructureDataQueryItem]) -> None: """Initializes a new `FixedInfrastructureDataResult`. Args: - data (List[FixedInfrastructureDataItem]): + data (List[BulkFixedInfrastructureDataQueryItem]): The list of bulk fixed infrastructure data report items. """ super().__init__(data=data) diff --git a/src/gfwapiclient/resources/bulk_downloads/resources.py b/src/gfwapiclient/resources/bulk_downloads/resources.py index c0d093e..c78575f 100644 --- a/src/gfwapiclient/resources/bulk_downloads/resources.py +++ b/src/gfwapiclient/resources/bulk_downloads/resources.py @@ -423,7 +423,7 @@ async def query_bulk_fixed_infrastructure_data_report( Additional keyword arguments. Returns: - FixedInfrastructureDataResult: + BulkFixedInfrastructureDataQueryResult: The result containing the list of bulk fixed infrastructure data report items. Raises: diff --git a/src/gfwapiclient/resources/fourwings/report/models/response.py b/src/gfwapiclient/resources/fourwings/report/models/response.py index ce525b1..a925d62 100644 --- a/src/gfwapiclient/resources/fourwings/report/models/response.py +++ b/src/gfwapiclient/resources/fourwings/report/models/response.py @@ -132,7 +132,7 @@ def empty_datetime_str_to_none(cls, value: Any) -> Optional[Any]: The value to validate. Returns: - Optional[datetime.datetime]: + Optional[Any]: The validated datetime object or `None` if input is empty. """ if isinstance(value, str) and value.strip() == "": From d608704658f33f6391eb1210f8c071ec6a2e3491 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 8 Jan 2026 12:19:26 +0300 Subject: [PATCH 12/22] docs: add datasets, data caveats, and terms of use links --- README.md | 2 +- docs/source/development-guides/changelog.md | 1 + .../development-guides/code-of-conduct.md | 1 + docs/source/development-guides/contributing.md | 1 + docs/source/development-guides/git-workflow.md | 1 + docs/source/development-guides/index.md | 1 - docs/source/development-guides/license.md | 1 + docs/source/development-guides/security.md | 1 + docs/source/development-guides/setup.md | 1 + docs/source/getting-started.md | 2 +- docs/source/index.md | 17 ++++++++++------- docs/source/installation.md | 1 + docs/source/usage-guides/4wings-api.md | 2 +- docs/source/usage-guides/datasets-api.md | 2 +- docs/source/usage-guides/events-api.md | 2 +- docs/source/usage-guides/index.md | 2 ++ docs/source/usage-guides/insights-api.md | 2 +- docs/source/usage-guides/references-data-api.md | 2 +- docs/source/usage-guides/vessels-api.md | 2 +- notebooks/getting-started.ipynb | 2 +- notebooks/usage-guides/datasets-api.ipynb | 2 +- notebooks/usage-guides/events-api.ipynb | 2 +- notebooks/usage-guides/insights-api.ipynb | 2 +- .../usage-guides/references-data-api.ipynb | 2 +- notebooks/usage-guides/vessels-api.ipynb | 2 +- src/gfwapiclient/__init__.py | 4 +++- src/gfwapiclient/client/__init__.py | 14 ++++++++------ src/gfwapiclient/client/client.py | 2 ++ 28 files changed, 47 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 342a448..ebc8848 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The Global Fishing Watch Python package currently works with the following APIs: - [References API](https://globalfishingwatch.org/our-apis/documentation#regions): Access metadata for EEZs, MPAs, and RFMOs to use in [Events API](https://globalfishingwatch.org/our-apis/documentation#events-api) and [Map Visualization (4Wings API)](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) requests and analyses. -> **Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. ## Requirements diff --git a/docs/source/development-guides/changelog.md b/docs/source/development-guides/changelog.md index dd74d15..4f3f75f 100644 --- a/docs/source/development-guides/changelog.md +++ b/docs/source/development-guides/changelog.md @@ -3,4 +3,5 @@ All notable changes to this project will be documented in this file. ```{include} ../../../CHANGELOG.md + ``` diff --git a/docs/source/development-guides/code-of-conduct.md b/docs/source/development-guides/code-of-conduct.md index 03ce547..7d7f11c 100644 --- a/docs/source/development-guides/code-of-conduct.md +++ b/docs/source/development-guides/code-of-conduct.md @@ -1,2 +1,3 @@ ```{include} ../../../CODE_OF_CONDUCT.md + ``` diff --git a/docs/source/development-guides/contributing.md b/docs/source/development-guides/contributing.md index 004f419..7f619f5 100644 --- a/docs/source/development-guides/contributing.md +++ b/docs/source/development-guides/contributing.md @@ -1,2 +1,3 @@ ```{include} ../../../CONTRIBUTING.md + ``` diff --git a/docs/source/development-guides/git-workflow.md b/docs/source/development-guides/git-workflow.md index 157422a..47caf96 100644 --- a/docs/source/development-guides/git-workflow.md +++ b/docs/source/development-guides/git-workflow.md @@ -1,2 +1,3 @@ ```{include} ../../../GIT_WORKFLOW.md + ``` diff --git a/docs/source/development-guides/index.md b/docs/source/development-guides/index.md index e1159ac..54a59f9 100644 --- a/docs/source/development-guides/index.md +++ b/docs/source/development-guides/index.md @@ -2,7 +2,6 @@ The sections below will help you get started with development, testing, and documentation. - ```{toctree} :maxdepth: 1 diff --git a/docs/source/development-guides/license.md b/docs/source/development-guides/license.md index 57b86a0..3bdb79c 100644 --- a/docs/source/development-guides/license.md +++ b/docs/source/development-guides/license.md @@ -1,4 +1,5 @@ # License ```{include} ../../../LICENSE + ``` diff --git a/docs/source/development-guides/security.md b/docs/source/development-guides/security.md index cef7352..c559719 100644 --- a/docs/source/development-guides/security.md +++ b/docs/source/development-guides/security.md @@ -1,2 +1,3 @@ ```{include} ../../../SECURITY.md + ``` diff --git a/docs/source/development-guides/setup.md b/docs/source/development-guides/setup.md index c856d25..e68a53b 100644 --- a/docs/source/development-guides/setup.md +++ b/docs/source/development-guides/setup.md @@ -1,2 +1,3 @@ ```{include} ../../../SETUP.md + ``` diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index c6b887a..7933bee 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -4,7 +4,7 @@ This guide introduces you to the basics of using the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client). For detailed and alternative installation instructions, please refer to the [Installation](installation) section. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/getting-started.ipynb) version for this guide. -> **Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. ## Authorization diff --git a/docs/source/index.md b/docs/source/index.md index 15707df..bb58aed 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -4,7 +4,9 @@ hide-toc: true # gfw-api-python-client -The `gfw-api-python-client` simplifies access to Global Fishing Watch (GFW) data through [our APIs](https://globalfishingwatch.org/our-apis/documentation). It offers straightforward functions for retrieving GFW data. For R users, we also provide the gfwr package; learn more [here](https://globalfishingwatch.github.io/gfwr/) +The `gfw-api-python-client` simplifies access to Global Fishing Watch (GFW) data through [our APIs](https://globalfishingwatch.org/our-apis/documentation). It offers straightforward functions for retrieving GFW data. For **R users**, we also provide the [gfwr](https://github.com/GlobalFishingWatch/gfwr) package; learn more [here](https://globalfishingwatch.github.io/gfwr/) + +> **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. ```{toctree} :hidden: @@ -29,6 +31,7 @@ GitHub Website Our APIs +Datasets Data Caveats Terms of Use FAQs @@ -40,12 +43,12 @@ To learn about how to use `gfw-api-python-client`, check out the following resou - [Getting Started](getting-started) - [Installation Guide](installation) - [Usage Guides](usage-guides/index) - - [4Wings API](usage-guides/4wings-api) - - [Vessels API](usage-guides/vessels-api) - - [Events API](usage-guides/events-api) - - [Insights API](usage-guides/insights-api) - - [Datasets API](usage-guides/datasets-api) - - [References Data API](usage-guides/references-data-api) + - [4Wings API](usage-guides/4wings-api) + - [Vessels API](usage-guides/vessels-api) + - [Events API](usage-guides/events-api) + - [Insights API](usage-guides/insights-api) + - [Datasets API](usage-guides/datasets-api) + - [References Data API](usage-guides/references-data-api) If you find bugs, need help, or want to contribute, check out the following resources: diff --git a/docs/source/installation.md b/docs/source/installation.md index f703928..d63111c 100644 --- a/docs/source/installation.md +++ b/docs/source/installation.md @@ -1,2 +1,3 @@ ```{include} ../../INSTALLATION.md + ``` diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 068bcee..1e5aa78 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-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 the 4Wings API, which is designed for generating reports and statistics on activities within specified regions. This API is particularly useful for creating data visualizations related to fishing effort and other vessel activities. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/4wings-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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 diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 61649ce..43e0569 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-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 various datasets available through the Global Fishing Watch API. Currently, it focuses on retrieving SAR (Synthetic Aperture Radar) fixed infrastructure data. The Datasets API allows you to retrieve this information, either by specifying `tile coordinates` or a `geographic geometry`. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/datasets-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats), 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 diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index a5079a8..1bc62ef 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-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 information about various activities of a vessel, including fishing activity, encounters, port visits, loitering, and gaps in AIS reporting. The Events API allows you to retrieve lists of events, get details for a specific event, and obtain statistics on event occurrences. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/events-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Events Data Caveats](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Events Data Caveats](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated), 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 diff --git a/docs/source/usage-guides/index.md b/docs/source/usage-guides/index.md index f3aacd0..00ec833 100644 --- a/docs/source/usage-guides/index.md +++ b/docs/source/usage-guides/index.md @@ -2,6 +2,8 @@ The sections below provide detailed instructions and examples for interacting with the various APIs offered by Global Fishing Watch using the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client). +> **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. + ```{toctree} :maxdepth: 1 diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 2270b9f..6d4354a 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 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 [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) page 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 [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. ## Prerequisites diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index 19b24c5..95a4f45 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-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 reference data, specifically geographic regions. The Reference Data API offers access to static datasets, currently focusing on Exclusive Economic Zones (EEZs), Marine Protected Areas (MPAs), and Regional Fisheries Management Organizations (RFMOs). Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/references-data-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Reference Data Caveats](https://globalfishingwatch.org/our-apis/documentation#reference-data) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Reference Data Caveats](https://globalfishingwatch.org/our-apis/documentation#reference-data), 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 diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index e980e05..a3b4ea3 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-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 information about vessels. The Vessels API allows you to search for vessels, retrieve lists of vessels by their IDs, and get detailed information for a specific vessel, drawing from various datasets like identity, authorizations, and ownership. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/vessels-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Vessel Data Caveats](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Vessel Data Caveats](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information), 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 diff --git a/notebooks/getting-started.ipynb b/notebooks/getting-started.ipynb index 1705966..9d1ab70 100644 --- a/notebooks/getting-started.ipynb +++ b/notebooks/getting-started.ipynb @@ -36,7 +36,7 @@ "id": "54769843-ce28-4fcb-84ca-d57636e1f5b1", "metadata": {}, "source": [ - "**Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." ] }, { diff --git a/notebooks/usage-guides/datasets-api.ipynb b/notebooks/usage-guides/datasets-api.ipynb index 73d0fa9..6746eb6 100644 --- a/notebooks/usage-guides/datasets-api.ipynb +++ b/notebooks/usage-guides/datasets-api.ipynb @@ -36,7 +36,7 @@ "id": "0805b620-fb90-4f78-b4eb-79fb3bf5d878", "metadata": {}, "source": [ - "See the [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats), 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." ] }, { diff --git a/notebooks/usage-guides/events-api.ipynb b/notebooks/usage-guides/events-api.ipynb index f8ade5a..69982ee 100644 --- a/notebooks/usage-guides/events-api.ipynb +++ b/notebooks/usage-guides/events-api.ipynb @@ -36,7 +36,7 @@ "id": "ac3ebead-45de-4287-bbd0-7c62d5e71b3a", "metadata": {}, "source": [ - "See the [Events Data Caveats](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Events Data Caveats](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated), 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." ] }, { diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 84a4629..766d5ec 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": [ - "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 [Terms of Use](https://globalfishingwatch.org/our-apis/documentation#terms-of-use) page 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 [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." ] }, { diff --git a/notebooks/usage-guides/references-data-api.ipynb b/notebooks/usage-guides/references-data-api.ipynb index 1827ea3..55bf077 100644 --- a/notebooks/usage-guides/references-data-api.ipynb +++ b/notebooks/usage-guides/references-data-api.ipynb @@ -36,7 +36,7 @@ "id": "c777748f-4bf0-4529-8361-46841cf4ea26", "metadata": {}, "source": [ - "See the [Reference Data Caveats](https://globalfishingwatch.org/our-apis/documentation#reference-data) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Reference Data Caveats](https://globalfishingwatch.org/our-apis/documentation#reference-data), 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." ] }, { diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index d1302cd..59ec9fe 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -36,7 +36,7 @@ "id": "fa8109d3-42f9-4ad2-a734-5c62ff41eb72", "metadata": {}, "source": [ - "See the [Vessel Data Caveats](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Vessel Data Caveats](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information), 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." ] }, { diff --git a/src/gfwapiclient/__init__.py b/src/gfwapiclient/__init__.py index 31e66e3..f46c81d 100644 --- a/src/gfwapiclient/__init__.py +++ b/src/gfwapiclient/__init__.py @@ -41,9 +41,11 @@ See: https://globalfishingwatch.org/our-apis/documentation#introduction -For more details on the data caveats and terms of use, please refer to the +For more details on the datasets, data caveats and terms of use, please refer to the official Global Fishing Watch API documentation: +See: https://globalfishingwatch.org/our-apis/documentation#api-dataset + See: https://globalfishingwatch.org/our-apis/documentation#data-caveat See: https://globalfishingwatch.org/our-apis/documentation#terms-of-use diff --git a/src/gfwapiclient/client/__init__.py b/src/gfwapiclient/client/__init__.py index 790c30f..e9d2293 100644 --- a/src/gfwapiclient/client/__init__.py +++ b/src/gfwapiclient/client/__init__.py @@ -1,17 +1,19 @@ """Global Fishing Watch (GFW) API Python Client. -This module provides the main entry point for interacting with the Global Fishing Watch (GFW) API, specifically Version 3. -It encapsulates the HTTP client and resources, providing a unified interface -for accessing GFW's data. +This module provides the main entry point for interacting with the +Global Fishing Watch (GFW) API, specifically Version 3. It encapsulates the HTTP client +and resources, providing a unified interface for accessing GFW's data. -For more details on the GFW API and available data, please refer to the -official documentation: +For more details on the GFW API and available data, please refer to the official +Global Fishing Watch API documentation: See: https://globalfishingwatch.org/our-apis/documentation#introduction See: https://globalfishingwatch.org/our-apis/documentation#data-available -See: https://globalfishingwatch.org/our-apis/documentation#version-3-api +See: https://globalfishingwatch.org/our-apis/documentation#api-dataset + +See: https://globalfishingwatch.org/our-apis/documentation#data-caveat """ from gfwapiclient.client.client import Client diff --git a/src/gfwapiclient/client/client.py b/src/gfwapiclient/client/client.py index 270de6e..1474534 100644 --- a/src/gfwapiclient/client/client.py +++ b/src/gfwapiclient/client/client.py @@ -38,6 +38,8 @@ class Client: See: https://globalfishingwatch.org/our-apis/documentation#data-available + See: https://globalfishingwatch.org/our-apis/documentation#api-dataset + See: https://globalfishingwatch.org/our-apis/documentation#data-caveat Attributes: From f1214c58929db873c806c474f0631db66c4eb371 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 8 Jan 2026 13:39:53 +0300 Subject: [PATCH 13/22] docs(fourwings): clarify `GEARTYPE` and `FLAGANDGEARTYPE` exclusions for AIS presence reports --- docs/source/usage-guides/4wings-api.md | 110 +++--- notebooks/usage-guides/4wings-api.ipynb | 364 +++++++++--------- .../resources/fourwings/resources.py | 7 +- 3 files changed, 250 insertions(+), 231 deletions(-) diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 1e5aa78..108f682 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -40,7 +40,7 @@ Generates **AIS (Automatic Identification System) apparent fishing effort** repo fishing_effort_report_result = await gfw_client.fourwings.create_fishing_effort_report( spatial_resolution="LOW", temporal_resolution="MONTHLY", - group_by="GEARTYPE", + group_by="FLAG", start_date="2022-01-01", end_date="2022-05-01", region={ @@ -59,7 +59,7 @@ fishing_effort_report_item = fishing_effort_report_data[-1] print(( fishing_effort_report_item.date, - fishing_effort_report_item.gear_type, + fishing_effort_report_item.flag, fishing_effort_report_item.hours, fishing_effort_report_item.vessel_ids, fishing_effort_report_item.lat, @@ -70,7 +70,7 @@ print(( **Output:** ``` -('2022-04', 'fishing', 2.705, 1, 52.0, 155.2) +('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0) ``` ### Access the report data as a DataFrame @@ -79,23 +79,23 @@ print(( fishing_effort_report_df = fishing_effort_report_result.df() print(fishing_effort_report_df.info()) -print(fishing_effort_report_df[["date", "gear_type", "hours", "vessel_ids", "lat", "lon"]].head()) +print(fishing_effort_report_df[["date", "flag", "hours", "vessel_ids", "lat", "lon"]].head()) ``` **Output:** ``` -RangeIndex: 41916 entries, 0 to 41915 +RangeIndex: 32271 entries, 0 to 32270 Data columns (total 20 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 date 41916 non-null object + 0 date 32271 non-null object 1 detections 0 non-null object - 2 flag 0 non-null object - 3 gear_type 41916 non-null object - 4 hours 41916 non-null float64 - 5 vessel_ids 41916 non-null int64 + 2 flag 32271 non-null object + 3 gear_type 0 non-null object + 4 hours 32271 non-null float64 + 5 vessel_ids 32271 non-null int64 6 vessel_id 0 non-null object 7 vessel_type 0 non-null object 8 entry_timestamp 0 non-null object @@ -106,12 +106,12 @@ Data columns (total 20 columns): 13 mmsi 0 non-null object 14 call_sign 0 non-null object 15 dataset 0 non-null object - 16 report_dataset 41916 non-null object + 16 report_dataset 32271 non-null object 17 ship_name 0 non-null object - 18 lat 41916 non-null float64 - 19 lon 41916 non-null float64 + 18 lat 32271 non-null float64 + 19 lon 32271 non-null float64 dtypes: float64(3), int64(1), object(16) -memory usage: 6.4+ MB +memory usage: 4.9+ MB ``` ## Creating an AIS Presence Report (`create_ais_presence_report`) @@ -124,7 +124,7 @@ Generates **AIS (Automatic Identification System) vessel presence** reports to v ais_presence_report_result = await gfw_client.fourwings.create_ais_presence_report( spatial_resolution="LOW", temporal_resolution="MONTHLY", - group_by="GEARTYPE", + group_by="FLAG", start_date="2022-01-01", end_date="2022-05-01", region={ @@ -143,6 +143,7 @@ ais_presence_report_item = ais_presence_report_data[-1] print(( ais_presence_report_item.date, + ais_presence_report_item.flag, ais_presence_report_item.hours, ais_presence_report_item.vessel_ids, ais_presence_report_item.lat, @@ -153,7 +154,7 @@ print(( **Output:** ``` -('2022-04', 9.0, 8, 50.4, 160.7) +('2022-03', 'RUS', 1.0, 1, 52.1, 153.2) ``` ### Access the report data as a DataFrame @@ -162,23 +163,23 @@ print(( ais_presence_report_df = ais_presence_report_result.df() print(ais_presence_report_df.info()) -print(ais_presence_report_df[["date", "hours", "vessel_ids", "lat", "lon"]].head()) +print(ais_presence_report_df[["date", "flag", "hours", "vessel_ids", "lat", "lon"]].head()) ``` **Output:** ``` -RangeIndex: 144227 entries, 0 to 144226 +RangeIndex: 274333 entries, 0 to 274332 Data columns (total 20 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 date 144227 non-null object + 0 date 274333 non-null object 1 detections 0 non-null object - 2 flag 0 non-null object - 3 gear_type 144227 non-null object - 4 hours 144227 non-null float64 - 5 vessel_ids 144227 non-null int64 + 2 flag 274333 non-null object + 3 gear_type 0 non-null object + 4 hours 274333 non-null float64 + 5 vessel_ids 274333 non-null int64 6 vessel_id 0 non-null object 7 vessel_type 0 non-null object 8 entry_timestamp 0 non-null object @@ -189,12 +190,12 @@ Data columns (total 20 columns): 13 mmsi 0 non-null object 14 call_sign 0 non-null object 15 dataset 0 non-null object - 16 report_dataset 144227 non-null object + 16 report_dataset 274333 non-null object 17 ship_name 0 non-null object - 18 lat 144227 non-null float64 - 19 lon 144227 non-null float64 + 18 lat 274333 non-null float64 + 19 lon 274333 non-null float64 dtypes: float64(3), int64(1), object(16) -memory usage: 22.0+ MB +memory usage: 41.9+ MB ``` ## Creating a SAR Vessel Detections Report (`create_sar_presence_report`) @@ -226,6 +227,7 @@ sar_presence_report_item = sar_presence_report_data[-1] print(( sar_presence_report_item.date, + sar_presence_report_item.flag, sar_presence_report_item.detections, sar_presence_report_item.vessel_ids, sar_presence_report_item.lat, @@ -236,7 +238,7 @@ print(( **Output:** ``` -('2022-04', 1, 1, 46.6, 142.6) +('2022-04', '', 1, 1, 46.6, 142.6) ``` ### Access the report data as a DataFrame @@ -245,23 +247,23 @@ print(( sar_presence_report_df = sar_presence_report_result.df() print(sar_presence_report_df.info()) -print(sar_presence_report_df[["date", "detections", "vessel_ids", "lat", "lon"]].head()) +print(sar_presence_report_df[["date", "flag", "detections", "vessel_ids", "lat", "lon"]].head()) ``` **Output:** ``` -RangeIndex: 3300 entries, 0 to 3299 +RangeIndex: 3995 entries, 0 to 3994 Data columns (total 20 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 date 3300 non-null object - 1 detections 3300 non-null int64 - 2 flag 0 non-null object - 3 gear_type 3300 non-null object + 0 date 3995 non-null object + 1 detections 3995 non-null int64 + 2 flag 3995 non-null object + 3 gear_type 0 non-null object 4 hours 0 non-null object - 5 vessel_ids 3300 non-null int64 + 5 vessel_ids 3995 non-null int64 6 vessel_id 0 non-null object 7 vessel_type 0 non-null object 8 entry_timestamp 0 non-null object @@ -272,23 +274,25 @@ Data columns (total 20 columns): 13 mmsi 0 non-null object 14 call_sign 0 non-null object 15 dataset 0 non-null object - 16 report_dataset 3300 non-null object + 16 report_dataset 3995 non-null object 17 ship_name 0 non-null object - 18 lat 3300 non-null float64 - 19 lon 3300 non-null float64 + 18 lat 3995 non-null float64 + 19 lon 3995 non-null float64 dtypes: float64(2), int64(2), object(16) -memory usage: 515.8+ KB +memory usage: 624.3+ KB ``` ## Creating a Report (`create_report`) Generates a report for any [supported datasets](https://globalfishingwatch.org/our-apis/documentation#supported-datasets), using fully customizable parameters. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat). +> **Note:** AIS vessel presence (i.e., `"public-global-sar-presence:latest"` dataset) does **not** support `"GEARTYPE"` or `"FLAGANDGEARTYPE"` as `group_by` criteria. + ```python report_result = await gfw_client.fourwings.create_report( spatial_resolution="LOW", temporal_resolution="MONTHLY", - group_by="GEARTYPE", + group_by="FLAG", datasets=["public-global-fishing-effort:latest"], start_date="2022-01-01", end_date="2022-05-01", @@ -308,7 +312,7 @@ report_item = report_data[-1] print(( report_item.date, - report_item.gear_type, + report_item.flag, report_item.hours, report_item.vessel_ids, report_item.lat, @@ -320,7 +324,7 @@ print(report_item.model_dump()) **Output:** ``` -('2022-04', 'fishing', 2.705, 1, 52.0, 155.2) +('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0) ``` ### Access the report data as a DataFrame @@ -329,23 +333,23 @@ print(report_item.model_dump()) report_df = report_result.df() print(report_df.info()) -print(report_df[["date", "hours", "lat", "lon"]].head()) +print(report_df[["date", "flag", "hours", "lat", "lon"]].head()) ``` **Output:** ``` -RangeIndex: 41916 entries, 0 to 41915 +RangeIndex: 32271 entries, 0 to 32270 Data columns (total 20 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 date 41916 non-null object + 0 date 32271 non-null object 1 detections 0 non-null object - 2 flag 0 non-null object - 3 gear_type 41916 non-null object - 4 hours 41916 non-null float64 - 5 vessel_ids 41916 non-null int64 + 2 flag 32271 non-null object + 3 gear_type 0 non-null object + 4 hours 32271 non-null float64 + 5 vessel_ids 32271 non-null int64 6 vessel_id 0 non-null object 7 vessel_type 0 non-null object 8 entry_timestamp 0 non-null object @@ -356,12 +360,12 @@ Data columns (total 20 columns): 13 mmsi 0 non-null object 14 call_sign 0 non-null object 15 dataset 0 non-null object - 16 report_dataset 41916 non-null object + 16 report_dataset 32271 non-null object 17 ship_name 0 non-null object - 18 lat 41916 non-null float64 - 19 lon 41916 non-null float64 + 18 lat 32271 non-null float64 + 19 lon 32271 non-null float64 dtypes: float64(3), int64(1), object(16) -memory usage: 6.4+ MB +memory usage: 4.9+ MB ``` ## Reference Data diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index db1850b..a20a48d 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -173,7 +173,7 @@ "fishing_effort_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", " spatial_resolution=\"LOW\",\n", " temporal_resolution=\"MONTHLY\",\n", - " group_by=\"GEARTYPE\",\n", + " group_by=\"FLAG\",\n", " start_date=\"2022-01-01\",\n", " end_date=\"2022-05-01\",\n", " region={\n", @@ -220,7 +220,7 @@ { "data": { "text/plain": [ - "('2022-04', 'fishing', 2.705, 1, 52.0, 155.2)" + "('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0)" ] }, "execution_count": 8, @@ -231,7 +231,7 @@ "source": [ "(\n", " fishing_effort_report_item.date,\n", - " fishing_effort_report_item.gear_type,\n", + " fishing_effort_report_item.flag,\n", " fishing_effort_report_item.hours,\n", " fishing_effort_report_item.vessel_ids,\n", " fishing_effort_report_item.lat,\n", @@ -309,12 +309,12 @@ " \n", " \n", " 0\n", - " 2022-01\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 2.848333\n", - " 1\n", + " 3.416944\n", + " 2\n", " None\n", " None\n", " None\n", @@ -327,17 +327,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 58.5\n", - " 149.2\n", + " 75.6\n", + " 50.3\n", " \n", " \n", " 1\n", - " 2022-03\n", + " 2022-02\n", " None\n", + " RUS\n", " None\n", - " fishing\n", - " 1.305710\n", - " 1\n", + " 2.144444\n", + " 3\n", " None\n", " None\n", " None\n", @@ -350,17 +350,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 55.6\n", - " 153.8\n", + " 51.4\n", + " 155.4\n", " \n", " \n", " 2\n", - " 2022-02\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 20.537500\n", - " 13\n", + " 5.436944\n", + " 2\n", " None\n", " None\n", " None\n", @@ -373,17 +373,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 54.9\n", - " 152.7\n", + " 58.6\n", + " 155.8\n", " \n", " \n", " 3\n", - " 2022-02\n", + " 2022-01\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 5.952222\n", - " 3\n", + " 4.435556\n", + " 1\n", " None\n", " None\n", " None\n", @@ -396,16 +396,16 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 56.1\n", - " 144.4\n", + " 45.7\n", + " 149.8\n", " \n", " \n", " 4\n", - " 2022-01\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 1.951944\n", + " 0.362778\n", " 1\n", " None\n", " None\n", @@ -419,20 +419,20 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 51.7\n", - " 154.1\n", + " 46.7\n", + " 141.9\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-01 None None trawlers 2.848333 1 None \n", - "1 2022-03 None None fishing 1.305710 1 None \n", - "2 2022-02 None None trawlers 20.537500 13 None \n", - "3 2022-02 None None trawlers 5.952222 3 None \n", - "4 2022-01 None None trawlers 1.951944 1 None \n", + " date detections flag gear_type hours vessel_ids vessel_id \\\n", + "0 2022-03 None RUS None 3.416944 2 None \n", + "1 2022-02 None RUS None 2.144444 3 None \n", + "2 2022-03 None RUS None 5.436944 2 None \n", + "3 2022-01 None RUS None 4.435556 1 None \n", + "4 2022-03 None RUS None 0.362778 1 None \n", "\n", " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", "0 None None None None \n", @@ -449,11 +449,11 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-fishing-effort:v3.0 None 58.5 149.2 \n", - "1 public-global-fishing-effort:v3.0 None 55.6 153.8 \n", - "2 public-global-fishing-effort:v3.0 None 54.9 152.7 \n", - "3 public-global-fishing-effort:v3.0 None 56.1 144.4 \n", - "4 public-global-fishing-effort:v3.0 None 51.7 154.1 " + "0 public-global-fishing-effort:v3.0 None 75.6 50.3 \n", + "1 public-global-fishing-effort:v3.0 None 51.4 155.4 \n", + "2 public-global-fishing-effort:v3.0 None 58.6 155.8 \n", + "3 public-global-fishing-effort:v3.0 None 45.7 149.8 \n", + "4 public-global-fishing-effort:v3.0 None 46.7 141.9 " ] }, "execution_count": 10, @@ -499,7 +499,7 @@ "ais_presence_report_result = await gfw_client.fourwings.create_ais_presence_report(\n", " spatial_resolution=\"LOW\",\n", " temporal_resolution=\"MONTHLY\",\n", - " group_by=\"GEARTYPE\",\n", + " group_by=\"FLAG\",\n", " start_date=\"2022-01-01\",\n", " end_date=\"2022-05-01\",\n", " region={\n", @@ -546,7 +546,7 @@ { "data": { "text/plain": [ - "('2022-04', 9.0, 8, 50.4, 160.7)" + "('2022-03', 'RUS', 1.0, 1, 52.1, 153.2)" ] }, "execution_count": 14, @@ -557,6 +557,7 @@ "source": [ "(\n", " ais_presence_report_item.date,\n", + " ais_presence_report_item.flag,\n", " ais_presence_report_item.hours,\n", " ais_presence_report_item.vessel_ids,\n", " ais_presence_report_item.lat,\n", @@ -634,12 +635,12 @@ " \n", " \n", " 0\n", - " 2022-02\n", + " 2022-04\n", " None\n", + " PAN\n", " None\n", - " \n", - " 4.0\n", - " 4\n", + " 3.0\n", + " 2\n", " None\n", " None\n", " None\n", @@ -652,16 +653,16 @@ " None\n", " public-global-presence:v3.0\n", " None\n", - " 45.0\n", - " 154.3\n", + " 47.8\n", + " 154.1\n", " \n", " \n", " 1\n", - " 2022-03\n", + " 2022-02\n", " None\n", + " RUS\n", " None\n", - " \n", - " 1.0\n", + " 4.0\n", " 1\n", " None\n", " None\n", @@ -675,17 +676,17 @@ " None\n", " public-global-presence:v3.0\n", " None\n", - " 49.8\n", - " 147.8\n", + " 77.6\n", + " 70.6\n", " \n", " \n", " 2\n", - " 2022-03\n", + " 2022-02\n", " None\n", + " RUS\n", " None\n", - " \n", - " 2.0\n", - " 2\n", + " 1.0\n", + " 1\n", " None\n", " None\n", " None\n", @@ -698,17 +699,17 @@ " None\n", " public-global-presence:v3.0\n", " None\n", - " 69.4\n", - " 45.4\n", + " 75.0\n", + " 159.2\n", " \n", " \n", " 3\n", - " 2022-02\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " \n", - " 1.0\n", - " 1\n", + " 2.0\n", + " 2\n", " None\n", " None\n", " None\n", @@ -721,17 +722,17 @@ " None\n", " public-global-presence:v3.0\n", " None\n", - " 54.3\n", - " 145.3\n", + " 68.4\n", + " 49.0\n", " \n", " \n", " 4\n", - " 2022-03\n", + " 2022-02\n", " None\n", + " PAN\n", " None\n", - " \n", - " 13.0\n", - " 10\n", + " 1.0\n", + " 1\n", " None\n", " None\n", " None\n", @@ -744,27 +745,27 @@ " None\n", " public-global-presence:v3.0\n", " None\n", - " 66.3\n", - " 40.8\n", + " 50.0\n", + " 157.0\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-02 None None 4.0 4 None \n", - "1 2022-03 None None 1.0 1 None \n", - "2 2022-03 None None 2.0 2 None \n", - "3 2022-02 None None 1.0 1 None \n", - "4 2022-03 None None 13.0 10 None \n", + " date detections flag gear_type hours vessel_ids vessel_id vessel_type \\\n", + "0 2022-04 None PAN None 3.0 2 None None \n", + "1 2022-02 None RUS None 4.0 1 None None \n", + "2 2022-02 None RUS None 1.0 1 None None \n", + "3 2022-03 None RUS None 2.0 2 None None \n", + "4 2022-02 None PAN None 1.0 1 None None \n", "\n", - " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", - "0 None None None None \n", - "1 None None None None \n", - "2 None None None None \n", - "3 None None None None \n", - "4 None None None None \n", + " entry_timestamp exit_timestamp first_transmission_date \\\n", + "0 None None None \n", + "1 None None None \n", + "2 None None None \n", + "3 None None None \n", + "4 None None None \n", "\n", " last_transmission_date imo mmsi call_sign dataset \\\n", "0 None None None None None \n", @@ -774,11 +775,11 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-presence:v3.0 None 45.0 154.3 \n", - "1 public-global-presence:v3.0 None 49.8 147.8 \n", - "2 public-global-presence:v3.0 None 69.4 45.4 \n", - "3 public-global-presence:v3.0 None 54.3 145.3 \n", - "4 public-global-presence:v3.0 None 66.3 40.8 " + "0 public-global-presence:v3.0 None 47.8 154.1 \n", + "1 public-global-presence:v3.0 None 77.6 70.6 \n", + "2 public-global-presence:v3.0 None 75.0 159.2 \n", + "3 public-global-presence:v3.0 None 68.4 49.0 \n", + "4 public-global-presence:v3.0 None 50.0 157.0 " ] }, "execution_count": 16, @@ -824,7 +825,7 @@ "sar_presence_report_result = await gfw_client.fourwings.create_sar_presence_report(\n", " spatial_resolution=\"LOW\",\n", " temporal_resolution=\"MONTHLY\",\n", - " group_by=\"GEARTYPE\",\n", + " group_by=\"FLAG\",\n", " start_date=\"2022-01-01\",\n", " end_date=\"2022-05-01\",\n", " region={\n", @@ -871,7 +872,7 @@ { "data": { "text/plain": [ - "('2022-04', 1, 1, 46.6, 142.6)" + "('2022-04', '', 1, 1, 46.6, 142.6)" ] }, "execution_count": 20, @@ -882,6 +883,7 @@ "source": [ "(\n", " sar_presence_report_item.date,\n", + " sar_presence_report_item.flag,\n", " sar_presence_report_item.detections,\n", " sar_presence_report_item.vessel_ids,\n", " sar_presence_report_item.lat,\n", @@ -959,11 +961,11 @@ " \n", " \n", " 0\n", - " 2022-02\n", + " 2022-01\n", " 1\n", - " None\n", " \n", " None\n", + " None\n", " 1\n", " None\n", " None\n", @@ -977,17 +979,17 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 46.3\n", - " 142.4\n", + " 44.6\n", + " 38.0\n", " \n", " \n", " 1\n", - " 2022-04\n", - " 1\n", + " 2022-03\n", + " 3\n", + " RUS\n", " None\n", - " other\n", " None\n", - " 1\n", + " 3\n", " None\n", " None\n", " None\n", @@ -1000,15 +1002,15 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 46.0\n", - " 143.7\n", + " 46.7\n", + " 141.8\n", " \n", " \n", " 2\n", - " 2022-03\n", + " 2022-04\n", " 1\n", + " RUS\n", " None\n", - " fishing\n", " None\n", " 1\n", " None\n", @@ -1023,17 +1025,17 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 46.7\n", - " 141.7\n", + " 46.8\n", + " 141.4\n", " \n", " \n", " 3\n", - " 2022-03\n", - " 1\n", + " 2022-02\n", + " 2\n", + " GRC\n", " None\n", - " \n", " None\n", - " 1\n", + " 2\n", " None\n", " None\n", " None\n", @@ -1046,15 +1048,15 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 49.1\n", - " 144.4\n", + " 44.2\n", + " 37.4\n", " \n", " \n", " 4\n", - " 2022-03\n", + " 2022-01\n", " 1\n", + " MLT\n", " None\n", - " other\n", " None\n", " 1\n", " None\n", @@ -1069,27 +1071,27 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 49.3\n", - " 141.8\n", + " 43.8\n", + " 38.7\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-02 1 None None 1 None \n", - "1 2022-04 1 None other None 1 None \n", - "2 2022-03 1 None fishing None 1 None \n", - "3 2022-03 1 None None 1 None \n", - "4 2022-03 1 None other None 1 None \n", + " date detections flag gear_type hours vessel_ids vessel_id vessel_type \\\n", + "0 2022-01 1 None None 1 None None \n", + "1 2022-03 3 RUS None None 3 None None \n", + "2 2022-04 1 RUS None None 1 None None \n", + "3 2022-02 2 GRC None None 2 None None \n", + "4 2022-01 1 MLT None None 1 None None \n", "\n", - " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", - "0 None None None None \n", - "1 None None None None \n", - "2 None None None None \n", - "3 None None None None \n", - "4 None None None None \n", + " entry_timestamp exit_timestamp first_transmission_date \\\n", + "0 None None None \n", + "1 None None None \n", + "2 None None None \n", + "3 None None None \n", + "4 None None None \n", "\n", " last_transmission_date imo mmsi call_sign dataset \\\n", "0 None None None None None \n", @@ -1099,11 +1101,11 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-sar-presence:v3.0 None 46.3 142.4 \n", - "1 public-global-sar-presence:v3.0 None 46.0 143.7 \n", - "2 public-global-sar-presence:v3.0 None 46.7 141.7 \n", - "3 public-global-sar-presence:v3.0 None 49.1 144.4 \n", - "4 public-global-sar-presence:v3.0 None 49.3 141.8 " + "0 public-global-sar-presence:v3.0 None 44.6 38.0 \n", + "1 public-global-sar-presence:v3.0 None 46.7 141.8 \n", + "2 public-global-sar-presence:v3.0 None 46.8 141.4 \n", + "3 public-global-sar-presence:v3.0 None 44.2 37.4 \n", + "4 public-global-sar-presence:v3.0 None 43.8 38.7 " ] }, "execution_count": 22, @@ -1133,6 +1135,14 @@ "Generates a report for any [supported datasets](https://globalfishingwatch.org/our-apis/documentation#supported-datasets), using fully customizable parameters. [Please check the data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat)." ] }, + { + "cell_type": "markdown", + "id": "ef93b16e-2374-44b3-84f1-afe681df336b", + "metadata": {}, + "source": [ + "**Note:** AIS vessel presence (i.e., `\"public-global-sar-presence:latest\"` dataset) does **not** support `\"GEARTYPE\"` or `\"FLAGANDGEARTYPE\"` as `group_by` criteria." + ] + }, { "cell_type": "code", "execution_count": 23, @@ -1145,7 +1155,7 @@ "report_result = await gfw_client.fourwings.create_report(\n", " spatial_resolution=\"LOW\",\n", " temporal_resolution=\"MONTHLY\",\n", - " group_by=\"GEARTYPE\",\n", + " group_by=\"FLAG\",\n", " datasets=[\"public-global-fishing-effort:latest\"],\n", " start_date=\"2022-01-01\",\n", " end_date=\"2022-05-01\",\n", @@ -1205,7 +1215,7 @@ { "data": { "text/plain": [ - "('2022-04', 'fishing', 2.705, 1, 52.0, 155.2)" + "('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0)" ] }, "execution_count": 26, @@ -1216,7 +1226,7 @@ "source": [ "(\n", " report_item.date,\n", - " report_item.gear_type,\n", + " report_item.flag,\n", " report_item.hours,\n", " report_item.vessel_ids,\n", " report_item.lat,\n", @@ -1305,12 +1315,12 @@ " \n", " \n", " 0\n", - " 2022-01\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 2.848333\n", - " 1\n", + " 3.416944\n", + " 2\n", " None\n", " None\n", " None\n", @@ -1323,17 +1333,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 58.5\n", - " 149.2\n", + " 75.6\n", + " 50.3\n", " \n", " \n", " 1\n", - " 2022-03\n", + " 2022-02\n", " None\n", + " RUS\n", " None\n", - " fishing\n", - " 1.305710\n", - " 1\n", + " 2.144444\n", + " 3\n", " None\n", " None\n", " None\n", @@ -1346,17 +1356,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 55.6\n", - " 153.8\n", + " 51.4\n", + " 155.4\n", " \n", " \n", " 2\n", - " 2022-02\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 20.537500\n", - " 13\n", + " 5.436944\n", + " 2\n", " None\n", " None\n", " None\n", @@ -1369,17 +1379,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 54.9\n", - " 152.7\n", + " 58.6\n", + " 155.8\n", " \n", " \n", " 3\n", - " 2022-02\n", + " 2022-01\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 5.952222\n", - " 3\n", + " 4.435556\n", + " 1\n", " None\n", " None\n", " None\n", @@ -1392,16 +1402,16 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 56.1\n", - " 144.4\n", + " 45.7\n", + " 149.8\n", " \n", " \n", " 4\n", - " 2022-01\n", + " 2022-03\n", " None\n", + " RUS\n", " None\n", - " trawlers\n", - " 1.951944\n", + " 0.362778\n", " 1\n", " None\n", " None\n", @@ -1415,20 +1425,20 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 51.7\n", - " 154.1\n", + " 46.7\n", + " 141.9\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-01 None None trawlers 2.848333 1 None \n", - "1 2022-03 None None fishing 1.305710 1 None \n", - "2 2022-02 None None trawlers 20.537500 13 None \n", - "3 2022-02 None None trawlers 5.952222 3 None \n", - "4 2022-01 None None trawlers 1.951944 1 None \n", + " date detections flag gear_type hours vessel_ids vessel_id \\\n", + "0 2022-03 None RUS None 3.416944 2 None \n", + "1 2022-02 None RUS None 2.144444 3 None \n", + "2 2022-03 None RUS None 5.436944 2 None \n", + "3 2022-01 None RUS None 4.435556 1 None \n", + "4 2022-03 None RUS None 0.362778 1 None \n", "\n", " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", "0 None None None None \n", @@ -1445,11 +1455,11 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-fishing-effort:v3.0 None 58.5 149.2 \n", - "1 public-global-fishing-effort:v3.0 None 55.6 153.8 \n", - "2 public-global-fishing-effort:v3.0 None 54.9 152.7 \n", - "3 public-global-fishing-effort:v3.0 None 56.1 144.4 \n", - "4 public-global-fishing-effort:v3.0 None 51.7 154.1 " + "0 public-global-fishing-effort:v3.0 None 75.6 50.3 \n", + "1 public-global-fishing-effort:v3.0 None 51.4 155.4 \n", + "2 public-global-fishing-effort:v3.0 None 58.6 155.8 \n", + "3 public-global-fishing-effort:v3.0 None 45.7 149.8 \n", + "4 public-global-fishing-effort:v3.0 None 46.7 141.9 " ] }, "execution_count": 28, diff --git a/src/gfwapiclient/resources/fourwings/resources.py b/src/gfwapiclient/resources/fourwings/resources.py index 6551647..a632c88 100644 --- a/src/gfwapiclient/resources/fourwings/resources.py +++ b/src/gfwapiclient/resources/fourwings/resources.py @@ -227,7 +227,7 @@ async def create_ais_presence_report( group_by (Optional[Union[FourWingsReportGroupBy, str]], default=None): Grouping criteria for the report. Defaults to `None`. - Allowed values: `"VESSEL_ID"`, `"FLAG"`, `"GEARTYPE"`, `"FLAGANDGEARTYPE"`, `"MMSI"`. + Allowed values: `"VESSEL_ID"`, `"FLAG"`, `"MMSI"`. Example: `"FLAG"`. temporal_resolution (Optional[Union[FourWingsReportTemporalResolution, str]], default="HOURLY"): @@ -463,6 +463,11 @@ async def create_report( and ensure optimal performance, keep requests manageable: prefer simple, small regions and shorter time ranges (e.g., a few days). + **Note:** + + AIS vessel presence (i.e., `"public-global-sar-presence:latest"` dataset) does **not** + support `"GEARTYPE"` or `"FLAGANDGEARTYPE"` as `group_by` criteria. + Args: spatial_resolution (Optional[Union[FourWingsReportSpatialResolution, str]], default="HIGH"): Spatial resolution of the report. Defaults to `"HIGH"`. From 066f48359c1f1ccdfd4211a5cf908ad1717c7d33 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 8 Jan 2026 14:03:14 +0300 Subject: [PATCH 14/22] docs: update prerequisites with access token and getting started links --- docs/source/usage-guides/4wings-api.md | 2 +- docs/source/usage-guides/datasets-api.md | 2 +- docs/source/usage-guides/events-api.md | 2 +- docs/source/usage-guides/insights-api.md | 2 +- .../usage-guides/references-data-api.md | 2 +- docs/source/usage-guides/vessels-api.md | 2 +- notebooks/getting-started.ipynb | 22 +++++++++---------- notebooks/usage-guides/4wings-api.ipynb | 2 +- notebooks/usage-guides/datasets-api.ipynb | 2 +- notebooks/usage-guides/events-api.ipynb | 2 +- notebooks/usage-guides/insights-api.ipynb | 2 +- .../usage-guides/references-data-api.ipynb | 2 +- notebooks/usage-guides/vessels-api.ipynb | 2 +- 13 files changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 108f682..748f00b 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). ## Getting Started diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 43e0569..0c1e96f 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). ## Getting Started diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index 1bc62ef..c570a91 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). ## Getting Started diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 6d4354a..5208c2b 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). - You will need a valid `Vessel ID` to retrieve insights for a specific vessel. You can obtain these IDs using the [Vessels API](vessels-api). diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index 95a4f45..1290a74 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). ## Getting Started diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index a3b4ea3..ec9ef6c 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-api.md @@ -8,7 +8,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Prerequisites -- You have installed the `gfw-api-python-client`. Refer to the [Getting Started](../getting-started) guide for installation instructions. +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). ## Getting Started diff --git a/notebooks/getting-started.ipynb b/notebooks/getting-started.ipynb index 9d1ab70..e02c500 100644 --- a/notebooks/getting-started.ipynb +++ b/notebooks/getting-started.ipynb @@ -56,7 +56,7 @@ "id": "7523e57e-6439-43cb-ae85-2bf789462453" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { @@ -378,12 +378,12 @@ " b45f90c9d26b298d740d981ff3989e9f\n", " fishing\n", " {'lat': 41.4282, 'lon': -69.0376}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAMMCO'...\n", + " {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ...\n", " [-69.09002, 41.356445, -69.013173, 41.455082]\n", " {'start_distance_from_shore_km': 74.0, 'end_di...\n", " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", " None\n", - " {'total_distance_km': 20.67347342859376, 'aver...\n", + " {'total_distance_km': 20.673473428593752, 'ave...\n", " None\n", " None\n", " None\n", @@ -395,7 +395,7 @@ " f126f405f67d32f6488dbff9c828ca86\n", " fishing\n", " {'lat': 40.9922, 'lon': -68.2989}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAMMCO'...\n", + " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAFO', ...\n", " [-68.444835, 40.96636, -68.237482, 41.062727]\n", " {'start_distance_from_shore_km': 133.0, 'end_d...\n", " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", @@ -412,12 +412,12 @@ " 5a78695b7c9e56e511c40d058dd07e20\n", " fishing\n", " {'lat': 41.2956, 'lon': -69.0377}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ...\n", + " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NASCO',...\n", " [-69.116493, 41.278087, -69.014402, 41.368413]\n", " {'start_distance_from_shore_km': 71.0, 'end_di...\n", " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", " None\n", - " {'total_distance_km': 16.614674434708487, 'ave...\n", + " {'total_distance_km': 16.61467443470849, 'aver...\n", " None\n", " None\n", " None\n", @@ -443,9 +443,9 @@ "2 {'lat': 41.2956, 'lon': -69.0377} \n", "\n", " regions \\\n", - "0 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAMMCO'... \n", - "1 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAMMCO'... \n", - "2 {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ... \n", + "0 {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ... \n", + "1 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAFO', ... \n", + "2 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NASCO',... \n", "\n", " bounding_box \\\n", "0 [-69.09002, 41.356445, -69.013173, 41.455082] \n", @@ -463,9 +463,9 @@ "2 {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'... None \n", "\n", " fishing gap loitering \\\n", - "0 {'total_distance_km': 20.67347342859376, 'aver... None None \n", + "0 {'total_distance_km': 20.673473428593752, 'ave... None None \n", "1 {'total_distance_km': 22.543354447253645, 'ave... None None \n", - "2 {'total_distance_km': 16.614674434708487, 'ave... None None \n", + "2 {'total_distance_km': 16.61467443470849, 'aver... None None \n", "\n", " port_visit \n", "0 None \n", diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index a20a48d..d825bef 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -56,7 +56,7 @@ "id": "57109889-5f3f-45b3-a594-2f82b94bcadb" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { diff --git a/notebooks/usage-guides/datasets-api.ipynb b/notebooks/usage-guides/datasets-api.ipynb index 6746eb6..41f53ea 100644 --- a/notebooks/usage-guides/datasets-api.ipynb +++ b/notebooks/usage-guides/datasets-api.ipynb @@ -56,7 +56,7 @@ "id": "a5b0d532-a373-4082-b860-3ad9ebc90a45" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { diff --git a/notebooks/usage-guides/events-api.ipynb b/notebooks/usage-guides/events-api.ipynb index 69982ee..0893d10 100644 --- a/notebooks/usage-guides/events-api.ipynb +++ b/notebooks/usage-guides/events-api.ipynb @@ -56,7 +56,7 @@ "id": "57109889-5f3f-45b3-a594-2f82b94bcadb" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 766d5ec..87f69f4 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -56,7 +56,7 @@ "id": "57109889-5f3f-45b3-a594-2f82b94bcadb" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { diff --git a/notebooks/usage-guides/references-data-api.ipynb b/notebooks/usage-guides/references-data-api.ipynb index 55bf077..49fa4c2 100644 --- a/notebooks/usage-guides/references-data-api.ipynb +++ b/notebooks/usage-guides/references-data-api.ipynb @@ -56,7 +56,7 @@ "id": "cda8a081-5851-4926-adc4-fe09a82b6221" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index 59ec9fe..501d764 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -56,7 +56,7 @@ "id": "57109889-5f3f-45b3-a594-2f82b94bcadb" }, "source": [ - "Before using the `gfw-api-python-client`, you need to obtain an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)" + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." ] }, { From 84fbc86736871f70657522ddc7c1f0a6b2d610a2 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Thu, 8 Jan 2026 19:02:06 +0300 Subject: [PATCH 15/22] docs: add vessel and insights API examples on getting started guide --- docs/source/getting-started.md | 141 ++- notebooks/getting-started.ipynb | 873 ++++++++++++++++-- notebooks/usage-guides/insights-api.ipynb | 8 + notebooks/usage-guides/vessels-api.ipynb | 95 +- .../resources/insights/resources.py | 2 +- 5 files changed, 962 insertions(+), 157 deletions(-) diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index 7933bee..9bccd24 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -42,10 +42,13 @@ For more detailed installation instructions, including setting up a virtual envi ## Basic Usage +Open In Colab + Once installed, you can import and use `gfw-api-python-client` in your Python codes: ```python import os +import datetime import gfwapiclient as gfw @@ -66,15 +69,38 @@ gfw_client = gfw.Client( ```python vessel_search_result = await gfw_client.vessels.search_vessels( - query="368045130", - datasets=["public-global-vessel-identity:latest"], - includes=["MATCH_CRITERIA", "OWNERSHIP", "AUTHORIZATIONS"], + query="412331038", ) -vessel_ids = [ +vessel_search_ids = [ self_reported_info.id - for vessel in vessel_search_result.data() - for self_reported_info in vessel.self_reported_info + for vessel_search_item in vessel_search_result.data() + if vessel_search_item.registry_info_total_records >= 1 + for self_reported_info in vessel_search_item.self_reported_info +] + +print(vessel_search_ids) +``` + +**Output:** + +``` +['755a48dd4-4bee-4bcf-7b5f-9baea058fc7b', '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'] +``` + +**Note:** It is recommended to prioritize vessels that include both `registry_info` and `self_reported_info` (AIS), as this indicates a successful match between registry data and AIS information. + +### Getting Details of Vessels Filtered by Vessel Searched IDs + +```python +vessels_result = await gfw_client.vessels.get_vessels_by_ids( + ids=vessel_search_ids, +) + +vessel_self_reported_infos = [ + self_reported_info + for vessel_item in vessels_result.data() + for self_reported_info in vessel_item.self_reported_info ] print(vessel_ids) @@ -83,16 +109,85 @@ print(vessel_ids) **Output:** ``` -["3312b30d6-65b6-1bdb-6a78-3f5eb3977e58", "126221ace-e3b5-f4ed-6150-394809737c55"] +['755a48dd4-4bee-4bcf-7b5f-9baea058fc7b', '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'] ``` -### Getting Fishing Events for the Searched Vessels +### Getting Insights Related to Fishing Events for the Vessel Searched + +**Important:** `start_date` must be on or after `January 1, 2020` + +```python +start_datetime = min( + [ + self_reported_info.transmission_date_from + for self_reported_info in vessel_self_reported_infos + ] +) +start_date = start_datetime.date() + + +end_datetime = max( + [ + self_reported_info.transmission_date_to + for self_reported_info in vessel_self_reported_infos + ] +) +end_date = end_datetime.date() + +dataset_id = "public-global-vessel-identity:latest" +dataset_ids_vessel_ids = [ + {"dataset_id": dataset_id, "vessel_id": vessel_id} for vessel_id in vessel_ids +] + +insights_result = await gfw_client.insights.get_vessel_insights( + includes=["FISHING"], + start_date=start_date, + end_date=end_date, + vessels=dataset_ids_vessel_ids, +) + +insights_df = insights_result.df() + +print(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 1 non-null object + 5 vessel_identity 0 non-null object +dtypes: object(6) +memory usage: 180.0+ bytes +``` + +```python +insights_data = insights_result.data() + +print(dict(insights_data.apparent_fishing.period_selected_counters)) +``` + +**Output:** + +``` +{'events': 398, 'events_gap_off': None, 'events_in_rfmo_without_known_authorization': 144, 'events_in_no_take_mpas': 0} +``` + +### Getting Fishing Events for the Vessels Searched ```python events_result = await gfw_client.events.get_all_events( datasets=["public-global-fishing-events:latest"], - start_date="2024-03-01", - end_date="2025-03-31", + start_date=start_date, + end_date=end_date, vessels=vessel_ids, ) @@ -101,30 +196,30 @@ events_df = events_result.df() print(events_df.info()) ``` -Output: +**Output:** ``` -RangeIndex: 3 entries, 0 to 2 +RangeIndex: 398 entries, 0 to 397 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 start 3 non-null datetime64[ns, UTC] - 1 end 3 non-null datetime64[ns, UTC] - 2 id 3 non-null object - 3 type 3 non-null object - 4 position 3 non-null object - 5 regions 3 non-null object - 6 bounding_box 3 non-null object - 7 distances 3 non-null object - 8 vessel 3 non-null object + 0 start 398 non-null datetime64[ns, UTC] + 1 end 398 non-null datetime64[ns, UTC] + 2 id 398 non-null object + 3 type 398 non-null object + 4 position 398 non-null object + 5 regions 398 non-null object + 6 bounding_box 398 non-null object + 7 distances 398 non-null object + 8 vessel 398 non-null object 9 encounter 0 non-null object - 10 fishing 3 non-null object + 10 fishing 398 non-null object 11 gap 0 non-null object 12 loitering 0 non-null object 13 port_visit 0 non-null object dtypes: datetime64[ns, UTC](2), object(12) -memory usage: 468.0+ bytes +memory usage: 43.7+ KB ``` ## Next Steps diff --git a/notebooks/getting-started.ipynb b/notebooks/getting-started.ipynb index e02c500..4be4609 100644 --- a/notebooks/getting-started.ipynb +++ b/notebooks/getting-started.ipynb @@ -121,6 +121,8 @@ "outputs": [], "source": [ "import os\n", + "import datetime\n", + "import pandas as pd\n", "import gfwapiclient as gfw" ] }, @@ -187,31 +189,398 @@ "outputs": [], "source": [ "vessel_search_result = await gfw_client.vessels.search_vessels(\n", - " query=\"368045130\",\n", - " datasets=[\"public-global-vessel-identity:latest\"],\n", - " includes=[\"MATCH_CRITERIA\", \"OWNERSHIP\", \"AUTHORIZATIONS\"],\n", + " query=\"412331038\",\n", ")" ] }, { "cell_type": "code", "execution_count": 6, - "id": "44a0cd8d-4ec6-4163-8ecc-90d9a1300641", - "metadata": { - "id": "44a0cd8d-4ec6-4163-8ecc-90d9a1300641" - }, + "id": "9e2d4dae-455b-43ca-81ed-dea8917b1b23", + "metadata": {}, "outputs": [], "source": [ - "vessel_ids = [\n", + "vessel_search_df = vessel_search_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5a970cc1-2f4e-424b-a7bb-b92f935cfbe7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 5 entries, 0 to 4\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 5 non-null object\n", + " 1 registry_info_total_records 5 non-null int64 \n", + " 2 registry_info 5 non-null object\n", + " 3 registry_owners 5 non-null object\n", + " 4 registry_public_authorizations 5 non-null object\n", + " 5 combined_sources_info 5 non-null object\n", + " 6 self_reported_info 5 non-null object\n", + " 7 matchCriteria 5 non-null object\n", + "dtypes: int64(1), object(7)\n", + "memory usage: 452.0+ bytes\n" + ] + } + ], + "source": [ + "vessel_search_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "17b0c17c-92e0-49e1-9aaa-0831d4de567c", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
datasetregistry_info_total_recordsregistry_inforegistry_ownersregistry_public_authorizationscombined_sources_infoself_reported_infomatchCriteria
0public-global-vessel-identity:v3.00[][][][{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f...[{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2...[{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f...
1public-global-vessel-identity:v3.01[{'id': '4ef90bea19300c6a23f6ce627a80238b', 's...[{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',...[{'date_from': 2017-01-04 00:00:00+00:00, 'dat...[{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea...[{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b...[{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea...
2public-global-vessel-identity:v3.00[][][][{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c...[{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff...[{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c...
3public-global-vessel-identity:v3.00[][][][{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d...[{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741...[{'reference': '108c5510b-b6aa-9cf2-8b86-0598d...
4public-global-vessel-identity:v3.00[][][][{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75...[{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80...[{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75...
\n", + "
" + ], + "text/plain": [ + " dataset registry_info_total_records \\\n", + "0 public-global-vessel-identity:v3.0 0 \n", + "1 public-global-vessel-identity:v3.0 1 \n", + "2 public-global-vessel-identity:v3.0 0 \n", + "3 public-global-vessel-identity:v3.0 0 \n", + "4 public-global-vessel-identity:v3.0 0 \n", + "\n", + " registry_info \\\n", + "0 [] \n", + "1 [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's... \n", + "2 [] \n", + "3 [] \n", + "4 [] \n", + "\n", + " registry_owners \\\n", + "0 [] \n", + "1 [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',... \n", + "2 [] \n", + "3 [] \n", + "4 [] \n", + "\n", + " registry_public_authorizations \\\n", + "0 [] \n", + "1 [{'date_from': 2017-01-04 00:00:00+00:00, 'dat... \n", + "2 [] \n", + "3 [] \n", + "4 [] \n", + "\n", + " combined_sources_info \\\n", + "0 [{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", + "1 [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", + "2 [{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", + "3 [{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d... \n", + "4 [{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75... \n", + "\n", + " self_reported_info \\\n", + "0 [{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2... \n", + "1 [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b... \n", + "2 [{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff... \n", + "3 [{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741... \n", + "4 [{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80... \n", + "\n", + " matchCriteria \n", + "0 [{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", + "1 [{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", + "2 [{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", + "3 [{'reference': '108c5510b-b6aa-9cf2-8b86-0598d... \n", + "4 [{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75... " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vessel_search_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3b34b0b1-c631-42c0-8950-d87234e68e87", + "metadata": {}, + "source": [ + "**Note:** It is recommended to prioritize vessels that include both `registry_info` and `self_reported_info` (AIS), as this indicates a successful match between registry data and AIS information." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "49b4c9fd-0d95-4259-a124-4e1f0193cd92", + "metadata": {}, + "outputs": [], + "source": [ + "vessel_search_ids = [\n", " self_reported_info.id\n", - " for vessel in vessel_search_result.data()\n", - " for self_reported_info in vessel.self_reported_info\n", + " for vessel_search_item in vessel_search_result.data()\n", + " if vessel_search_item.registry_info_total_records >= 1\n", + " for self_reported_info in vessel_search_item.self_reported_info\n", "]" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, + "id": "9ecd48fb-11e3-45b6-ac50-f16b81f7f1b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['755a48dd4-4bee-4bcf-7b5f-9baea058fc7b',\n", + " '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f']" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vessel_search_ids" + ] + }, + { + "cell_type": "markdown", + "id": "f72bc72f-8a94-425d-9a38-8dabc7947b05", + "metadata": {}, + "source": [ + "### Getting Details of Vessels Filtered by Vessel Searched IDs" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "19e6add8-e0a8-42e5-a2b9-8291026cf48d", + "metadata": {}, + "outputs": [], + "source": [ + "vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=vessel_search_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "6aded3f4-69c3-47ec-8a6a-4d672fc56356", + "metadata": {}, + "outputs": [], + "source": [ + "vessels_df = vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "c131c32f-1cc1-4bf8-83d3-4d559153d150", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 1 non-null object\n", + " 1 registry_info_total_records 1 non-null int64 \n", + " 2 registry_info 1 non-null object\n", + " 3 registry_owners 1 non-null object\n", + " 4 registry_public_authorizations 1 non-null object\n", + " 5 combined_sources_info 1 non-null object\n", + " 6 self_reported_info 1 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 188.0+ bytes\n" + ] + } + ], + "source": [ + "vessels_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "40c56dc8-09a0-48d5-9a93-fdca34815a27", + "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", + " \n", + " \n", + "
datasetregistry_info_total_recordsregistry_inforegistry_ownersregistry_public_authorizationscombined_sources_infoself_reported_info
0public-global-vessel-identity:v3.01[{'id': '4ef90bea19300c6a23f6ce627a80238b', 's...[{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',...[{'date_from': 2017-01-04 00:00:00+00:00, 'dat...[{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea...[{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b...
\n", + "
" + ], + "text/plain": [ + " dataset registry_info_total_records \\\n", + "0 public-global-vessel-identity:v3.0 1 \n", + "\n", + " registry_info \\\n", + "0 [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',... \n", + "\n", + " registry_public_authorizations \\\n", + "0 [{'date_from': 2017-01-04 00:00:00+00:00, 'dat... \n", + "\n", + " combined_sources_info \\\n", + "0 [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", + "\n", + " self_reported_info \n", + "0 [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b... " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vessels_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, "id": "522a618d-140e-4d36-9e18-b71e81d1c40e", "metadata": { "colab": { @@ -220,15 +589,41 @@ "id": "522a618d-140e-4d36-9e18-b71e81d1c40e", "outputId": "ee9a5ca8-f994-4357-f748-d1140bb29f9a" }, + "outputs": [], + "source": [ + "vessel_self_reported_infos = [\n", + " self_reported_info\n", + " for vessel_item in vessels_result.data()\n", + " for self_reported_info in vessel_item.self_reported_info\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "e35272d9-7758-4abc-bb24-a112647c8fc9", + "metadata": {}, + "outputs": [], + "source": [ + "vessel_ids = [\n", + " self_reported_info.id for self_reported_info in vessel_self_reported_infos\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "05a96294-7009-477f-9175-f2653d10b989", + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['3312b30d6-65b6-1bdb-6a78-3f5eb3977e58',\n", - " '126221ace-e3b5-f4ed-6150-394809737c55']" + "['755a48dd4-4bee-4bcf-7b5f-9baea058fc7b',\n", + " '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f']" ] }, - "execution_count": 7, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -237,6 +632,256 @@ "vessel_ids" ] }, + { + "cell_type": "markdown", + "id": "ef5c4cd5-c8b0-440b-8177-67741714b574", + "metadata": {}, + "source": [ + "### Getting Insights Related to Fishing Events for the Vessel Searched" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "89f02bda-8318-43e3-8b28-fa85d42772e9", + "metadata": {}, + "outputs": [], + "source": [ + "start_datetime = min(\n", + " [\n", + " self_reported_info.transmission_date_from\n", + " for self_reported_info in vessel_self_reported_infos\n", + " ]\n", + ")\n", + "start_date = start_datetime.date()" + ] + }, + { + "cell_type": "markdown", + "id": "4fee4e40-4ec0-406d-aa4e-3de9e6224c55", + "metadata": {}, + "source": [ + "**Important:** `start_date` must be on or after `January 1, 2020`" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "ba29290c-d0c2-4150-8650-7851cb4fe097", + "metadata": {}, + "outputs": [], + "source": [ + "start_date = max(start_date, datetime.date.fromisoformat(\"2020-01-01\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e2b49d3e-4317-4866-adcd-78e51662c89d", + "metadata": {}, + "outputs": [], + "source": [ + "end_datetime = max(\n", + " [\n", + " self_reported_info.transmission_date_to\n", + " for self_reported_info in vessel_self_reported_infos\n", + " ]\n", + ")\n", + "end_date = end_datetime.date()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "629f5ca9-ff9f-4d09-bfe8-e01b7af6f6c3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(datetime.date(2020, 1, 1), datetime.date(2026, 1, 4))" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "start_date, end_date" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "2d331aeb-370e-4039-aa46-75a10e2d0a18", + "metadata": {}, + "outputs": [], + "source": [ + "dataset_id = \"public-global-vessel-identity:latest\"\n", + "dataset_ids_vessel_ids = [\n", + " {\"dataset_id\": dataset_id, \"vessel_id\": vessel_id} for vessel_id in vessel_ids\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "cd5725f5-57ca-4620-9946-d3cf4ea153b1", + "metadata": {}, + "outputs": [], + "source": [ + "insights_result = await gfw_client.insights.get_vessel_insights(\n", + " includes=[\"FISHING\"],\n", + " start_date=start_date,\n", + " end_date=end_date,\n", + " vessels=dataset_ids_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "15f1a28c-215d-4cef-b62e-84f029fecfd1", + "metadata": {}, + "outputs": [], + "source": [ + "insights_df = insights_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "cca3b40f-8f19-4715-a91e-0e86c2d2588e", + "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": [ + "insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "be8dd7ac-b8d7-4c3d-9fe6-157831a8a7b9", + "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': 2026-01...NoneNoneNone{'datasets': ['public-global-fishing-events:v3...None
\n", + "
" + ], + "text/plain": [ + " period \\\n", + "0 {'start_date': 2020-01-01, 'end_date': 2026-01... \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:v3... None " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "insights_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "7eb5f9e3-57b8-44b7-bf5e-3091cb9c0033", + "metadata": {}, + "outputs": [], + "source": [ + "insights_data = insights_result.data()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "53704e62-9e21-4182-bab6-058e4e297fe6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'events': 398,\n", + " 'events_gap_off': None,\n", + " 'events_in_rfmo_without_known_authorization': 144,\n", + " 'events_in_no_take_mpas': 0}" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dict(insights_data.apparent_fishing.period_selected_counters)" + ] + }, { "cell_type": "markdown", "id": "38d7148a-23dc-4a7b-8aa2-27a79f49bea9", @@ -244,12 +889,12 @@ "id": "38d7148a-23dc-4a7b-8aa2-27a79f49bea9" }, "source": [ - "### Getting Fishing Events for the Searched Vessels" + "### Getting Fishing Events for the Vessels Searched" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 29, "id": "b078ce74-f2d1-4ec3-a163-b3961407e497", "metadata": { "id": "b078ce74-f2d1-4ec3-a163-b3961407e497" @@ -258,15 +903,15 @@ "source": [ "events_result = await gfw_client.events.get_all_events(\n", " datasets=[\"public-global-fishing-events:latest\"],\n", - " start_date=\"2024-03-01\",\n", - " end_date=\"2025-03-31\",\n", + " start_date=start_date,\n", + " end_date=end_date,\n", " vessels=vessel_ids,\n", ")" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 30, "id": "8b1c4289-5896-4590-8d6e-7405bb0037f8", "metadata": { "id": "8b1c4289-5896-4590-8d6e-7405bb0037f8" @@ -278,7 +923,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 31, "id": "8a1f2985-e849-4e7c-8a7e-77afcba17764", "metadata": { "colab": { @@ -293,26 +938,26 @@ "output_type": "stream", "text": [ "\n", - "RangeIndex: 3 entries, 0 to 2\n", + "RangeIndex: 398 entries, 0 to 397\n", "Data columns (total 14 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", - " 0 start 3 non-null datetime64[ns, UTC]\n", - " 1 end 3 non-null datetime64[ns, UTC]\n", - " 2 id 3 non-null object \n", - " 3 type 3 non-null object \n", - " 4 position 3 non-null object \n", - " 5 regions 3 non-null object \n", - " 6 bounding_box 3 non-null object \n", - " 7 distances 3 non-null object \n", - " 8 vessel 3 non-null object \n", + " 0 start 398 non-null datetime64[ns, UTC]\n", + " 1 end 398 non-null datetime64[ns, UTC]\n", + " 2 id 398 non-null object \n", + " 3 type 398 non-null object \n", + " 4 position 398 non-null object \n", + " 5 regions 398 non-null object \n", + " 6 bounding_box 398 non-null object \n", + " 7 distances 398 non-null object \n", + " 8 vessel 398 non-null object \n", " 9 encounter 0 non-null object \n", - " 10 fishing 3 non-null object \n", + " 10 fishing 398 non-null object \n", " 11 gap 0 non-null object \n", " 12 loitering 0 non-null object \n", " 13 port_visit 0 non-null object \n", "dtypes: datetime64[ns, UTC](2), object(12)\n", - "memory usage: 468.0+ bytes\n" + "memory usage: 43.7+ KB\n" ] } ], @@ -322,7 +967,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 32, "id": "ff424bc9-bb00-4bc6-a8e3-ee01346786c8", "metadata": { "colab": { @@ -373,51 +1018,85 @@ " \n", " \n", " 0\n", - " 2024-03-02 07:20:58+00:00\n", - " 2024-03-02 16:31:16+00:00\n", - " b45f90c9d26b298d740d981ff3989e9f\n", + " 2025-12-21 22:54:19+00:00\n", + " 2025-12-22 01:59:26+00:00\n", + " 20722d55b7a106978e2b55e65f7affa6\n", " fishing\n", - " {'lat': 41.4282, 'lon': -69.0376}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ...\n", - " [-69.09002, 41.356445, -69.013173, 41.455082]\n", - " {'start_distance_from_shore_km': 74.0, 'end_di...\n", - " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", + " {'lat': -45.734, 'lon': -60.6275}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'...\n", + " [-60.638205, -45.736243333333334, -60.622215, ...\n", + " {'start_distance_from_shore_km': 390.0, 'end_d...\n", + " {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'...\n", " None\n", - " {'total_distance_km': 20.673473428593752, 'ave...\n", + " {'total_distance_km': 1.553408717842079, 'aver...\n", " None\n", " None\n", " None\n", " \n", " \n", " 1\n", - " 2024-04-08 22:29:41+00:00\n", - " 2024-04-09 01:56:10+00:00\n", - " f126f405f67d32f6488dbff9c828ca86\n", + " 2020-05-29 15:38:07+00:00\n", + " 2020-05-29 19:22:03+00:00\n", + " aa6f570aee327010bd4714aa6e459d08\n", " fishing\n", - " {'lat': 40.9922, 'lon': -68.2989}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAFO', ...\n", - " [-68.444835, 40.96636, -68.237482, 41.062727]\n", - " {'start_distance_from_shore_km': 133.0, 'end_d...\n", - " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", + " {'lat': 41.4151, 'lon': 165.5954}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['NPAFC', 'PICE...\n", + " [165.58234666666667, 41.404185, 165.602265, 41...\n", + " {'start_distance_from_shore_km': 1213.0, 'end_...\n", + " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 22.543354447253645, 'ave...\n", + " {'total_distance_km': 3.2539329459390007, 'ave...\n", " None\n", " None\n", " None\n", " \n", " \n", " 2\n", - " 2024-04-06 06:24:38+00:00\n", - " 2024-04-06 10:44:37+00:00\n", - " 5a78695b7c9e56e511c40d058dd07e20\n", + " 2025-12-31 23:00:02+00:00\n", + " 2026-01-01 07:57:31+00:00\n", + " 82ab07bcb2f0881dbdc2bea176f4d0eb\n", + " fishing\n", + " {'lat': -45.7853, 'lon': -60.6598}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'CCSBT...\n", + " [-60.66967666666667, -45.80526166666667, -60.6...\n", + " {'start_distance_from_shore_km': 390.0, 'end_d...\n", + " {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'...\n", + " None\n", + " {'total_distance_km': 5.18218418253593, 'avera...\n", + " None\n", + " None\n", + " None\n", + " \n", + " \n", + " 3\n", + " 2021-03-23 22:31:06+00:00\n", + " 2021-03-24 06:45:12+00:00\n", + " 634e0f958283315e9850e1523e6f7a88\n", + " fishing\n", + " {'lat': -41.9474, 'lon': -57.9515}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'...\n", + " [-57.89071, -41.96338333333333, -57.9833649999...\n", + " {'start_distance_from_shore_km': 377.0, 'end_d...\n", + " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", + " None\n", + " {'total_distance_km': 13.20298689870354, 'aver...\n", + " None\n", + " None\n", + " None\n", + " \n", + " \n", + " 4\n", + " 2022-06-17 12:52:22+00:00\n", + " 2022-06-17 18:55:39+00:00\n", + " 1c4ef3bc92b7a763c5f3b04d3a1a0779\n", " fishing\n", - " {'lat': 41.2956, 'lon': -69.0377}\n", - " {'mpa': [], 'eez': ['8456'], 'rfmo': ['NASCO',...\n", - " [-69.116493, 41.278087, -69.014402, 41.368413]\n", - " {'start_distance_from_shore_km': 71.0, 'end_di...\n", - " {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'...\n", + " {'lat': 42.8639, 'lon': 168.4996}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['WCPFC', 'NPAF...\n", + " [168.47266833333333, 42.858135, 168.5181933333...\n", + " {'start_distance_from_shore_km': 1122.0, 'end_...\n", + " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 16.61467443470849, 'aver...\n", + " {'total_distance_km': 4.430991184550807, 'aver...\n", " None\n", " None\n", " None\n", @@ -428,52 +1107,70 @@ ], "text/plain": [ " start end \\\n", - "0 2024-03-02 07:20:58+00:00 2024-03-02 16:31:16+00:00 \n", - "1 2024-04-08 22:29:41+00:00 2024-04-09 01:56:10+00:00 \n", - "2 2024-04-06 06:24:38+00:00 2024-04-06 10:44:37+00:00 \n", + "0 2025-12-21 22:54:19+00:00 2025-12-22 01:59:26+00:00 \n", + "1 2020-05-29 15:38:07+00:00 2020-05-29 19:22:03+00:00 \n", + "2 2025-12-31 23:00:02+00:00 2026-01-01 07:57:31+00:00 \n", + "3 2021-03-23 22:31:06+00:00 2021-03-24 06:45:12+00:00 \n", + "4 2022-06-17 12:52:22+00:00 2022-06-17 18:55:39+00:00 \n", "\n", " id type \\\n", - "0 b45f90c9d26b298d740d981ff3989e9f fishing \n", - "1 f126f405f67d32f6488dbff9c828ca86 fishing \n", - "2 5a78695b7c9e56e511c40d058dd07e20 fishing \n", + "0 20722d55b7a106978e2b55e65f7affa6 fishing \n", + "1 aa6f570aee327010bd4714aa6e459d08 fishing \n", + "2 82ab07bcb2f0881dbdc2bea176f4d0eb fishing \n", + "3 634e0f958283315e9850e1523e6f7a88 fishing \n", + "4 1c4ef3bc92b7a763c5f3b04d3a1a0779 fishing \n", "\n", - " position \\\n", - "0 {'lat': 41.4282, 'lon': -69.0376} \n", - "1 {'lat': 40.9922, 'lon': -68.2989} \n", - "2 {'lat': 41.2956, 'lon': -69.0377} \n", + " position \\\n", + "0 {'lat': -45.734, 'lon': -60.6275} \n", + "1 {'lat': 41.4151, 'lon': 165.5954} \n", + "2 {'lat': -45.7853, 'lon': -60.6598} \n", + "3 {'lat': -41.9474, 'lon': -57.9515} \n", + "4 {'lat': 42.8639, 'lon': 168.4996} \n", "\n", " regions \\\n", - "0 {'mpa': [], 'eez': ['8456'], 'rfmo': ['ACAP', ... \n", - "1 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NAFO', ... \n", - "2 {'mpa': [], 'eez': ['8456'], 'rfmo': ['NASCO',... \n", + "0 {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'... \n", + "1 {'mpa': [], 'eez': [], 'rfmo': ['NPAFC', 'PICE... \n", + "2 {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'CCSBT... \n", + "3 {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'... \n", + "4 {'mpa': [], 'eez': [], 'rfmo': ['WCPFC', 'NPAF... \n", "\n", - " bounding_box \\\n", - "0 [-69.09002, 41.356445, -69.013173, 41.455082] \n", - "1 [-68.444835, 40.96636, -68.237482, 41.062727] \n", - "2 [-69.116493, 41.278087, -69.014402, 41.368413] \n", + " bounding_box \\\n", + "0 [-60.638205, -45.736243333333334, -60.622215, ... \n", + "1 [165.58234666666667, 41.404185, 165.602265, 41... \n", + "2 [-60.66967666666667, -45.80526166666667, -60.6... \n", + "3 [-57.89071, -41.96338333333333, -57.9833649999... \n", + "4 [168.47266833333333, 42.858135, 168.5181933333... \n", "\n", " distances \\\n", - "0 {'start_distance_from_shore_km': 74.0, 'end_di... \n", - "1 {'start_distance_from_shore_km': 133.0, 'end_d... \n", - "2 {'start_distance_from_shore_km': 71.0, 'end_di... \n", + "0 {'start_distance_from_shore_km': 390.0, 'end_d... \n", + "1 {'start_distance_from_shore_km': 1213.0, 'end_... \n", + "2 {'start_distance_from_shore_km': 390.0, 'end_d... \n", + "3 {'start_distance_from_shore_km': 377.0, 'end_d... \n", + "4 {'start_distance_from_shore_km': 1122.0, 'end_... \n", "\n", " vessel encounter \\\n", - "0 {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'... None \n", - "1 {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'... None \n", - "2 {'id': '3312b30d6-65b6-1bdb-6a78-3f5eb3977e58'... None \n", + "0 {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'... None \n", + "1 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", + "2 {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'... None \n", + "3 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", + "4 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", "\n", " fishing gap loitering \\\n", - "0 {'total_distance_km': 20.673473428593752, 'ave... None None \n", - "1 {'total_distance_km': 22.543354447253645, 'ave... None None \n", - "2 {'total_distance_km': 16.61467443470849, 'aver... None None \n", + "0 {'total_distance_km': 1.553408717842079, 'aver... None None \n", + "1 {'total_distance_km': 3.2539329459390007, 'ave... None None \n", + "2 {'total_distance_km': 5.18218418253593, 'avera... None None \n", + "3 {'total_distance_km': 13.20298689870354, 'aver... None None \n", + "4 {'total_distance_km': 4.430991184550807, 'aver... None None \n", "\n", " port_visit \n", "0 None \n", "1 None \n", - "2 None " + "2 None \n", + "3 None \n", + "4 None " ] }, - "execution_count": 11, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 87f69f4..790a793 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -157,6 +157,14 @@ "## Getting Insights by Vessel (`get_vessel_insights`)" ] }, + { + "cell_type": "markdown", + "id": "ec5549cf-873a-4f34-9dd5-fd651ff85ef5", + "metadata": {}, + "source": [ + "**Important:** `start_date` must be on or after `January 1, 2020`" + ] + }, { "cell_type": "code", "execution_count": 5, diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index 501d764..6915924 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -222,7 +222,7 @@ { "data": { "text/plain": [ - "('public-global-vessel-identity:v3.0', 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff')" + "('public-global-vessel-identity:v3.0', 'c54923e64-46f3-9338-9dcb-ff09724077a3')" ] }, "execution_count": 8, @@ -308,9 +308,9 @@ " []\n", " []\n", " None\n", - " [{'vessel_id': 'c54923e64-46f3-9338-9dcb-ff097...\n", - " [{'id': 'c54923e64-46f3-9338-9dcb-ff09724077a3...\n", - " [{'reference': 'c54923e64-46f3-9338-9dcb-ff097...\n", + " [{'vessel_id': 'bae8f325c-cf0a-01fe-6d1a-9a275...\n", + " [{'id': 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff...\n", + " [{'reference': 'bae8f325c-cf0a-01fe-6d1a-9a275...\n", " \n", " \n", " 1\n", @@ -319,9 +319,9 @@ " []\n", " []\n", " None\n", - " [{'vessel_id': 'bae8f325c-cf0a-01fe-6d1a-9a275...\n", - " [{'id': 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff...\n", - " [{'reference': 'bae8f325c-cf0a-01fe-6d1a-9a275...\n", + " [{'vessel_id': 'c54923e64-46f3-9338-9dcb-ff097...\n", + " [{'id': 'c54923e64-46f3-9338-9dcb-ff09724077a3...\n", + " [{'reference': 'c54923e64-46f3-9338-9dcb-ff097...\n", " \n", " \n", "\n", @@ -337,16 +337,16 @@ "1 [] [] None \n", "\n", " combined_sources_info \\\n", - "0 [{'vessel_id': 'c54923e64-46f3-9338-9dcb-ff097... \n", - "1 [{'vessel_id': 'bae8f325c-cf0a-01fe-6d1a-9a275... \n", + "0 [{'vessel_id': 'bae8f325c-cf0a-01fe-6d1a-9a275... \n", + "1 [{'vessel_id': 'c54923e64-46f3-9338-9dcb-ff097... \n", "\n", " self_reported_info \\\n", - "0 [{'id': 'c54923e64-46f3-9338-9dcb-ff09724077a3... \n", - "1 [{'id': 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff... \n", + "0 [{'id': 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff... \n", + "1 [{'id': 'c54923e64-46f3-9338-9dcb-ff09724077a3... \n", "\n", " matchCriteria \n", - "0 [{'reference': 'c54923e64-46f3-9338-9dcb-ff097... \n", - "1 [{'reference': 'bae8f325c-cf0a-01fe-6d1a-9a275... " + "0 [{'reference': 'bae8f325c-cf0a-01fe-6d1a-9a275... \n", + "1 [{'reference': 'c54923e64-46f3-9338-9dcb-ff097... " ] }, "execution_count": 10, @@ -436,7 +436,7 @@ { "data": { "text/plain": [ - "('public-global-vessel-identity:v3.0', 'aca119c29-95dd-f5c4-2057-ee45268dcd6f')" + "('public-global-vessel-identity:v3.0', '55889aefb-bef9-224c-d2db-58ecd01e1d7c')" ] }, "execution_count": 14, @@ -467,7 +467,7 @@ }, "outputs": [], "source": [ - "vessel_search_df = vessels_result.df()" + "vessels_df = vessels_result.df()" ] }, { @@ -517,62 +517,67 @@ " \n", " 0\n", " public-global-vessel-identity:v3.0\n", - " 1\n", - " [{'id': '685862e0626f6234c844919bc738a83a', 's...\n", - " []\n", - " [{'date_from': 2012-01-01 00:00:00+00:00, 'dat...\n", - " [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd...\n", - " [{'id': '71e7da672-2451-17da-b239-857831602eca...\n", - " \n", - " \n", - " 1\n", - " public-global-vessel-identity:v3.0\n", - " 2\n", + " 5\n", " [{'id': 'a8d00ce54b37add7f85a35fcce8e7a1b', 's...\n", - " []\n", + " [{'name': 'COLINER', 'flag': 'RUS', 'ssvid': '...\n", " [{'date_from': 2023-01-01 00:00:00+00:00, 'dat...\n", " [{'vessel_id': '3c81a942b-bf0a-f476-ea72-75c02...\n", " [{'id': 'da1cd7e1b-b8d0-539c-6581-2b3df8d0a6af...\n", " \n", " \n", - " 2\n", + " 1\n", " public-global-vessel-identity:v3.0\n", " 2\n", " [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's...\n", - " []\n", + " [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ...\n", " [{'date_from': 2015-10-08 00:00:00+00:00, 'dat...\n", " [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452...\n", " [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c...\n", " \n", + " \n", + " 2\n", + " public-global-vessel-identity:v3.0\n", + " 1\n", + " [{'id': '685862e0626f6234c844919bc738a83a', 's...\n", + " [{'name': 'TRANS PACIFIC JOURNEY FISHING', 'fl...\n", + " [{'date_from': 2012-01-01 00:00:00+00:00, 'dat...\n", + " [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd...\n", + " [{'id': '71e7da672-2451-17da-b239-857831602eca...\n", + " \n", " \n", "\n", "" ], "text/plain": [ " dataset registry_info_total_records \\\n", - "0 public-global-vessel-identity:v3.0 1 \n", + "0 public-global-vessel-identity:v3.0 5 \n", "1 public-global-vessel-identity:v3.0 2 \n", - "2 public-global-vessel-identity:v3.0 2 \n", + "2 public-global-vessel-identity:v3.0 1 \n", "\n", - " registry_info registry_owners \\\n", - "0 [{'id': '685862e0626f6234c844919bc738a83a', 's... [] \n", - "1 [{'id': 'a8d00ce54b37add7f85a35fcce8e7a1b', 's... [] \n", - "2 [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's... [] \n", + " registry_info \\\n", + "0 [{'id': 'a8d00ce54b37add7f85a35fcce8e7a1b', 's... \n", + "1 [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's... \n", + "2 [{'id': '685862e0626f6234c844919bc738a83a', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'COLINER', 'flag': 'RUS', 'ssvid': '... \n", + "1 [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ... \n", + "2 [{'name': 'TRANS PACIFIC JOURNEY FISHING', 'fl... \n", "\n", " registry_public_authorizations \\\n", - "0 [{'date_from': 2012-01-01 00:00:00+00:00, 'dat... \n", - "1 [{'date_from': 2023-01-01 00:00:00+00:00, 'dat... \n", - "2 [{'date_from': 2015-10-08 00:00:00+00:00, 'dat... \n", + "0 [{'date_from': 2023-01-01 00:00:00+00:00, 'dat... \n", + "1 [{'date_from': 2015-10-08 00:00:00+00:00, 'dat... \n", + "2 [{'date_from': 2012-01-01 00:00:00+00:00, 'dat... \n", "\n", " combined_sources_info \\\n", - "0 [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd... \n", - "1 [{'vessel_id': '3c81a942b-bf0a-f476-ea72-75c02... \n", - "2 [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452... \n", + "0 [{'vessel_id': '3c81a942b-bf0a-f476-ea72-75c02... \n", + "1 [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452... \n", + "2 [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd... \n", "\n", " self_reported_info \n", - "0 [{'id': '71e7da672-2451-17da-b239-857831602eca... \n", - "1 [{'id': 'da1cd7e1b-b8d0-539c-6581-2b3df8d0a6af... \n", - "2 [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c... " + "0 [{'id': 'da1cd7e1b-b8d0-539c-6581-2b3df8d0a6af... \n", + "1 [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c... \n", + "2 [{'id': '71e7da672-2451-17da-b239-857831602eca... " ] }, "execution_count": 16, @@ -581,7 +586,7 @@ } ], "source": [ - "vessel_search_df.head()" + "vessels_df.head()" ] }, { diff --git a/src/gfwapiclient/resources/insights/resources.py b/src/gfwapiclient/resources/insights/resources.py index cb3dde1..5008741 100644 --- a/src/gfwapiclient/resources/insights/resources.py +++ b/src/gfwapiclient/resources/insights/resources.py @@ -44,7 +44,7 @@ async def get_vessel_insights( Args: includes (Union[List[VesselInsightInclude], List[str]]): List of insight types to include in the response. - Allowed values are `"FISHING"`, `"GAP"`, `"COVERAGE"`, `"IDENTITY"`. + Allowed values are `"FISHING"`, `"GAP"`, `"COVERAGE"`, `"VESSEL-IDENTITY-IUU-VESSEL-LIST"`. Example: `["FISHING", "GAP"]`. start_date (Union[datetime.date, str]): From 70b8079f1ad77fb2bbd58b9196f0fdefd71d425a Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Fri, 9 Jan 2026 20:42:43 +0300 Subject: [PATCH 16/22] docs: add api workflow guides and jupyter notebooks This also: - enable MyST-NB for rendering and executing Markdown and Jupyter notebooks - configure notebook execution settings for docs builds - add workflow guides to documentation navigation and index - link workflow guides from getting started and usage guides --- docs/source/conf.py | 17 +- docs/source/getting-started.md | 2 +- docs/source/index.md | 5 + docs/source/usage-guides/4wings-api.md | 2 +- docs/source/usage-guides/datasets-api.md | 2 +- docs/source/usage-guides/events-api.md | 2 +- docs/source/usage-guides/insights-api.md | 2 +- .../usage-guides/references-data-api.md | 2 +- docs/source/usage-guides/vessels-api.md | 2 +- docs/source/workflow-guides/index.md | 14 + ...parent-fishing-effort-senegalese-eez.ipynb | 1260 ++++++++++ ...arent-fishing-effort-argentinian-eez.ipynb | 2173 +++++++++++++++++ ...low-03-analyze-fleet-in-ghanaian-eez.ipynb | 1996 +++++++++++++++ notebooks/usage-guides/4wings-api.ipynb | 2 +- ...parent-fishing-effort-senegalese-eez.ipynb | 1260 ++++++++++ ...arent-fishing-effort-argentinian-eez.ipynb | 2173 +++++++++++++++++ ...low-03-analyze-fleet-in-ghanaian-eez.ipynb | 1996 +++++++++++++++ 17 files changed, 10899 insertions(+), 11 deletions(-) create mode 100644 docs/source/workflow-guides/index.md create mode 100644 docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb create mode 100644 docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb create mode 100644 docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb create mode 100644 notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb create mode 100644 notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb create mode 100644 notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb diff --git a/docs/source/conf.py b/docs/source/conf.py index 7538520..452f9e5 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -34,8 +34,8 @@ "sphinx.ext.autodoc", "sphinx.ext.intersphinx", # third-party extensions - "myst_parser", - # "myst_nb", + # "myst_parser", # imported by myst_nb automatically + "myst_nb", "autodoc2", "sphinx_copybutton", "sphinx_inline_tabs", @@ -47,7 +47,8 @@ # The suffix of source filenames. source_suffix = { ".rst": "restructuredtext", - ".md": "markdown", + ".md": "myst-nb", + ".ipynb": "myst-nb", } # The master toctree document. @@ -95,6 +96,16 @@ ] myst_heading_anchors = 3 +# -- MyST-NB execution configuration ------------------------------------------ +# https://myst-nb.readthedocs.io/en/latest/configuration.html#config-intro + +nb_execution_mode = "force" +nb_execution_timeout = 300 +nb_execution_raise_on_error = True + +nb_output_stderr = "show" +nb_merge_streams = True + # -- Options for autodoc2 ------------------------------------------------- # https://sphinx-autodoc2.readthedocs.io/en/latest/config.html diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index 9bccd24..cbb841d 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -226,6 +226,6 @@ memory usage: 43.7+ KB This guide has provided you with the fundamental steps to install and use the `gfw-api-python-client` for making basic API requests. -To further explore the capabilities of our APIs (`4Wings`, `Vessels`, `Events`, `Insights`, `Datasets`, `References`, etc.), please refer to the detailed [Usage Guides](usage-guides/index). These guides delve into specific use cases and demonstrate how to effectively leverage the `gfw-api-python-client` for your data exploration needs. +To further explore the capabilities of our APIs (`4Wings`, `Vessels`, `Events`, `Insights`, `Datasets`, `References`, etc.), please refer to the detailed [Usage Guides](usage-guides/index) and [Workflow Guides](workflow-guides/index). These guides delve into specific use cases and demonstrate how to effectively leverage the `gfw-api-python-client` for your data exploration needs. Happy coding and data exploring! diff --git a/docs/source/index.md b/docs/source/index.md index bb58aed..188bcd3 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -14,6 +14,7 @@ The `gfw-api-python-client` simplifies access to Global Fishing Watch (GFW) data getting-started installation usage-guides/index +workflow-guides/index ``` ```{toctree} @@ -49,6 +50,10 @@ To learn about how to use `gfw-api-python-client`, check out the following resou - [Insights API](usage-guides/insights-api) - [Datasets API](usage-guides/datasets-api) - [References Data API](usage-guides/references-data-api) +- [Workflow Guides](workflow-guides/index) + - [Analyze apparent fishing effort in Senegalese EEZ](workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez) + - [Analyze apparent fishing effort in Argentinian EEZ](workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez) + - [Analyze a fleet in Ghanaian EEZ](workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez) If you find bugs, need help, or want to contribute, check out the following resources: diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 748f00b..e3b58cc 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -374,7 +374,7 @@ The 4Wings API often requires specifying geographic regions. You can use the [Re ## Next Steps -Explore the [Usage Guides](index) for other API resources to understand how you can combine the reporting and statistical capabilities of the 4Wings API with vessel information, event data, and more. Check out the following resources: +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine the reporting and statistical capabilities of the 4Wings API with vessel information, event data, and more. Check out the following resources: - [Vessels API](vessels-api) - [Events API](events-api) diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 0c1e96f..3e9c587 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-api.md @@ -169,7 +169,7 @@ memory usage: 60.6+ KB ## Next Steps -Explore the [Usage Guides](index) for other API resources. Check out the following resources: +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources. Check out the following resources: - [4Wings API](4wings-api) - [Vessels API](vessels-api) diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index c570a91..f3afd85 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-api.md @@ -219,7 +219,7 @@ Please be aware that the accuracy and completeness of the event data can vary. R ## Next Steps -Explore the [Usage Guides](index) for other API resources to understand how you can combine event data with information about vessels, and more. Check out the following resources: +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine event data with information about vessels, and more. Check out the following resources: - [4Wings API](4wings-api) - [Vessels API](vessels-api) diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 5208c2b..51c0813 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -98,7 +98,7 @@ memory usage: 180.0+ bytes ## Next Steps -Explore the [Usage 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: +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: - [Vessels API](vessels-api) - [Events API](events-api) diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index 1290a74..b54c014 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-api.md @@ -178,7 +178,7 @@ memory usage: 1.4+ KB ## Next Steps -Explore the [Usage Guides](index) for other API resources to understand how you can combine reference data with dynamic information about events, vessels, and more. Check out the following resources: +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine reference data with dynamic information about events, vessels, and more. Check out the following resources: - [4Wings API](4wings-api) - [Vessels API](vessels-api) diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index ec9ef6c..4120d06 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-api.md @@ -198,7 +198,7 @@ memory usage: 188.0+ bytes ## Next Steps -Explore the [Usage Guides](index) for other API resources to understand how you can combine vessel data with information about events, and more. Check out the following resources: +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine vessel data with information about events, and more. Check out the following resources: - [4Wings API](4wings-api) - [Events API](events-api) diff --git a/docs/source/workflow-guides/index.md b/docs/source/workflow-guides/index.md new file mode 100644 index 0000000..e3adbac --- /dev/null +++ b/docs/source/workflow-guides/index.md @@ -0,0 +1,14 @@ +# Workflow Guides + +The sections below provide detailed instructions on how to combine Global Fishing Watch APIs to build powerful **workflows** and **applications** for a variety of **use cases** using the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client). For additional context and expanded explanations, refer to the [API Workflows Guide (PDF)](https://globalfishingwatch.org/our-apis/assets/2025_GFW_API_Workflows.pdf), and [API Workflows](https://globalfishingwatch.org/our-apis/documentation#api-workflows) pages in the [GFW API documentation](https://globalfishingwatch.org/our-apis/documentation#introduction). + + +> **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. + +```{toctree} +:maxdepth: 1 + +workflow-01-analyze-apparent-fishing-effort-senegalese-eez +workflow-02-analyze-apparent-fishing-effort-argentinian-eez +workflow-03-analyze-fleet-in-ghanaian-eez +``` diff --git a/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb b/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb new file mode 100644 index 0000000..c37fb6a --- /dev/null +++ b/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb @@ -0,0 +1,1260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze apparent fishing effort in Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d79f0ab4-ab4d-4098-82b0-b6a5c772e101", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Analyze apparent fishing effort in [Senegalese EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8371) region and monitor vessel activities** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, and **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "eafaa9d1-2143-452c-813c-75b21fd2198c", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc98323c-c9e4-401c-8f26-f551968c003a", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "047ff069-3c87-47fe-bb4a-acb920df2137", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "708e137f-6aa0-461e-b1af-33512a2093fc", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: A Port Inspector Monitoring Vessel Activity**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Mamadou, a port inspector in Dakar, Senegal, monitors vessel activity within **[Senegalese Exclusive Economic Zone (EEZ)]((https://www.marineregions.org/gazetteer.php?p=details&id=8371))**. His goal is to:\n", + "\n", + "1. Analyzing apparent fishing effort, specifically for **trawlers** in Senegalese EEZ.\n", + "2. Identifying vessels involved in **apparent trawling activity** and determining their reported **flag states**.\n", + "3. Checking vessel history, including prior **encounters (or potential transshipment)** or **port visits**.\n", + "4. Generating reports for enforcement authorities to assess risks." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – To retrieve **apparent fishing effort** data for trawlers operating in Senegalese EEZ over the past 3 months.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – To retrieve **detailed vessel information**, including `flag`, `ownership history`, and `authorizations`." + ] + }, + { + "cell_type": "markdown", + "id": "a6006ce5-675f-4d1f-89a5-69130ff1ed5b", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "5413d78e-e745-4f74-a062-f303c7a1669f", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "7d5e3571-f47f-4c2f-8d0d-0c89baae4411", + "metadata": {}, + "source": [ + "Before making API requests, Mamadou must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "75a985b1-3803-48d9-b2f3-f12b29bd29e7", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Senegalese EEZ, the region ID is 8371](https://www.marineregions.org/gazetteer.php?p=details&id=8371)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Apparent Fishing Effort in Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "4bede3c0-3d01-4661-8b88-467244417d20", + "metadata": {}, + "source": [ + "Mamadou **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **apparent fishing effort for all vessels**, grouping them by **vessel ID** in **[Senegalese EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8371)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "2e2e42d9-1b9e-4115-b601-72d0e86ab91d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8371 Senegalese EEZ]((https://www.marineregions.org/gazetteer.php?p=details&id=8371))\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 3 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID\n", + "4. **[Gear Type](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported)** - Trawlers " + ] + }, + { + "cell_type": "markdown", + "id": "849f6157-fa79-456f-8974-d294c77a0729", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 2 below**.\n" + ] + }, + { + "cell_type": "markdown", + "id": "cf72ff2d-afd7-45bb-8350-aceaebc154d4", + "metadata": {}, + "source": [ + "**Explanation of Parameters & Considerations**\n", + "\n", + "- Gear types, such as **trawlers**, are inferred based on **Global Fishing Watch’s vessel classification system**, which relies on **AIS data and vessel public registries**. The **gear type associated with each vessel is not always 100% accurate**, as it may be derived from historical sources or inferred from movement patterns. See more details on [supported gear types here](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported).\n", + "- Also, please see data caveats regarding [vessel types and their classification here](https://globalfishingwatch.org/our-apis/documentation#vessel-types).\n", + "- See more details on retrieving [Region IDs here](https://globalfishingwatch.org/our-apis/documentation#regions)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "db35d1b2-ba32-4a58-97f3-17059b3de164", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"MONTHLY\",\n", + " filters=[\"geartype in ('trawlers')\"],\n", + " start_date=\"2024-11-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8371\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "301f888e-3b7e-4946-a7aa-496e05b53cbd", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "866f84fb-50c4-47e2-95fa-43fbc06d17cd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 170 entries, 0 to 169\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 170 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 170 non-null object \n", + " 3 gear_type 170 non-null object \n", + " 4 hours 170 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 170 non-null object \n", + " 7 vessel_type 170 non-null object \n", + " 8 entry_timestamp 170 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 170 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 170 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 170 non-null datetime64[ns, UTC]\n", + " 12 imo 170 non-null object \n", + " 13 mmsi 170 non-null object \n", + " 14 call_sign 170 non-null object \n", + " 15 dataset 170 non-null object \n", + " 16 report_dataset 170 non-null object \n", + " 17 ship_name 170 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 26.7+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c76de7b9-260b-4469-aea5-0ad8fe2f25a4", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0CHNTRAWLERS31.888889412444322MIN LONG YU61146
1SENTRAWLERS524.815556663093000AMINE
2CHNTRAWLERS0.368056412209175MENGXIN24
3ESPTRAWLERS1.306389225987981CIUDAD DE HUELVA
4CHNTRAWLERS216.545000412549331YUAN YU 886
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146\n", + "1 SEN TRAWLERS 524.815556 663093000 AMINE\n", + "2 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", + "3 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", + "4 CHN TRAWLERS 216.545000 412549331 YUAN YU 886" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "792a7b37-50c6-4218-afc9-1e2d1bcdfdb6", + "metadata": {}, + "source": [ + "### Explore Vessels Potentially Engaged in Trawling Activity in the Senegalese EEZ" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c44d3d72-ebe5-4fe0-85fb-8e8675bd1922", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"flag\", \"gear_type\", \"mmsi\", \"ship_name\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "545d63f0-e3b6-4e81-8c5c-55990eeec9b0", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typemmsiship_namehours
66SENTRAWLERS663178000NUEVONOSOLAR1678.888333
52SENTRAWLERS663115000BETTY1648.771944
49SENTRAWLERS663112000TADORNE1610.828611
42SENTRAWLERS663039000SEGUNDO SAN RAFAEL1595.538333
74SENTRAWLERS663250000PRAIA DA MAROSA1573.587500
\n", + "
" + ], + "text/plain": [ + " flag gear_type mmsi ship_name hours\n", + "66 SEN TRAWLERS 663178000 NUEVONOSOLAR 1678.888333\n", + "52 SEN TRAWLERS 663115000 BETTY 1648.771944\n", + "49 SEN TRAWLERS 663112000 TADORNE 1610.828611\n", + "42 SEN TRAWLERS 663039000 SEGUNDO SAN RAFAEL 1595.538333\n", + "74 SEN TRAWLERS 663250000 PRAIA DA MAROSA 1573.587500" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3f948958-ebce-4478-8b17-d6143c38956b", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "7d51287d-263b-4ff5-a40a-5efa7e7ea0a4", + "metadata": {}, + "source": [ + "- There are vessels appear to have been engaged in potential trawling activity in Senegalese EEZ over the past 3 months i.e.,:\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)`\n", + " - `BETTY (mmsi: 663115000, flag: SEN)`\n", + "- We will retrieve these vessels' `ownership`, `flag history`, and `authorizations` in **Step 2 to validate** them." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "dcbde755-0e9c-48d9-babe-aaee3179b88d", + "metadata": {}, + "source": [ + "Mamadou queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "ba645e15-f111-48f3-96a4-7e091f27669e", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), **Step 1 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "42a309da-6a56-46a0-aa86-2a148d21d855", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5b507df7-99fe-4bb2-82da-7ed4ad4cfa8e", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_vessel_mmsis = list(step_1_agg_report_df[\"mmsi\"].head(n=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f87106f0-b2a0-482c-bd1f-d11119ee53a3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['663178000', '663115000']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_vessel_mmsis" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1eb89d2a-4d53-4d67-a668-0cbb233e950c", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_vessel_ids = list(\n", + " step_1_report_df[step_1_report_df[\"mmsi\"].isin(step_1_vessel_mmsis)][\n", + " \"vessel_id\"\n", + " ].unique()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e670a688-3af0-410d-b93b-ec1e06ec4e09", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['894bc3ec6-6ade-f09c-e792-ff2e947508d8',\n", + " 'bf28c5a58-8c83-8690-8689-7f2d520f926e']" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "428889bd-4761-4301-b21e-fbc37eba5622", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_1_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c64d68dc-b952-412f-827c-df5236c98bd7", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessels_df = step_2_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "757e6c3c-d0df-4b8f-839d-1e31518d42d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2 entries, 0 to 1\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 2 non-null object\n", + " 1 registry_info_total_records 2 non-null int64 \n", + " 2 registry_info 2 non-null object\n", + " 3 registry_owners 2 non-null object\n", + " 4 registry_public_authorizations 2 non-null object\n", + " 5 combined_sources_info 2 non-null object\n", + " 6 self_reported_info 2 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 244.0+ bytes\n" + ] + } + ], + "source": [ + "step_2_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "7746d027-fb76-41dd-86e9-b949284ec19c", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "4767e025-e26e-4a61-8971-8f2cc90385cc", + "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", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '199483471cd2da3717552fddb1a3172a', 's...[{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...[{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...
1[{'id': '29fef17154387858d8d4c777311c57f7', 's...[{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ...[{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", + "1 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", + "1 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "\n", + " self_reported_info \n", + "0 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... \n", + "1 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "46760bde-049d-433c-817d-ae63b1c58924", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "7efdc6d6-52d8-40bb-9537-e09f242fdb25", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_registry_info_df = pd.json_normalize(\n", + " step_2_vessels_df[\"registry_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "27ab60a9-6496-4406-9ae4-57a7aa97f6fa", + "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", + " \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", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0663115000SENBETTYBETTY[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
1663178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
2762178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
3552178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 663115000 SEN BETTY BETTY [TRAWLERS] \n", + "1 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "2 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "3 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "\n", + " source_code \n", + "0 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "1 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "2 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "3 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "db341dcf-c0a4-48df-bcc9-1e8fa78d3b25", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "24cec6f2-3e70-4396-a779-13ace779733f", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_registry_owners_df = pd.json_normalize(\n", + " step_2_vessels_df[\"registry_owners\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "16f804f4-ea4f-4a07-8c53-497e09deddfd", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0663115000SENARMEMENT SOPASEN[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
1663178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
2663176000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
3762178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
4552178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name source_code\n", + "0 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "1 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "2 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "3 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "4 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "7a22580f-7c7a-4181-9a80-e37687cc0471", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "c2fa4bdd-1b51-4b37-abf5-aa18a1cab3e5", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_self_reported_info_df = pd.json_normalize(\n", + " step_2_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d1b559c7-4587-4019-a843-181017dd3f07", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0663115000SENBETTYBETTY[AIS]
1663178000SENNUEVONOSOLARNUEVONOSOLAR[AIS]
2663178000SENNUEVO=NOSOLAR+3&!U.?NUEVONOSOLAR3U[AIS]
3762178000NoneNUEVO NOSOLARNUEVONOSOLAR[AIS]
4552178000NoneNUEVO NOSOLARNUEVONOSOLAR[AIS]
5663178000SENNUEVO NOSOLARNUEVONOSOLAR[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 663115000 SEN BETTY BETTY [AIS]\n", + "1 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", + "2 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", + "3 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "4 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "5 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "6a6bcbcd-49a8-4575-9003-d8495deeb2d3", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "53b4b694-b730-451c-b853-01485b6ca38c", + "metadata": {}, + "source": [ + "- **Vessel Identity:**\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)`- appears to be registered under Senegal (SEN)\n", + " - `BETTY (mmsi: 663115000, flag: SEN)` - appears to be registered under Senegal (SEN)\n", + "- **Ownership & Historical Changes:**\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)` - **SENEVISA** appears to be listed as the registered owner.\n", + " - `BETTY (mmsi: 663115000, flag: SEN)`- **ARMEMENT SOPASEN** appears to be listed as the registered owner." + ] + }, + { + "cell_type": "markdown", + "id": "e35fec91-477e-4fb5-99f2-766b3a5dbeff", + "metadata": {}, + "source": [ + "**Next Steps:**\n", + "\n", + "- Further, **validate ownership history** using official registry sources.\n", + "- Assess whether any **historical changes** in `flag`, `name`, or `ownership` are relevant for enforcement.\n", + "- Generate an **apparent activity report** with all available details." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "## Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve apparent fishing effort for **trawlers** within Senegalese EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch detailed **vessel identity**, **ownership history**, and **public authorizations** for vessels detected in **Step 1**.\n", + "3. **Analyze vessel history** - Compare **registry records**, **AIS self-reported** data, and inferred information to identify potential flag-hopping or historical changes in vessel identity.\n", + "4. **Assess authorizations** - Cross-check whether vessels have publicly available fishing authorizations and consider external official sources for further verification.\n", + "5. **Generate an analysis report** - Provide enforcement authorities with a structured report highlighting vessel activity, identity records, and any notable discrepancies for further investigation." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb b/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb new file mode 100644 index 0000000..0953cfe --- /dev/null +++ b/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb @@ -0,0 +1,2173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze apparent fishing effort in Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d79f0ab4-ab4d-4098-82b0-b6a5c772e101", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Analyze apparent fishing effort in [Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466) region and monitor industrial trawlers** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**, and **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "eafaa9d1-2143-452c-813c-75b21fd2198c", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc98323c-c9e4-401c-8f26-f551968c003a", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "047ff069-3c87-47fe-bb4a-acb920df2137", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "708e137f-6aa0-461e-b1af-33512a2093fc", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: A Fisheries Enforcement Officer Monitoring Industrial Trawlers**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Maria, a fisheries enforcement officer in Argentina, monitors industrial trawlers operating within **[Argentinian Exclusive Economic Zone (EEZ)](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. His goal is to:\n", + "\n", + "1. Analyzing apparent fishing effort for **trawlers** operating in Argentinian EEZ.\n", + "2. Identifying vessels involved in **apparent trawling activity** and determining their reported **flag states**.\n", + "3. Checking vessel history, including **potential transshipment** and **port visits**.\n", + "4. Generating reports to support fisheries enforcement decisions." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Retrieve **apparent fishing effort** data for trawlers.\n", + "2. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Group vessels by ID that are involved in **trawling activity**.\n", + "3. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – Retrieve **vessel identity** & **ownership** details.\n", + "4. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** – Fetch **port visits** & **potential transshipment** history. " + ] + }, + { + "cell_type": "markdown", + "id": "c93924be-f36e-4f6c-830f-4d06c03d08f7", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "01169672-36d5-4b2b-969d-471070d75f8c", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "88789a27-1e15-44af-ba81-7d07ded02e4b", + "metadata": {}, + "source": [ + "Before making API requests, Maria must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "75a985b1-3803-48d9-b2f3-f12b29bd29e7", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Argentinian EEZ, the region ID is 8466](https://www.marineregions.org/gazetteer.php?p=details&id=8466)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "35a0691d-b747-48e6-8b02-5c2f54a5d536", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Apparent Fishing Effort in Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d57cd039-a667-44f7-b785-8d0e50530333", + "metadata": {}, + "source": [ + "Maria **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **apparent fishing effort for all vessels**, grouping them by **gear type** in **[Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "6229af14-613a-4809-96f5-9cb3d6bd3461", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - 8466 Argentinian EEZ\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 6 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Gear Type" + ] + }, + { + "cell_type": "markdown", + "id": "b945aa10-40c3-490a-84e7-89092badd783", + "metadata": {}, + "source": [ + "**Why This Step?**\n", + "\n", + "- Identifies which gear types (e.g., `trawlers`, `squid jiggers` etc.) are most active in the Argentinian EEZ.\n", + "- Establishes baseline fishing activity trends before narrowing the search to specific vessels." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "62b9b9e5-4170-40d0-9aef-7579beb89bc0", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"GEARTYPE\",\n", + " temporal_resolution=\"MONTHLY\",\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8466\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4d6190fc-a8fa-4d59-914e-ebae41943381", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d98ca51f-bb46-4edc-9a61-3e26c56bbcc8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 40 entries, 0 to 39\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 40 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 0 non-null object \n", + " 3 gear_type 40 non-null object \n", + " 4 hours 40 non-null float64\n", + " 5 vessel_ids 40 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 40 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: float64(1), int64(1), object(18)\n", + "memory usage: 6.4+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ce844c77-6cf0-4648-bdfb-3a72589c0785", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
0inconclusive215.6238892
1set_longlines17.9258331
2inconclusive98.1558332
3other_purse_seines57.3775001
4set_longlines153.9602783
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "0 inconclusive 215.623889 2\n", + "1 set_longlines 17.925833 1\n", + "2 inconclusive 98.155833 2\n", + "3 other_purse_seines 57.377500 1\n", + "4 set_longlines 153.960278 3" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"gear_type\", \"hours\", \"vessel_ids\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "45319c2a-e82e-4a9a-8a2d-2ea6d9cdada4", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"gear_type\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"), vessel_ids=(\"vessel_ids\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "121465c6-65ef-4efa-9d8a-4a0a136564bd", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
8trawlers240642.4144441315
1fishing16023.20138994
7squid_jigger6124.06222244
2fixed_gear1948.32555616
3inconclusive1072.35138914
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "8 trawlers 240642.414444 1315\n", + "1 fishing 16023.201389 94\n", + "7 squid_jigger 6124.062222 44\n", + "2 fixed_gear 1948.325556 16\n", + "3 inconclusive 1072.351389 14" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "449828f2-dda7-422c-8cfb-770ced828ca6", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "e83e24d9-edb1-45d3-af4a-fa60b155ecab", + "metadata": {}, + "source": [ + "- Multiple **gear types** were potentially detected in Argentinian EEZ.\n", + "- `Trawlers` appear to be operating, but further **vessel-level investigation** is needed." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel IDs for Trawlers" + ] + }, + { + "cell_type": "markdown", + "id": "4bede3c0-3d01-4661-8b88-467244417d20", + "metadata": {}, + "source": [ + "Maria refines her **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** request to group by **vessel ID**, and filtering only for **trawlers** in **[Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "2e2e42d9-1b9e-4115-b601-72d0e86ab91d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8466 Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 6 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID\n", + "4. **[Gear Type](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported)** - Trawlers " + ] + }, + { + "cell_type": "markdown", + "id": "849f6157-fa79-456f-8974-d294c77a0729", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 3 below**.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "db35d1b2-ba32-4a58-97f3-17059b3de164", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " filters=[\"geartype in ('trawlers')\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8466\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "301f888e-3b7e-4946-a7aa-496e05b53cbd", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_df = step_2_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "866f84fb-50c4-47e2-95fa-43fbc06d17cd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 385 entries, 0 to 384\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 385 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 385 non-null object \n", + " 3 gear_type 385 non-null object \n", + " 4 hours 385 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 385 non-null object \n", + " 7 vessel_type 385 non-null object \n", + " 8 entry_timestamp 385 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 385 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 385 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 385 non-null datetime64[ns, UTC]\n", + " 12 imo 385 non-null object \n", + " 13 mmsi 385 non-null object \n", + " 14 call_sign 385 non-null object \n", + " 15 dataset 385 non-null object \n", + " 16 report_dataset 385 non-null object \n", + " 17 ship_name 385 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 60.3+ KB\n" + ] + } + ], + "source": [ + "step_2_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "82a786a1-c437-430e-aeb5-f61d02a5f900", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0URYTRAWLERS10.023056770576463KALATXORI
1ARGTRAWLERS326.160833701079000ENTRENA UNO
2ARGTRAWLERS714.842500701000882FELIX AUGUSTO
3ARGTRAWLERS641.522222701000932ANTONIO ALVAREZ
4ARGTRAWLERS295.007500701000820CORAJE
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 URY TRAWLERS 10.023056 770576463 KALATXORI\n", + "1 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", + "2 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", + "3 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "4 ARG TRAWLERS 295.007500 701000820 CORAJE" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "630d95dd-8f82-407f-b223-f55e981e3593", + "metadata": {}, + "source": [ + "### Explore Vessels Potentially Engaged in Trawling Activity in the Argentinian EEZ" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "984052a3-3920-4fce-8894-4b67af4a8a69", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_agg_report_df = (\n", + " step_2_report_df.groupby([\"flag\", \"gear_type\", \"mmsi\", \"ship_name\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "83e4dafb-4491-40c9-9f4d-f4cc1e2b7766", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typemmsiship_namehours
297ARGTRAWLERS701024000ATLANTIC SURF III3151.855278
247ARGTRAWLERS701006605CAPESANTE2270.097500
22ARGTRAWLERS701000577MISS TIDE2244.895833
296ARGTRAWLERS701023000CAROLINA P2065.586944
301ARGTRAWLERS701037000DON PEDRO1807.146111
\n", + "
" + ], + "text/plain": [ + " flag gear_type mmsi ship_name hours\n", + "297 ARG TRAWLERS 701024000 ATLANTIC SURF III 3151.855278\n", + "247 ARG TRAWLERS 701006605 CAPESANTE 2270.097500\n", + "22 ARG TRAWLERS 701000577 MISS TIDE 2244.895833\n", + "296 ARG TRAWLERS 701023000 CAROLINA P 2065.586944\n", + "301 ARG TRAWLERS 701037000 DON PEDRO 1807.146111" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3f948958-ebce-4478-8b17-d6143c38956b", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "d4fb7cba-a577-45fe-88fa-8e5001bb9869", + "metadata": {}, + "source": [ + "- There are vessels appear to have been engaged in potential trawling activity in Argentinian EEZ over the past 6 months i.e.,:\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)`\n", + "- We will retrieve these vessels' `ownership`, `flag history`, and `authorizations` in **Step 3 to validate** them." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 3: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "dcbde755-0e9c-48d9-babe-aaee3179b88d", + "metadata": {}, + "source": [ + "Maria queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "ba645e15-f111-48f3-96a4-7e091f27669e", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), **Step 2 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "42a309da-6a56-46a0-aa86-2a148d21d855", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "24e8452f-7848-4c88-89db-66e4bf182cd1", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_mmsis = list(step_2_agg_report_df[\"mmsi\"].head(n=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f25ceec0-3188-4584-bb95-f76c9e0ac578", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['701024000', '701006605']" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_mmsis" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "446b506a-a19f-49cd-9110-ed8b9103af8b", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_ids = list(\n", + " step_2_report_df[step_2_report_df[\"mmsi\"].isin(step_2_vessel_mmsis)][\n", + " \"vessel_id\"\n", + " ].unique()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "6233b1eb-ed4b-4ba9-bce8-faa1ee027dcc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['de8a03acd-dc6c-8e08-2867-24e55ffc0017',\n", + " '8e930bac5-594b-aa3f-081d-d12668819e1f']" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "428889bd-4761-4301-b21e-fbc37eba5622", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_2_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "c64d68dc-b952-412f-827c-df5236c98bd7", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_df = step_3_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "757e6c3c-d0df-4b8f-839d-1e31518d42d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2 entries, 0 to 1\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 2 non-null object\n", + " 1 registry_info_total_records 2 non-null int64 \n", + " 2 registry_info 2 non-null object\n", + " 3 registry_owners 2 non-null object\n", + " 4 registry_public_authorizations 2 non-null object\n", + " 5 combined_sources_info 2 non-null object\n", + " 6 self_reported_info 2 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 244.0+ bytes\n" + ] + } + ], + "source": [ + "step_3_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "c2d30f1a-352b-42cb-8ee8-acd67f16103f", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "4767e025-e26e-4a61-8971-8f2cc90385cc", + "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", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '45502524c9a150e77869ee647423dba1', 's...[{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...[{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...
1[{'id': '2d939efefd3f45788ed103ff0723f564', 's...[{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'...[{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", + "1 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", + "1 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "\n", + " self_reported_info \n", + "0 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... \n", + "1 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "46760bde-049d-433c-817d-ae63b1c58924", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "7efdc6d6-52d8-40bb-9537-e09f242fdb25", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "27ab60a9-6496-4406-9ae4-57a7aa97f6fa", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0701024000ARGATLANTIC SURF IIIATLANTICSURF3[TRAWLERS][IMO, TMT_OTHER_OFFICIAL]
1701006605ARGCAPESANTECAPESANTE[TRAWLERS][GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF...
2316003980CANATLANTICLEADERATLANTICLEADER[TRAWLERS][IMO, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", + "1 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", + "2 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "\n", + " source_code \n", + "0 [IMO, TMT_OTHER_OFFICIAL] \n", + "1 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "2 [IMO, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "5787e4ee-69e0-4769-ba05-9a57254c7289", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "afe07c2a-81cb-45b3-9e86-c23b4ef67fe9", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_owners_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_owners\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "df7e0b65-0ab0-4722-aaec-3d11c7674b8f", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0701024000ARGGLACIAR PESQUERA[TMT_OTHER_OFFICIAL]
1701006605CANCLEARWATER SEAFOODS[RESEARCH-PAPER]
2316003980CANCS MANPAR[TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name source_code\n", + "0 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]\n", + "1 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", + "2 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "7a22580f-7c7a-4181-9a80-e37687cc0471", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "c2fa4bdd-1b51-4b37-abf5-aa18a1cab3e5", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_self_reported_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "d1b559c7-4587-4019-a843-181017dd3f07", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0701024000ARGATLANTIC SURF IIIATLANTICSURF3[AIS]
1701006605ARGCAPESANTECAPESANTE[AIS]
2316003980CANATLANTIC LEADERATLANTICLEADER[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]\n", + "1 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", + "2 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "6a6bcbcd-49a8-4575-9003-d8495deeb2d3", + "metadata": {}, + "source": [ + "### What We have Learned from Step 3" + ] + }, + { + "cell_type": "markdown", + "id": "da9c80ea-94d7-4945-8e90-9f5ec4bad8f1", + "metadata": {}, + "source": [ + "- **Vessel Identity:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- appears to be registered under Argentina (ARG)\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - appears to be registered under Argentina (ARG)\n", + "- **Ownership & Historical Changes:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)` - **GLACIAR PESQUERA** appears to be listed as the registered owner.\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)`- **CLEARWATER SEAFOODS** appears to be listed as the registered owner." + ] + }, + { + "cell_type": "markdown", + "id": "4803ae37-3f96-40dc-8db8-690b51710735", + "metadata": {}, + "source": [ + "## Step 4: Detect Potential Port Visits, Encounters, or Fishing Events" + ] + }, + { + "cell_type": "markdown", + "id": "058cc09a-64dc-4913-a90c-cadc7d38439a", + "metadata": {}, + "source": [ + "Now Maria checks `port visits`, `encounters`, and `fishing events` using the **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**, which allows **monitoring of vessel activities** such as `potential transshipments`, `unauthorized port entries`, or `fishing activity patterns`." + ] + }, + { + "cell_type": "markdown", + "id": "c8ee8f1c-7e5e-487f-ba45-7f7f609ba389", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel ID** from 4Wings API\n", + "2. **[Event Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - Port visits, encounters (potential transshipment), and fishing events.\n", + "3. **Time Range** - Last 6 months.\n", + "4. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)**:\n", + " - `public-global-port-visits-events::latest` (Port Visits)\n", + " - `public-global-encounters-events:latest` (Encounters between vessels)\n", + " - `public-global-fishing-events:latest` (Fishing activity)\n", + "5. **[Encounter Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - CARRIER-FISHING" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "87c3b592-e431-457c-a5f4-5ce07711d52f", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_result = await gfw_client.events.get_all_events(\n", + " datasets=[\n", + " \"public-global-encounters-events:latest\",\n", + " \"public-global-fishing-events:latest\",\n", + " \"public-global-port-visits-events:latest\",\n", + " ],\n", + " vessels=step_2_vessel_ids,\n", + " types=[\"ENCOUNTER\", \"FISHING\", \"PORT_VISIT\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " encounter_types=[\"CARRIER-FISHING\"],\n", + " sort=\"-start\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "64cb0776-7f0d-481e-be98-da00b448c720", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_df = step_4_events_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "4c82d647-3870-4a54-979b-7f586575e5c1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 359 entries, 0 to 358\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 359 non-null datetime64[ns, UTC]\n", + " 1 end 359 non-null datetime64[ns, UTC]\n", + " 2 id 359 non-null object \n", + " 3 type 359 non-null object \n", + " 4 position 359 non-null object \n", + " 5 regions 359 non-null object \n", + " 6 bounding_box 359 non-null object \n", + " 7 distances 359 non-null object \n", + " 8 vessel 359 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 351 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 8 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 39.4+ KB\n" + ] + } + ], + "source": [ + "step_4_events_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "17d89920-cda2-497d-9797-1e05a84a0daa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "type\n", + "fishing 351\n", + "port_visit 8\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_events_df[\"type\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "1b472de1-8fef-41a1-a76c-057406d86ee1", + "metadata": {}, + "source": [ + "### Explore Apparent Fishing Events" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "4d360bc4-9762-4ae6-b5b1-1b937e2d2ed0", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_events_df = step_4_events_df[step_4_events_df[\"fishing\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "18ff38d6-9442-4742-9dc9-accfb1299e43", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_fishing_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_fishing_events_df[\"fishing\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "fc6ebae0-eba2-4a8a-892c-6dfc38822bd7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 351 entries, 0 to 350\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 351 non-null object \n", + " 1 name 351 non-null object \n", + " 2 ssvid 351 non-null object \n", + " 3 flag 351 non-null object \n", + " 4 type 351 non-null object \n", + " 5 public_authorizations 351 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 total_distance_km 351 non-null float64\n", + " 8 average_speed_knots 351 non-null float64\n", + " 9 average_duration_hours 0 non-null object \n", + " 10 potential_risk 351 non-null bool \n", + " 11 vessel_public_authorization_status 351 non-null object \n", + "dtypes: bool(1), float64(2), object(9)\n", + "memory usage: 30.6+ KB\n" + ] + } + ], + "source": [ + "step_4_fishing_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "8799e988-56a2-41d5-b472-bc83064e1807", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidtotal_distance_kmaverage_speed_knots
0ATLANTIC SURF III701024000117.5454504.351747
1ATLANTIC SURF III70102400010.4088513.791667
2ATLANTIC SURF III70102400061.3669114.448980
3ATLANTIC SURF III70102400092.1807044.485407
4ATLANTIC SURF III701024000974.7618714.051429
...............
346CAPESANTE70100660595.1280594.202542
347CAPESANTE701006605205.8262824.136848
348CAPESANTE701006605369.3366033.938255
349ATLANTIC SURF III701024000256.9088424.186333
350CAPESANTE701006605208.0719853.971505
\n", + "

351 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " name ssvid total_distance_km average_speed_knots\n", + "0 ATLANTIC SURF III 701024000 117.545450 4.351747\n", + "1 ATLANTIC SURF III 701024000 10.408851 3.791667\n", + "2 ATLANTIC SURF III 701024000 61.366911 4.448980\n", + "3 ATLANTIC SURF III 701024000 92.180704 4.485407\n", + "4 ATLANTIC SURF III 701024000 974.761871 4.051429\n", + ".. ... ... ... ...\n", + "346 CAPESANTE 701006605 95.128059 4.202542\n", + "347 CAPESANTE 701006605 205.826282 4.136848\n", + "348 CAPESANTE 701006605 369.336603 3.938255\n", + "349 ATLANTIC SURF III 701024000 256.908842 4.186333\n", + "350 CAPESANTE 701006605 208.071985 3.971505\n", + "\n", + "[351 rows x 4 columns]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"total_distance_km\",\n", + " \"average_speed_knots\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "3659c048-c8bf-463c-a6cb-fc29f818ed77", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "701024000 245\n", + "701006605 106\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "5da05a04-947e-4f87-b61e-bad015796e5f", + "metadata": {}, + "source": [ + "### Explore Port Visit Events" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "e806616b-6ed7-4c0c-9bf4-2b4a23de2046", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visit_events_df = step_4_events_df[step_4_events_df[\"port_visit\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "58a68605-9432-43fe-b8eb-4d0393f95f60", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visits_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_port_visit_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_port_visit_events_df[\"port_visit\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "685a746e-8091-4321-b851-79a5f3ca0f81", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 8 entries, 0 to 7\n", + "Data columns (total 37 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 8 non-null object \n", + " 1 name 8 non-null object \n", + " 2 ssvid 8 non-null object \n", + " 3 flag 8 non-null object \n", + " 4 type 8 non-null object \n", + " 5 public_authorizations 8 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 visit_id 8 non-null object \n", + " 8 confidence 8 non-null object \n", + " 9 duration_hrs 8 non-null float64\n", + " 10 start_anchorage_anchorage_id 8 non-null object \n", + " 11 start_anchorage_at_dock 8 non-null bool \n", + " 12 start_anchorage_distance_from_shore_km 8 non-null float64\n", + " 13 start_anchorage_flag 8 non-null object \n", + " 14 start_anchorage_id 8 non-null object \n", + " 15 start_anchorage_lat 8 non-null float64\n", + " 16 start_anchorage_lon 8 non-null float64\n", + " 17 start_anchorage_name 8 non-null object \n", + " 18 start_anchorage_top_destination 8 non-null object \n", + " 19 intermediate_anchorage_anchorage_id 8 non-null object \n", + " 20 intermediate_anchorage_at_dock 8 non-null bool \n", + " 21 intermediate_anchorage_distance_from_shore_km 8 non-null float64\n", + " 22 intermediate_anchorage_flag 8 non-null object \n", + " 23 intermediate_anchorage_id 8 non-null object \n", + " 24 intermediate_anchorage_lat 8 non-null float64\n", + " 25 intermediate_anchorage_lon 8 non-null float64\n", + " 26 intermediate_anchorage_name 8 non-null object \n", + " 27 intermediate_anchorage_top_destination 8 non-null object \n", + " 28 end_anchorage_anchorage_id 8 non-null object \n", + " 29 end_anchorage_at_dock 8 non-null bool \n", + " 30 end_anchorage_distance_from_shore_km 8 non-null float64\n", + " 31 end_anchorage_flag 8 non-null object \n", + " 32 end_anchorage_id 8 non-null object \n", + " 33 end_anchorage_lat 8 non-null float64\n", + " 34 end_anchorage_lon 8 non-null float64\n", + " 35 end_anchorage_name 8 non-null object \n", + " 36 end_anchorage_top_destination 8 non-null object \n", + "dtypes: bool(3), float64(10), object(24)\n", + "memory usage: 2.3+ KB\n" + ] + } + ], + "source": [ + "step_4_port_visits_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "0e77b956-f0f8-4fbd-8a49-0116e4401c12", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidconfidencestart_anchorage_nameintermediate_anchorage_nameend_anchorage_name
0ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
1CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
2CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
3ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
4CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
5ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
6CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
7ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
\n", + "
" + ], + "text/plain": [ + " name ssvid confidence start_anchorage_name \\\n", + "0 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "1 CAPESANTE 701006605 4 USHUAIA \n", + "2 CAPESANTE 701006605 4 USHUAIA \n", + "3 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "4 CAPESANTE 701006605 4 USHUAIA \n", + "5 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "6 CAPESANTE 701006605 4 USHUAIA \n", + "7 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "\n", + " intermediate_anchorage_name end_anchorage_name \n", + "0 MAR DEL PLATA MAR DEL PLATA \n", + "1 USHUAIA USHUAIA \n", + "2 USHUAIA USHUAIA \n", + "3 MAR DEL PLATA MAR DEL PLATA \n", + "4 USHUAIA USHUAIA \n", + "5 MAR DEL PLATA MAR DEL PLATA \n", + "6 USHUAIA USHUAIA \n", + "7 MAR DEL PLATA MAR DEL PLATA " + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"confidence\",\n", + " \"start_anchorage_name\",\n", + " \"intermediate_anchorage_name\",\n", + " \"end_anchorage_name\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "32ee1871-f1c7-4561-9384-5a681293e7e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "701024000 4\n", + "701006605 4\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "61d59d0c-8919-40c4-ac30-bb9ab35a4d53", + "metadata": {}, + "source": [ + "### What We have learned from step 4" + ] + }, + { + "cell_type": "markdown", + "id": "4771fe04-5984-4576-b774-a83f104d7194", + "metadata": {}, + "source": [ + "- **Apparent Fishing Events:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025)\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025)\n", + "- **Port Visit Events:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- potentially made multiple port visits, including stops at `MAR DEL PLATA`\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - potentially made multiple port visits, including stops at `USHUAIA`\n", + "- **ENCOUNTER Events:** No explicit **ENCOUNTER** events were returned in the response dataset. Check more details [here](https://globalfishingwatch.org/faqs/what-is-a-vessel-encounter/). You can read more about transshipment behavior from our [report](https://globalfishingwatch.org/wp-content/uploads/GlobalViewOfTransshipment_Aug2017.pdf) or [scientific publication](https://www.frontiersin.org/articles/10.3389/fmars.2018.00240/full)." + ] + }, + { + "cell_type": "markdown", + "id": "f0cf3958-fb92-49c0-ba2f-2cfe971bcbc5", + "metadata": {}, + "source": [ + "**Potential Considerations:**\n", + "\n", + "- The vessel's fishing activities appear near the EEZ boundary, requiring further assessment of compliance with national or RFMO regulations.\n", + "- The absence of matching public authorizations in the RFMO registry does not necessarily indicate illegality, but it suggests that authorities may need to verify through national databases or official sources." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "### Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve apparent fishing effort for **trawlers** within Argentinian EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch **vessel identity**, **ownership history**, and **public authorizations**.\n", + "3. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** - Detect potential **port visits**, **encounters**, and **apparent fishing** events to analyze operational patterns.\n", + "4. **Assess potential risks** - Compare registry records, AIS data, and inferred vessel activity for enforcement follow-ups.\n", + "5. **Generate a report** - Provide a structured analysis for relevant authorities." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb b/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb new file mode 100644 index 0000000..a894429 --- /dev/null +++ b/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb @@ -0,0 +1,1996 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze a fleet in Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "2006da5f-b6dc-491b-b64d-ad332e89e814", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Monitor a Fleet (a group of vessels) of Tuna Longliners in [Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400) region for Compliance** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**, and **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "b7a03d8d-8dec-4096-8395-d8cfc599db69", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d93d57ae-0ec7-4d97-8fea-f679e89fc3b1", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0b398f94-cd59-49c8-95a3-0ee46cf17e77", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f5884635-6941-4f97-8b1a-5fd485a95bc4", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: Monitoring a Fleet of Tuna Longliners for Compliance**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Kwame is a fisheries compliance officer in Ghana, responsible for monitoring a fleet of tuna longliners operating within **[Ghanaian Exclusive Economic Zone (EEZ)](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**. His goal is to:\n", + "\n", + "1. Track apparent fishing effort for **longliners** over the last 12 months.\n", + "2. Identify potential vessels in this fleet, their operational patterns, and their activity levels.\n", + "3. Retrieve vessel details, including **flag state**, **ownership history**, and **authorizations**.\n", + "4. Analyze events such as **port visits** and **encounters (potential transshipment)** activities." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Retrieve apparent fishing effort grouped by vessel ID in Ghanaian EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – Get vessel identity, ownership, and compliance details.\n", + "3. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** – Identify port visits and potential transshipment activities for vessels in the fleet." + ] + }, + { + "cell_type": "markdown", + "id": "0ebc365c-2c5c-413e-80a5-36a4825f3032", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "379460dd-ed9f-49ee-9c9b-e428ad5f4522", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "64b1bbab-9780-4821-ae4f-ccff0a4bb100", + "metadata": {}, + "source": [ + "Before making API requests, Kwame must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "362137ce-97eb-4965-a649-a038bd5d167f", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Ghanaian EEZ, the region ID is 8400](https://www.marineregions.org/gazetteer.php?p=details&id=8400)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Fishing Effort in Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "eba86e0d-90f7-4494-857c-261f9b734dc0", + "metadata": {}, + "source": [ + "Kwame **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **fishing effort for all vessels**, grouping them by **gear type** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "8816740a-4871-49e8-862c-049e0a3d02d3", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - 8400 Ghanaian EEZ\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 12 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Gear Type" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "38c3bc74-e0f6-4f81-b830-3e3393d6b3d0", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"LOW\",\n", + " group_by=\"GEARTYPE\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " start_date=\"2024-01-01\",\n", + " end_date=\"2025-01-01\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8400\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5ee5daa3-6696-4552-8d1a-61df417b8873", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "35dac242-6479-437a-a35f-249ad22cf191", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 9 entries, 0 to 8\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 9 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 0 non-null object \n", + " 3 gear_type 9 non-null object \n", + " 4 hours 9 non-null float64\n", + " 5 vessel_ids 9 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 9 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: float64(1), int64(1), object(18)\n", + "memory usage: 1.5+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6a245cc8-0236-4554-b4c8-d9bbc11db235", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursvessel_ids
0Nonedrifting_longlines593.1383333
1Nonepurse_seines6.3405561
2Nonefishing20929.56333321
3Noneinconclusive30496.17361127
4Nonepole_and_line3481.5091675
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours vessel_ids\n", + "0 None drifting_longlines 593.138333 3\n", + "1 None purse_seines 6.340556 1\n", + "2 None fishing 20929.563333 21\n", + "3 None inconclusive 30496.173611 27\n", + "4 None pole_and_line 3481.509167 5" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"flag\", \"gear_type\", \"hours\", \"vessel_ids\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b56ec0e4-5f85-4a10-bd94-39ea55128920", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"gear_type\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"), vessel_ids=(\"vessel_ids\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "87289a41-0d54-44c9-a17a-f82b318af293", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
7trawlers46704.79722226
3inconclusive30496.17361127
1fishing20929.56333321
8tuna_purse_seines5146.62388923
5pole_and_line3481.5091675
0drifting_longlines593.1383333
4other_purse_seines26.5811111
6purse_seines6.3405561
2fixed_gear0.1636111
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "7 trawlers 46704.797222 26\n", + "3 inconclusive 30496.173611 27\n", + "1 fishing 20929.563333 21\n", + "8 tuna_purse_seines 5146.623889 23\n", + "5 pole_and_line 3481.509167 5\n", + "0 drifting_longlines 593.138333 3\n", + "4 other_purse_seines 26.581111 1\n", + "6 purse_seines 6.340556 1\n", + "2 fixed_gear 0.163611 1" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df" + ] + }, + { + "cell_type": "markdown", + "id": "09252564-51c1-4ed1-b938-76688a670cc6", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "79fee5f2-f217-40e4-be1d-235190de64b5", + "metadata": {}, + "source": [ + "1. Kwame now has apparent fishing effort data for multiple gear types.\n", + "2. There are **potential 3 vessels** operating as a **longliners (i.e., drifting_longlines)** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)** with `593.138333 hours` logged." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel IDs for Longliners" + ] + }, + { + "cell_type": "markdown", + "id": "33209132-cc4a-4711-8e96-0846a71b9c34", + "metadata": {}, + "source": [ + "Kwame refines his **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** request to group by **vessel ID**, and filtering only for **longliners** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**." + ] + }, + { + "cell_type": "markdown", + "id": "293c479b-497c-4472-9ce6-c813985b7533", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8400 Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 12 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID " + ] + }, + { + "cell_type": "markdown", + "id": "f55f1862-ae0d-4ad5-b281-6a514ae9dcce", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 3 below**.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "0797f962-6582-4d3b-bfba-3597d5513a73", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"LOW\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " filters=[\"geartype in ('drifting_longlines')\"],\n", + " start_date=\"2024-01-01\",\n", + " end_date=\"2025-01-01\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8400\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8be53e48-4b93-4140-ae0e-aa910a993da7", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_df = step_2_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "061b9fbf-88cf-47d8-9b30-b878c0b867cf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3 entries, 0 to 2\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 3 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 3 non-null object \n", + " 3 gear_type 3 non-null object \n", + " 4 hours 3 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 3 non-null object \n", + " 7 vessel_type 3 non-null object \n", + " 8 entry_timestamp 3 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 3 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 3 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 3 non-null datetime64[ns, UTC]\n", + " 12 imo 3 non-null object \n", + " 13 mmsi 3 non-null object \n", + " 14 call_sign 3 non-null object \n", + " 15 dataset 3 non-null object \n", + " 16 report_dataset 3 non-null object \n", + " 17 ship_name 3 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 612.0+ bytes\n" + ] + } + ], + "source": [ + "step_2_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "932bd692-c689-4e1d-985c-18eeccdf9ec3", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0CHNDRIFTING_LONGLINES2.750556412331032
1JPNDRIFTING_LONGLINES588.879722431100690SENSHU MARU NO.3
2TWNDRIFTING_LONGLINES1.508056416007496HUNG CHUAN SHUN
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 CHN DRIFTING_LONGLINES 2.750556 412331032 \n", + "1 JPN DRIFTING_LONGLINES 588.879722 431100690 SENSHU MARU NO.3\n", + "2 TWN DRIFTING_LONGLINES 1.508056 416007496 HUNG CHUAN SHUN" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "e54e9165-3f02-46a5-b4ef-74dbfc618766", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "72a9efeb-ae54-4bbd-ab85-77845f928376", + "metadata": {}, + "source": [ + "1. Kwame identifies `3 vessels` operating as longliners within **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**.\n", + "2. The vessel `(mmsi: 431100690, ship_name: SENSHU MARU NO.3)` shows significant activity with `588.879722 hours` logged.\n", + "3. Other vessels `(mmsi: 416007496, ship_name: HUNG CHUAN SHUN)` and `(mmsi: 412331032)` shows apparent fishing effort over a short duration.\n", + "4. This response is based on **AIS self-reported** data and should be further validated.\n" + ] + }, + { + "cell_type": "markdown", + "id": "06b8fa5a-b2fd-415c-9bea-d8ef4902cbe6", + "metadata": {}, + "source": [ + "## Step 3: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "f491fac4-0825-4c6b-aba2-d889d2ec678e", + "metadata": {}, + "source": [ + "Kwame queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "0ed8adac-33da-4168-90a6-5381e9b628f6", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from 4Wings API, **Step 2 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "fa782e3d-3c9d-4236-a0e4-157e22e6aeed", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "15889e5c-dea7-499d-bd77-68a12aca8d98", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_ids = list(step_2_report_df[\"vessel_id\"].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8477d36f-27ea-4ca9-aaad-dfaf8d94cd80", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['f37ebdc1b-be44-0740-7904-49397360e29d',\n", + " 'b1dad8628-8c9c-2ee7-258b-3d8fb747f1c8',\n", + " '60f7bb972-2c90-4553-650b-23c38f9521bf']" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "33d970d9-1321-46ec-87bc-91aed1f446ff", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_2_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c1b9a6e9-683f-44fe-bb47-98825cf9d150", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_df = step_3_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d87c1cef-92d1-462d-a86e-c2af11912ed9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3 entries, 0 to 2\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 3 non-null object\n", + " 1 registry_info_total_records 3 non-null int64 \n", + " 2 registry_info 3 non-null object\n", + " 3 registry_owners 3 non-null object\n", + " 4 registry_public_authorizations 3 non-null object\n", + " 5 combined_sources_info 3 non-null object\n", + " 6 self_reported_info 3 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 300.0+ bytes\n" + ] + } + ], + "source": [ + "step_3_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "9a64a937-59af-414d-8fcc-28948c423117", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "348301a7-c290-4684-bb03-23298e8bc7e0", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '0b0dec977c1aad4ae6652c4076572cc7', 's...[{'name': 'TOMIOKA FISHERIES', 'flag': 'JPN', ...[{'id': 'c86d138c5-5d51-3620-fe01-a9e0ed37fb91...
1[][][{'id': 'f37ebdc1b-be44-0740-7904-49397360e29d...
2[{'id': '02eda7d2da02943eecd48813fb7d562a', 's...[{'name': 'HER RONG SHUN FISHERIES', 'flag': '...[{'id': '60f7bb972-2c90-4553-650b-23c38f9521bf...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '0b0dec977c1aad4ae6652c4076572cc7', 's... \n", + "1 [] \n", + "2 [{'id': '02eda7d2da02943eecd48813fb7d562a', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'TOMIOKA FISHERIES', 'flag': 'JPN', ... \n", + "1 [] \n", + "2 [{'name': 'HER RONG SHUN FISHERIES', 'flag': '... \n", + "\n", + " self_reported_info \n", + "0 [{'id': 'c86d138c5-5d51-3620-fe01-a9e0ed37fb91... \n", + "1 [{'id': 'f37ebdc1b-be44-0740-7904-49397360e29d... \n", + "2 [{'id': '60f7bb972-2c90-4553-650b-23c38f9521bf... " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "44ae4527-da01-4845-be11-b46ddd5575fc", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "7e5cf6db-8f45-4c7e-a8c8-ccdb312eca7d", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_info\"].explode()\n", + ")\n", + "step_3_registry_info_df = step_3_registry_info_df.dropna()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "b350572a-93ec-434f-8f6f-d0418f693b46", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0431100690JPNSENSHU MARU NO.3SENSHUMARU3[DRIFTING_LONGLINES][CCSBT, GFCM, IATTC, ICCAT, IMO, IOTC, OPRT, R...
2416007496TWNHUNG CHUAN SHUNHUNGCHUANSHUN[DRIFTING_LONGLINES][ICCAT, IMO, ISSF, OPRT, TMT_ICCAT, TMT_OTHER_...
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 431100690 JPN SENSHU MARU NO.3 SENSHUMARU3 [DRIFTING_LONGLINES] \n", + "2 416007496 TWN HUNG CHUAN SHUN HUNGCHUANSHUN [DRIFTING_LONGLINES] \n", + "\n", + " source_code \n", + "0 [CCSBT, GFCM, IATTC, ICCAT, IMO, IOTC, OPRT, R... \n", + "2 [ICCAT, IMO, ISSF, OPRT, TMT_ICCAT, TMT_OTHER_... " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "5e0fb205-ea78-4074-b3bb-266d624d5f86", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "0ed351c2-104c-4132-bcae-a3c757ac2465", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_owners_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_owners\"].explode()\n", + ")\n", + "step_3_registry_owners_df = step_3_registry_owners_df.dropna()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d6bbbc39-1928-42cd-9866-71fa95a601d8", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0431100690JPNTOMIOKA FISHERIES[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
1431100690JPNTOMIOKA[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
2431100690JPNYAMAMOTO YUUKI[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
3431100690JPNYAMAMOTO HIROKI[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
5416007496TWNHER RONG SHUN FISHERIES[TMT_ICCAT, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name \\\n", + "0 431100690 JPN TOMIOKA FISHERIES \n", + "1 431100690 JPN TOMIOKA \n", + "2 431100690 JPN YAMAMOTO YUUKI \n", + "3 431100690 JPN YAMAMOTO HIROKI \n", + "5 416007496 TWN HER RONG SHUN FISHERIES \n", + "\n", + " source_code \n", + "0 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "1 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "2 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "3 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "5 [TMT_ICCAT, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "e355771a-ec2a-41b2-ab51-801baf15fab1", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "add8a66e-9736-4cdb-a74d-0607fcc530a2", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_self_reported_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "fd0831dc-e29e-4ccc-864f-704eebee2686", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0431100690JPNNoneNone[AIS]
1431100690JPNSENSHU MARU NO.3SENSHUMARU3[AIS]
2431100690JPNSENSHU MARU NO3SENSHUMARU3[AIS]
3412331032CHNNoneNone[AIS]
4416007496TWNHUNG CHUAN SHUNHUNGCHUANSHUN[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 431100690 JPN None None [AIS]\n", + "1 431100690 JPN SENSHU MARU NO.3 SENSHUMARU3 [AIS]\n", + "2 431100690 JPN SENSHU MARU NO3 SENSHUMARU3 [AIS]\n", + "3 412331032 CHN None None [AIS]\n", + "4 416007496 TWN HUNG CHUAN SHUN HUNGCHUANSHUN [AIS]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "a4e08576-803c-482f-afa5-3fbf4a86837d", + "metadata": {}, + "source": [ + "### What We have Learned from Step 3" + ] + }, + { + "cell_type": "markdown", + "id": "37e54952-ec16-4c85-a6c3-ee7e844d007b", + "metadata": {}, + "source": [ + "- The vessel `mmsi/ssvid: 412331032` appears to be a drifting longliner flagged under China.\n", + "- No public registry data is found for this vessel.\n", + "- The vessel's identity information is based on `AIS self-reported data`, which may not always align with official registries.\n", + "- The vessel appears to have been active since `2014`, based on `self-reported AIS records`.\n", + "- This vessel's data needs further validation against official public sources" + ] + }, + { + "cell_type": "markdown", + "id": "2dc21e2c-a261-44ee-a3b6-2065d4095bcb", + "metadata": {}, + "source": [ + "## Step 4: Detect Fleet Activity (Port Visits)" + ] + }, + { + "cell_type": "markdown", + "id": "ce91f54f-8938-428c-bb22-21c54c8b51f5", + "metadata": {}, + "source": [ + "Now that Kwame has identified vessels in the fleet, he examines their activity further by querying the **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**. This allows him to detect `port visits`, `encounters (Potential Transshipment)` and `apparent fishing activity` based on vessel movement patterns. Please [learn more about Events API here](https://globalfishingwatch.org/our-apis/documentation#events-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated)." + ] + }, + { + "cell_type": "markdown", + "id": "af80cd9c-fe29-4650-9052-dbe7b623eb8d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel ID** from 4Wings API\n", + "2. **[Event Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - Port visits, encounters (potential transshipment), and fishing events.\n", + "3. **Time Range** - Last 6 months.\n", + "4. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)**:\n", + " - `public-global-port-visits-events::latest` (Port Visits)\n", + " - `public-global-encounters-events:latest` (Encounters between vessels)\n", + " - `public-global-fishing-events:latest` (Fishing activity)\n", + "5. **[Encounter Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - FISHING-FISHING" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "ae1567e5-0594-4eb3-a78a-5e8902deb2ac", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_result = await gfw_client.events.get_all_events(\n", + " datasets=[\n", + " \"public-global-encounters-events:latest\",\n", + " \"public-global-fishing-events:latest\",\n", + " \"public-global-port-visits-events:latest\",\n", + " ],\n", + " vessels=step_2_vessel_ids,\n", + " types=[\"ENCOUNTER\", \"FISHING\", \"PORT_VISIT\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " encounter_types=[\"FISHING-FISHING\"],\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "904c3745-e999-4fc7-a3fe-dd639c6a87c2", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_df = step_4_events_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7f2ef6a8-6eed-47c5-bb44-253bad118956", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 418 entries, 0 to 417\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 418 non-null datetime64[ns, UTC]\n", + " 1 end 418 non-null datetime64[ns, UTC]\n", + " 2 id 418 non-null object \n", + " 3 type 418 non-null object \n", + " 4 position 418 non-null object \n", + " 5 regions 418 non-null object \n", + " 6 bounding_box 418 non-null object \n", + " 7 distances 418 non-null object \n", + " 8 vessel 418 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 414 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 4 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 45.8+ KB\n" + ] + } + ], + "source": [ + "step_4_events_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "39b4f990-1da9-4862-b9fc-554f7b4c7dc0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "type\n", + "fishing 414\n", + "port_visit 4\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_events_df[\"type\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "ccb71753-df83-4ca1-8a43-89fa2cb344d4", + "metadata": {}, + "source": [ + "### Explore Apparent Fishing Events" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "87b32f2a-29ea-4f11-87c2-a16655ac5005", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_events_df = step_4_events_df[step_4_events_df[\"fishing\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "7ee57f28-eff1-40d7-865a-e3ad04103b4c", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_fishing_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_fishing_events_df[\"fishing\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "4a8deceb-aaef-4fe3-8a43-88b4c34d2a70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 414 entries, 0 to 413\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 414 non-null object \n", + " 1 name 389 non-null object \n", + " 2 ssvid 414 non-null object \n", + " 3 flag 414 non-null object \n", + " 4 type 414 non-null object \n", + " 5 public_authorizations 414 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 total_distance_km 414 non-null float64\n", + " 8 average_speed_knots 414 non-null float64\n", + " 9 average_duration_hours 0 non-null object \n", + " 10 potential_risk 414 non-null bool \n", + " 11 vessel_public_authorization_status 414 non-null object \n", + "dtypes: bool(1), float64(2), object(9)\n", + "memory usage: 36.1+ KB\n" + ] + } + ], + "source": [ + "step_4_fishing_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "0b95e76a-7fe8-45ba-87a3-ffab7d15c7d1", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidtotal_distance_kmaverage_speed_knots
0HUNG CHUAN SHUN41600749618.4810568.841667
1HUNG CHUAN SHUN41600749634.8675598.240000
2HUNG CHUAN SHUN41600749611.0868508.208333
3HUNG CHUAN SHUN41600749612.6996508.266667
4HUNG CHUAN SHUN41600749656.7880346.248000
...............
409SENSHU MARU NO.343110069012.1644945.083333
410SENSHU MARU NO.343110069013.1911243.986957
411SENSHU MARU NO.34311006908.6856593.850000
412SENSHU MARU NO.343110069015.7219873.686667
413SENSHU MARU NO.343110069028.5537793.728571
\n", + "

414 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " name ssvid total_distance_km average_speed_knots\n", + "0 HUNG CHUAN SHUN 416007496 18.481056 8.841667\n", + "1 HUNG CHUAN SHUN 416007496 34.867559 8.240000\n", + "2 HUNG CHUAN SHUN 416007496 11.086850 8.208333\n", + "3 HUNG CHUAN SHUN 416007496 12.699650 8.266667\n", + "4 HUNG CHUAN SHUN 416007496 56.788034 6.248000\n", + ".. ... ... ... ...\n", + "409 SENSHU MARU NO.3 431100690 12.164494 5.083333\n", + "410 SENSHU MARU NO.3 431100690 13.191124 3.986957\n", + "411 SENSHU MARU NO.3 431100690 8.685659 3.850000\n", + "412 SENSHU MARU NO.3 431100690 15.721987 3.686667\n", + "413 SENSHU MARU NO.3 431100690 28.553779 3.728571\n", + "\n", + "[414 rows x 4 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"total_distance_km\",\n", + " \"average_speed_knots\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "2416d761-b334-4995-ba67-81ff96c3dd57", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "416007496 363\n", + "431100690 26\n", + "412331032 25\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "dfdc826c-d854-4f1c-bf0b-82560d23a2f4", + "metadata": {}, + "source": [ + "### Explore Port Visit Events" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "337ddf63-42ba-4ea7-a56d-2d8d602f5a22", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visit_events_df = step_4_events_df[step_4_events_df[\"port_visit\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "a77465d1-02ce-42bb-a0b3-7c243cf02a40", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visits_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_port_visit_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_port_visit_events_df[\"port_visit\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "566e8a67-8fff-4d10-9749-83c6dae727b7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 4 entries, 0 to 3\n", + "Data columns (total 37 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 4 non-null object \n", + " 1 name 3 non-null object \n", + " 2 ssvid 4 non-null object \n", + " 3 flag 4 non-null object \n", + " 4 type 4 non-null object \n", + " 5 public_authorizations 4 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 visit_id 4 non-null object \n", + " 8 confidence 4 non-null object \n", + " 9 duration_hrs 4 non-null float64\n", + " 10 start_anchorage_anchorage_id 4 non-null object \n", + " 11 start_anchorage_at_dock 4 non-null bool \n", + " 12 start_anchorage_distance_from_shore_km 4 non-null float64\n", + " 13 start_anchorage_flag 4 non-null object \n", + " 14 start_anchorage_id 4 non-null object \n", + " 15 start_anchorage_lat 4 non-null float64\n", + " 16 start_anchorage_lon 4 non-null float64\n", + " 17 start_anchorage_name 4 non-null object \n", + " 18 start_anchorage_top_destination 4 non-null object \n", + " 19 intermediate_anchorage_anchorage_id 4 non-null object \n", + " 20 intermediate_anchorage_at_dock 4 non-null bool \n", + " 21 intermediate_anchorage_distance_from_shore_km 4 non-null float64\n", + " 22 intermediate_anchorage_flag 4 non-null object \n", + " 23 intermediate_anchorage_id 4 non-null object \n", + " 24 intermediate_anchorage_lat 4 non-null float64\n", + " 25 intermediate_anchorage_lon 4 non-null float64\n", + " 26 intermediate_anchorage_name 4 non-null object \n", + " 27 intermediate_anchorage_top_destination 4 non-null object \n", + " 28 end_anchorage_anchorage_id 4 non-null object \n", + " 29 end_anchorage_at_dock 4 non-null bool \n", + " 30 end_anchorage_distance_from_shore_km 4 non-null float64\n", + " 31 end_anchorage_flag 4 non-null object \n", + " 32 end_anchorage_id 4 non-null object \n", + " 33 end_anchorage_lat 4 non-null float64\n", + " 34 end_anchorage_lon 4 non-null float64\n", + " 35 end_anchorage_name 4 non-null object \n", + " 36 end_anchorage_top_destination 4 non-null object \n", + "dtypes: bool(3), float64(10), object(24)\n", + "memory usage: 1.2+ KB\n" + ] + } + ], + "source": [ + "step_4_port_visits_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "0381a7bd-cf81-4b58-9f8d-f01601121ad2", + "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", + " \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", + " \n", + " \n", + "
namessvidconfidencestart_anchorage_nameintermediate_anchorage_nameend_anchorage_name
0HUNG CHUAN SHUN4160074964TEMATEMATEMA
1SENSHU MARU NO.34311006904TEMATEMATEMA
2None4123310324DAKARDAKARDAKAR
3SENSHU MARU NO.34311006904TEMATEMATEMA
\n", + "
" + ], + "text/plain": [ + " name ssvid confidence start_anchorage_name \\\n", + "0 HUNG CHUAN SHUN 416007496 4 TEMA \n", + "1 SENSHU MARU NO.3 431100690 4 TEMA \n", + "2 None 412331032 4 DAKAR \n", + "3 SENSHU MARU NO.3 431100690 4 TEMA \n", + "\n", + " intermediate_anchorage_name end_anchorage_name \n", + "0 TEMA TEMA \n", + "1 TEMA TEMA \n", + "2 DAKAR DAKAR \n", + "3 TEMA TEMA " + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"confidence\",\n", + " \"start_anchorage_name\",\n", + " \"intermediate_anchorage_name\",\n", + " \"end_anchorage_name\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "2d340b6b-3d88-4c48-a699-305a75e706a4", + "metadata": {}, + "source": [ + "### What We’ve Learned from Step 4" + ] + }, + { + "cell_type": "markdown", + "id": "709d2a5c-5246-4995-ab68-0997adf62349", + "metadata": {}, + "source": [ + "- `4: port visits`, `0: encounters`, and `414: fishing` events were found for the queried vessels in the given date range.\n", + "- Some events were missed due to **AIS data coverage gaps**.\n", + "- Different filters may need to be applied to refine results." + ] + }, + { + "cell_type": "markdown", + "id": "be4b21a0-f3ea-4f10-a61f-cf121cbe078e", + "metadata": {}, + "source": [ + "**Caveats & Considerations**" + ] + }, + { + "cell_type": "markdown", + "id": "c7625234-6210-4701-91b2-cca2cfe43494", + "metadata": {}, + "source": [ + "- **A lack of recorded encounters or any other events does not confirm the absence of such activities**—AIS coverage, reporting behavior, and dataset updates can impact results.\n", + "- **Further investigation may be required**, including manual validation using historical data or consulting additional sources." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "## Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Identify fishing effort by **gear type** in Ghanaian EEZ.\n", + "2. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve vessel IDs for potential **longliners**.\n", + "3. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch detailed **vessel identity** & **ownership**.\n", + "4. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** - Attempt to detect fleet activity (**port visits**, **encounters**, and **apparent fishing** events)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index d825bef..6c4d5df 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -36,7 +36,7 @@ "id": "3d31e934-e291-453d-aad9-6e0e61d1318e", "metadata": {}, "source": [ - "**Note:** See the [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat) 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." ] }, { diff --git a/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb b/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb new file mode 100644 index 0000000..c37fb6a --- /dev/null +++ b/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb @@ -0,0 +1,1260 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze apparent fishing effort in Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d79f0ab4-ab4d-4098-82b0-b6a5c772e101", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Analyze apparent fishing effort in [Senegalese EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8371) region and monitor vessel activities** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, and **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "eafaa9d1-2143-452c-813c-75b21fd2198c", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc98323c-c9e4-401c-8f26-f551968c003a", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "047ff069-3c87-47fe-bb4a-acb920df2137", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "708e137f-6aa0-461e-b1af-33512a2093fc", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: A Port Inspector Monitoring Vessel Activity**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Mamadou, a port inspector in Dakar, Senegal, monitors vessel activity within **[Senegalese Exclusive Economic Zone (EEZ)]((https://www.marineregions.org/gazetteer.php?p=details&id=8371))**. His goal is to:\n", + "\n", + "1. Analyzing apparent fishing effort, specifically for **trawlers** in Senegalese EEZ.\n", + "2. Identifying vessels involved in **apparent trawling activity** and determining their reported **flag states**.\n", + "3. Checking vessel history, including prior **encounters (or potential transshipment)** or **port visits**.\n", + "4. Generating reports for enforcement authorities to assess risks." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – To retrieve **apparent fishing effort** data for trawlers operating in Senegalese EEZ over the past 3 months.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – To retrieve **detailed vessel information**, including `flag`, `ownership history`, and `authorizations`." + ] + }, + { + "cell_type": "markdown", + "id": "a6006ce5-675f-4d1f-89a5-69130ff1ed5b", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "5413d78e-e745-4f74-a062-f303c7a1669f", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "7d5e3571-f47f-4c2f-8d0d-0c89baae4411", + "metadata": {}, + "source": [ + "Before making API requests, Mamadou must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "75a985b1-3803-48d9-b2f3-f12b29bd29e7", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Senegalese EEZ, the region ID is 8371](https://www.marineregions.org/gazetteer.php?p=details&id=8371)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Apparent Fishing Effort in Senegalese EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "4bede3c0-3d01-4661-8b88-467244417d20", + "metadata": {}, + "source": [ + "Mamadou **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **apparent fishing effort for all vessels**, grouping them by **vessel ID** in **[Senegalese EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8371)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "2e2e42d9-1b9e-4115-b601-72d0e86ab91d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8371 Senegalese EEZ]((https://www.marineregions.org/gazetteer.php?p=details&id=8371))\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 3 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID\n", + "4. **[Gear Type](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported)** - Trawlers " + ] + }, + { + "cell_type": "markdown", + "id": "849f6157-fa79-456f-8974-d294c77a0729", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 2 below**.\n" + ] + }, + { + "cell_type": "markdown", + "id": "cf72ff2d-afd7-45bb-8350-aceaebc154d4", + "metadata": {}, + "source": [ + "**Explanation of Parameters & Considerations**\n", + "\n", + "- Gear types, such as **trawlers**, are inferred based on **Global Fishing Watch’s vessel classification system**, which relies on **AIS data and vessel public registries**. The **gear type associated with each vessel is not always 100% accurate**, as it may be derived from historical sources or inferred from movement patterns. See more details on [supported gear types here](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported).\n", + "- Also, please see data caveats regarding [vessel types and their classification here](https://globalfishingwatch.org/our-apis/documentation#vessel-types).\n", + "- See more details on retrieving [Region IDs here](https://globalfishingwatch.org/our-apis/documentation#regions)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "db35d1b2-ba32-4a58-97f3-17059b3de164", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"MONTHLY\",\n", + " filters=[\"geartype in ('trawlers')\"],\n", + " start_date=\"2024-11-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8371\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "301f888e-3b7e-4946-a7aa-496e05b53cbd", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "866f84fb-50c4-47e2-95fa-43fbc06d17cd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 170 entries, 0 to 169\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 170 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 170 non-null object \n", + " 3 gear_type 170 non-null object \n", + " 4 hours 170 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 170 non-null object \n", + " 7 vessel_type 170 non-null object \n", + " 8 entry_timestamp 170 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 170 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 170 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 170 non-null datetime64[ns, UTC]\n", + " 12 imo 170 non-null object \n", + " 13 mmsi 170 non-null object \n", + " 14 call_sign 170 non-null object \n", + " 15 dataset 170 non-null object \n", + " 16 report_dataset 170 non-null object \n", + " 17 ship_name 170 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 26.7+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c76de7b9-260b-4469-aea5-0ad8fe2f25a4", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0CHNTRAWLERS31.888889412444322MIN LONG YU61146
1SENTRAWLERS524.815556663093000AMINE
2CHNTRAWLERS0.368056412209175MENGXIN24
3ESPTRAWLERS1.306389225987981CIUDAD DE HUELVA
4CHNTRAWLERS216.545000412549331YUAN YU 886
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146\n", + "1 SEN TRAWLERS 524.815556 663093000 AMINE\n", + "2 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", + "3 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", + "4 CHN TRAWLERS 216.545000 412549331 YUAN YU 886" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "792a7b37-50c6-4218-afc9-1e2d1bcdfdb6", + "metadata": {}, + "source": [ + "### Explore Vessels Potentially Engaged in Trawling Activity in the Senegalese EEZ" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c44d3d72-ebe5-4fe0-85fb-8e8675bd1922", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"flag\", \"gear_type\", \"mmsi\", \"ship_name\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "545d63f0-e3b6-4e81-8c5c-55990eeec9b0", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typemmsiship_namehours
66SENTRAWLERS663178000NUEVONOSOLAR1678.888333
52SENTRAWLERS663115000BETTY1648.771944
49SENTRAWLERS663112000TADORNE1610.828611
42SENTRAWLERS663039000SEGUNDO SAN RAFAEL1595.538333
74SENTRAWLERS663250000PRAIA DA MAROSA1573.587500
\n", + "
" + ], + "text/plain": [ + " flag gear_type mmsi ship_name hours\n", + "66 SEN TRAWLERS 663178000 NUEVONOSOLAR 1678.888333\n", + "52 SEN TRAWLERS 663115000 BETTY 1648.771944\n", + "49 SEN TRAWLERS 663112000 TADORNE 1610.828611\n", + "42 SEN TRAWLERS 663039000 SEGUNDO SAN RAFAEL 1595.538333\n", + "74 SEN TRAWLERS 663250000 PRAIA DA MAROSA 1573.587500" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3f948958-ebce-4478-8b17-d6143c38956b", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "7d51287d-263b-4ff5-a40a-5efa7e7ea0a4", + "metadata": {}, + "source": [ + "- There are vessels appear to have been engaged in potential trawling activity in Senegalese EEZ over the past 3 months i.e.,:\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)`\n", + " - `BETTY (mmsi: 663115000, flag: SEN)`\n", + "- We will retrieve these vessels' `ownership`, `flag history`, and `authorizations` in **Step 2 to validate** them." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "dcbde755-0e9c-48d9-babe-aaee3179b88d", + "metadata": {}, + "source": [ + "Mamadou queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "ba645e15-f111-48f3-96a4-7e091f27669e", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), **Step 1 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "42a309da-6a56-46a0-aa86-2a148d21d855", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "5b507df7-99fe-4bb2-82da-7ed4ad4cfa8e", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_vessel_mmsis = list(step_1_agg_report_df[\"mmsi\"].head(n=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f87106f0-b2a0-482c-bd1f-d11119ee53a3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['663178000', '663115000']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_vessel_mmsis" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1eb89d2a-4d53-4d67-a668-0cbb233e950c", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_vessel_ids = list(\n", + " step_1_report_df[step_1_report_df[\"mmsi\"].isin(step_1_vessel_mmsis)][\n", + " \"vessel_id\"\n", + " ].unique()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e670a688-3af0-410d-b93b-ec1e06ec4e09", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['894bc3ec6-6ade-f09c-e792-ff2e947508d8',\n", + " 'bf28c5a58-8c83-8690-8689-7f2d520f926e']" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "428889bd-4761-4301-b21e-fbc37eba5622", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_1_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c64d68dc-b952-412f-827c-df5236c98bd7", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessels_df = step_2_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "757e6c3c-d0df-4b8f-839d-1e31518d42d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2 entries, 0 to 1\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 2 non-null object\n", + " 1 registry_info_total_records 2 non-null int64 \n", + " 2 registry_info 2 non-null object\n", + " 3 registry_owners 2 non-null object\n", + " 4 registry_public_authorizations 2 non-null object\n", + " 5 combined_sources_info 2 non-null object\n", + " 6 self_reported_info 2 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 244.0+ bytes\n" + ] + } + ], + "source": [ + "step_2_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "7746d027-fb76-41dd-86e9-b949284ec19c", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "4767e025-e26e-4a61-8971-8f2cc90385cc", + "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", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '199483471cd2da3717552fddb1a3172a', 's...[{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...[{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...
1[{'id': '29fef17154387858d8d4c777311c57f7', 's...[{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ...[{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", + "1 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", + "1 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "\n", + " self_reported_info \n", + "0 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... \n", + "1 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "46760bde-049d-433c-817d-ae63b1c58924", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "7efdc6d6-52d8-40bb-9537-e09f242fdb25", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_registry_info_df = pd.json_normalize(\n", + " step_2_vessels_df[\"registry_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "27ab60a9-6496-4406-9ae4-57a7aa97f6fa", + "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", + " \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", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0663115000SENBETTYBETTY[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
1663178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
2762178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
3552178000SENNUEVO NOSO LARNUEVONOSOLAR[TRAWLERS][IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 663115000 SEN BETTY BETTY [TRAWLERS] \n", + "1 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "2 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "3 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "\n", + " source_code \n", + "0 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "1 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "2 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", + "3 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "db341dcf-c0a4-48df-bcc9-1e8fa78d3b25", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "24cec6f2-3e70-4396-a779-13ace779733f", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_registry_owners_df = pd.json_normalize(\n", + " step_2_vessels_df[\"registry_owners\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "16f804f4-ea4f-4a07-8c53-497e09deddfd", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0663115000SENARMEMENT SOPASEN[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
1663178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
2663176000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
3762178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
4552178000ESPSENEVISA[TMT_NATIONAL, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name source_code\n", + "0 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "1 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "2 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "3 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "4 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "7a22580f-7c7a-4181-9a80-e37687cc0471", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "c2fa4bdd-1b51-4b37-abf5-aa18a1cab3e5", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_self_reported_info_df = pd.json_normalize(\n", + " step_2_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d1b559c7-4587-4019-a843-181017dd3f07", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0663115000SENBETTYBETTY[AIS]
1663178000SENNUEVONOSOLARNUEVONOSOLAR[AIS]
2663178000SENNUEVO=NOSOLAR+3&!U.?NUEVONOSOLAR3U[AIS]
3762178000NoneNUEVO NOSOLARNUEVONOSOLAR[AIS]
4552178000NoneNUEVO NOSOLARNUEVONOSOLAR[AIS]
5663178000SENNUEVO NOSOLARNUEVONOSOLAR[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 663115000 SEN BETTY BETTY [AIS]\n", + "1 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", + "2 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", + "3 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "4 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "5 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "6a6bcbcd-49a8-4575-9003-d8495deeb2d3", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "53b4b694-b730-451c-b853-01485b6ca38c", + "metadata": {}, + "source": [ + "- **Vessel Identity:**\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)`- appears to be registered under Senegal (SEN)\n", + " - `BETTY (mmsi: 663115000, flag: SEN)` - appears to be registered under Senegal (SEN)\n", + "- **Ownership & Historical Changes:**\n", + " - `NUEVONOSOLAR (mmsi: 663178000, flag: SEN)` - **SENEVISA** appears to be listed as the registered owner.\n", + " - `BETTY (mmsi: 663115000, flag: SEN)`- **ARMEMENT SOPASEN** appears to be listed as the registered owner." + ] + }, + { + "cell_type": "markdown", + "id": "e35fec91-477e-4fb5-99f2-766b3a5dbeff", + "metadata": {}, + "source": [ + "**Next Steps:**\n", + "\n", + "- Further, **validate ownership history** using official registry sources.\n", + "- Assess whether any **historical changes** in `flag`, `name`, or `ownership` are relevant for enforcement.\n", + "- Generate an **apparent activity report** with all available details." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "## Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve apparent fishing effort for **trawlers** within Senegalese EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch detailed **vessel identity**, **ownership history**, and **public authorizations** for vessels detected in **Step 1**.\n", + "3. **Analyze vessel history** - Compare **registry records**, **AIS self-reported** data, and inferred information to identify potential flag-hopping or historical changes in vessel identity.\n", + "4. **Assess authorizations** - Cross-check whether vessels have publicly available fishing authorizations and consider external official sources for further verification.\n", + "5. **Generate an analysis report** - Provide enforcement authorities with a structured report highlighting vessel activity, identity records, and any notable discrepancies for further investigation." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb b/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb new file mode 100644 index 0000000..0953cfe --- /dev/null +++ b/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb @@ -0,0 +1,2173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze apparent fishing effort in Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d79f0ab4-ab4d-4098-82b0-b6a5c772e101", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Analyze apparent fishing effort in [Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466) region and monitor industrial trawlers** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**, and **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "eafaa9d1-2143-452c-813c-75b21fd2198c", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc98323c-c9e4-401c-8f26-f551968c003a", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "047ff069-3c87-47fe-bb4a-acb920df2137", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "708e137f-6aa0-461e-b1af-33512a2093fc", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: A Fisheries Enforcement Officer Monitoring Industrial Trawlers**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Maria, a fisheries enforcement officer in Argentina, monitors industrial trawlers operating within **[Argentinian Exclusive Economic Zone (EEZ)](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. His goal is to:\n", + "\n", + "1. Analyzing apparent fishing effort for **trawlers** operating in Argentinian EEZ.\n", + "2. Identifying vessels involved in **apparent trawling activity** and determining their reported **flag states**.\n", + "3. Checking vessel history, including **potential transshipment** and **port visits**.\n", + "4. Generating reports to support fisheries enforcement decisions." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Retrieve **apparent fishing effort** data for trawlers.\n", + "2. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Group vessels by ID that are involved in **trawling activity**.\n", + "3. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – Retrieve **vessel identity** & **ownership** details.\n", + "4. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** – Fetch **port visits** & **potential transshipment** history. " + ] + }, + { + "cell_type": "markdown", + "id": "c93924be-f36e-4f6c-830f-4d06c03d08f7", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "01169672-36d5-4b2b-969d-471070d75f8c", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "88789a27-1e15-44af-ba81-7d07ded02e4b", + "metadata": {}, + "source": [ + "Before making API requests, Maria must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "75a985b1-3803-48d9-b2f3-f12b29bd29e7", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Argentinian EEZ, the region ID is 8466](https://www.marineregions.org/gazetteer.php?p=details&id=8466)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "35a0691d-b747-48e6-8b02-5c2f54a5d536", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Apparent Fishing Effort in Argentinian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "d57cd039-a667-44f7-b785-8d0e50530333", + "metadata": {}, + "source": [ + "Maria **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **apparent fishing effort for all vessels**, grouping them by **gear type** in **[Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "6229af14-613a-4809-96f5-9cb3d6bd3461", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - 8466 Argentinian EEZ\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 6 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Gear Type" + ] + }, + { + "cell_type": "markdown", + "id": "b945aa10-40c3-490a-84e7-89092badd783", + "metadata": {}, + "source": [ + "**Why This Step?**\n", + "\n", + "- Identifies which gear types (e.g., `trawlers`, `squid jiggers` etc.) are most active in the Argentinian EEZ.\n", + "- Establishes baseline fishing activity trends before narrowing the search to specific vessels." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "62b9b9e5-4170-40d0-9aef-7579beb89bc0", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"GEARTYPE\",\n", + " temporal_resolution=\"MONTHLY\",\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8466\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "4d6190fc-a8fa-4d59-914e-ebae41943381", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d98ca51f-bb46-4edc-9a61-3e26c56bbcc8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 40 entries, 0 to 39\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 40 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 0 non-null object \n", + " 3 gear_type 40 non-null object \n", + " 4 hours 40 non-null float64\n", + " 5 vessel_ids 40 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 40 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: float64(1), int64(1), object(18)\n", + "memory usage: 6.4+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ce844c77-6cf0-4648-bdfb-3a72589c0785", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
0inconclusive215.6238892
1set_longlines17.9258331
2inconclusive98.1558332
3other_purse_seines57.3775001
4set_longlines153.9602783
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "0 inconclusive 215.623889 2\n", + "1 set_longlines 17.925833 1\n", + "2 inconclusive 98.155833 2\n", + "3 other_purse_seines 57.377500 1\n", + "4 set_longlines 153.960278 3" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"gear_type\", \"hours\", \"vessel_ids\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "45319c2a-e82e-4a9a-8a2d-2ea6d9cdada4", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"gear_type\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"), vessel_ids=(\"vessel_ids\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "121465c6-65ef-4efa-9d8a-4a0a136564bd", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
8trawlers240642.4144441315
1fishing16023.20138994
7squid_jigger6124.06222244
2fixed_gear1948.32555616
3inconclusive1072.35138914
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "8 trawlers 240642.414444 1315\n", + "1 fishing 16023.201389 94\n", + "7 squid_jigger 6124.062222 44\n", + "2 fixed_gear 1948.325556 16\n", + "3 inconclusive 1072.351389 14" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "449828f2-dda7-422c-8cfb-770ced828ca6", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "e83e24d9-edb1-45d3-af4a-fa60b155ecab", + "metadata": {}, + "source": [ + "- Multiple **gear types** were potentially detected in Argentinian EEZ.\n", + "- `Trawlers` appear to be operating, but further **vessel-level investigation** is needed." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel IDs for Trawlers" + ] + }, + { + "cell_type": "markdown", + "id": "4bede3c0-3d01-4661-8b88-467244417d20", + "metadata": {}, + "source": [ + "Maria refines her **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** request to group by **vessel ID**, and filtering only for **trawlers** in **[Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "2e2e42d9-1b9e-4115-b601-72d0e86ab91d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8466 Argentinian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8466)\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 6 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID\n", + "4. **[Gear Type](https://globalfishingwatch.org/our-apis/documentation#gear-types-supported)** - Trawlers " + ] + }, + { + "cell_type": "markdown", + "id": "849f6157-fa79-456f-8974-d294c77a0729", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 3 below**.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "db35d1b2-ba32-4a58-97f3-17059b3de164", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"HIGH\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " filters=[\"geartype in ('trawlers')\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8466\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "301f888e-3b7e-4946-a7aa-496e05b53cbd", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_df = step_2_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "866f84fb-50c4-47e2-95fa-43fbc06d17cd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 385 entries, 0 to 384\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 385 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 385 non-null object \n", + " 3 gear_type 385 non-null object \n", + " 4 hours 385 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 385 non-null object \n", + " 7 vessel_type 385 non-null object \n", + " 8 entry_timestamp 385 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 385 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 385 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 385 non-null datetime64[ns, UTC]\n", + " 12 imo 385 non-null object \n", + " 13 mmsi 385 non-null object \n", + " 14 call_sign 385 non-null object \n", + " 15 dataset 385 non-null object \n", + " 16 report_dataset 385 non-null object \n", + " 17 ship_name 385 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 60.3+ KB\n" + ] + } + ], + "source": [ + "step_2_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "82a786a1-c437-430e-aeb5-f61d02a5f900", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0URYTRAWLERS10.023056770576463KALATXORI
1ARGTRAWLERS326.160833701079000ENTRENA UNO
2ARGTRAWLERS714.842500701000882FELIX AUGUSTO
3ARGTRAWLERS641.522222701000932ANTONIO ALVAREZ
4ARGTRAWLERS295.007500701000820CORAJE
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 URY TRAWLERS 10.023056 770576463 KALATXORI\n", + "1 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", + "2 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", + "3 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "4 ARG TRAWLERS 295.007500 701000820 CORAJE" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "630d95dd-8f82-407f-b223-f55e981e3593", + "metadata": {}, + "source": [ + "### Explore Vessels Potentially Engaged in Trawling Activity in the Argentinian EEZ" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "984052a3-3920-4fce-8894-4b67af4a8a69", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_agg_report_df = (\n", + " step_2_report_df.groupby([\"flag\", \"gear_type\", \"mmsi\", \"ship_name\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "83e4dafb-4491-40c9-9f4d-f4cc1e2b7766", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typemmsiship_namehours
297ARGTRAWLERS701024000ATLANTIC SURF III3151.855278
247ARGTRAWLERS701006605CAPESANTE2270.097500
22ARGTRAWLERS701000577MISS TIDE2244.895833
296ARGTRAWLERS701023000CAROLINA P2065.586944
301ARGTRAWLERS701037000DON PEDRO1807.146111
\n", + "
" + ], + "text/plain": [ + " flag gear_type mmsi ship_name hours\n", + "297 ARG TRAWLERS 701024000 ATLANTIC SURF III 3151.855278\n", + "247 ARG TRAWLERS 701006605 CAPESANTE 2270.097500\n", + "22 ARG TRAWLERS 701000577 MISS TIDE 2244.895833\n", + "296 ARG TRAWLERS 701023000 CAROLINA P 2065.586944\n", + "301 ARG TRAWLERS 701037000 DON PEDRO 1807.146111" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_agg_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3f948958-ebce-4478-8b17-d6143c38956b", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "d4fb7cba-a577-45fe-88fa-8e5001bb9869", + "metadata": {}, + "source": [ + "- There are vessels appear to have been engaged in potential trawling activity in Argentinian EEZ over the past 6 months i.e.,:\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)`\n", + "- We will retrieve these vessels' `ownership`, `flag history`, and `authorizations` in **Step 3 to validate** them." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 3: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "dcbde755-0e9c-48d9-babe-aaee3179b88d", + "metadata": {}, + "source": [ + "Maria queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "ba645e15-f111-48f3-96a4-7e091f27669e", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), **Step 2 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "42a309da-6a56-46a0-aa86-2a148d21d855", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "24e8452f-7848-4c88-89db-66e4bf182cd1", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_mmsis = list(step_2_agg_report_df[\"mmsi\"].head(n=2))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f25ceec0-3188-4584-bb95-f76c9e0ac578", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['701024000', '701006605']" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_mmsis" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "446b506a-a19f-49cd-9110-ed8b9103af8b", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_ids = list(\n", + " step_2_report_df[step_2_report_df[\"mmsi\"].isin(step_2_vessel_mmsis)][\n", + " \"vessel_id\"\n", + " ].unique()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "6233b1eb-ed4b-4ba9-bce8-faa1ee027dcc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['de8a03acd-dc6c-8e08-2867-24e55ffc0017',\n", + " '8e930bac5-594b-aa3f-081d-d12668819e1f']" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "428889bd-4761-4301-b21e-fbc37eba5622", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_2_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "c64d68dc-b952-412f-827c-df5236c98bd7", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_df = step_3_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "757e6c3c-d0df-4b8f-839d-1e31518d42d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2 entries, 0 to 1\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 2 non-null object\n", + " 1 registry_info_total_records 2 non-null int64 \n", + " 2 registry_info 2 non-null object\n", + " 3 registry_owners 2 non-null object\n", + " 4 registry_public_authorizations 2 non-null object\n", + " 5 combined_sources_info 2 non-null object\n", + " 6 self_reported_info 2 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 244.0+ bytes\n" + ] + } + ], + "source": [ + "step_3_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "c2d30f1a-352b-42cb-8ee8-acd67f16103f", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "4767e025-e26e-4a61-8971-8f2cc90385cc", + "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", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '45502524c9a150e77869ee647423dba1', 's...[{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...[{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...
1[{'id': '2d939efefd3f45788ed103ff0723f564', 's...[{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'...[{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", + "1 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", + "1 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "\n", + " self_reported_info \n", + "0 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... \n", + "1 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "46760bde-049d-433c-817d-ae63b1c58924", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "7efdc6d6-52d8-40bb-9537-e09f242fdb25", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "27ab60a9-6496-4406-9ae4-57a7aa97f6fa", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0701024000ARGATLANTIC SURF IIIATLANTICSURF3[TRAWLERS][IMO, TMT_OTHER_OFFICIAL]
1701006605ARGCAPESANTECAPESANTE[TRAWLERS][GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF...
2316003980CANATLANTICLEADERATLANTICLEADER[TRAWLERS][IMO, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", + "1 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", + "2 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "\n", + " source_code \n", + "0 [IMO, TMT_OTHER_OFFICIAL] \n", + "1 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "2 [IMO, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "5787e4ee-69e0-4769-ba05-9a57254c7289", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "afe07c2a-81cb-45b3-9e86-c23b4ef67fe9", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_owners_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_owners\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "df7e0b65-0ab0-4722-aaec-3d11c7674b8f", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0701024000ARGGLACIAR PESQUERA[TMT_OTHER_OFFICIAL]
1701006605CANCLEARWATER SEAFOODS[RESEARCH-PAPER]
2316003980CANCS MANPAR[TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name source_code\n", + "0 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]\n", + "1 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", + "2 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "7a22580f-7c7a-4181-9a80-e37687cc0471", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "c2fa4bdd-1b51-4b37-abf5-aa18a1cab3e5", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_self_reported_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "d1b559c7-4587-4019-a843-181017dd3f07", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0701024000ARGATLANTIC SURF IIIATLANTICSURF3[AIS]
1701006605ARGCAPESANTECAPESANTE[AIS]
2316003980CANATLANTIC LEADERATLANTICLEADER[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]\n", + "1 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", + "2 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "6a6bcbcd-49a8-4575-9003-d8495deeb2d3", + "metadata": {}, + "source": [ + "### What We have Learned from Step 3" + ] + }, + { + "cell_type": "markdown", + "id": "da9c80ea-94d7-4945-8e90-9f5ec4bad8f1", + "metadata": {}, + "source": [ + "- **Vessel Identity:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- appears to be registered under Argentina (ARG)\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - appears to be registered under Argentina (ARG)\n", + "- **Ownership & Historical Changes:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)` - **GLACIAR PESQUERA** appears to be listed as the registered owner.\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)`- **CLEARWATER SEAFOODS** appears to be listed as the registered owner." + ] + }, + { + "cell_type": "markdown", + "id": "4803ae37-3f96-40dc-8db8-690b51710735", + "metadata": {}, + "source": [ + "## Step 4: Detect Potential Port Visits, Encounters, or Fishing Events" + ] + }, + { + "cell_type": "markdown", + "id": "058cc09a-64dc-4913-a90c-cadc7d38439a", + "metadata": {}, + "source": [ + "Now Maria checks `port visits`, `encounters`, and `fishing events` using the **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**, which allows **monitoring of vessel activities** such as `potential transshipments`, `unauthorized port entries`, or `fishing activity patterns`." + ] + }, + { + "cell_type": "markdown", + "id": "c8ee8f1c-7e5e-487f-ba45-7f7f609ba389", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel ID** from 4Wings API\n", + "2. **[Event Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - Port visits, encounters (potential transshipment), and fishing events.\n", + "3. **Time Range** - Last 6 months.\n", + "4. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)**:\n", + " - `public-global-port-visits-events::latest` (Port Visits)\n", + " - `public-global-encounters-events:latest` (Encounters between vessels)\n", + " - `public-global-fishing-events:latest` (Fishing activity)\n", + "5. **[Encounter Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - CARRIER-FISHING" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "87c3b592-e431-457c-a5f4-5ce07711d52f", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_result = await gfw_client.events.get_all_events(\n", + " datasets=[\n", + " \"public-global-encounters-events:latest\",\n", + " \"public-global-fishing-events:latest\",\n", + " \"public-global-port-visits-events:latest\",\n", + " ],\n", + " vessels=step_2_vessel_ids,\n", + " types=[\"ENCOUNTER\", \"FISHING\", \"PORT_VISIT\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " encounter_types=[\"CARRIER-FISHING\"],\n", + " sort=\"-start\",\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "64cb0776-7f0d-481e-be98-da00b448c720", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_df = step_4_events_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "4c82d647-3870-4a54-979b-7f586575e5c1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 359 entries, 0 to 358\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 359 non-null datetime64[ns, UTC]\n", + " 1 end 359 non-null datetime64[ns, UTC]\n", + " 2 id 359 non-null object \n", + " 3 type 359 non-null object \n", + " 4 position 359 non-null object \n", + " 5 regions 359 non-null object \n", + " 6 bounding_box 359 non-null object \n", + " 7 distances 359 non-null object \n", + " 8 vessel 359 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 351 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 8 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 39.4+ KB\n" + ] + } + ], + "source": [ + "step_4_events_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "17d89920-cda2-497d-9797-1e05a84a0daa", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "type\n", + "fishing 351\n", + "port_visit 8\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_events_df[\"type\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "1b472de1-8fef-41a1-a76c-057406d86ee1", + "metadata": {}, + "source": [ + "### Explore Apparent Fishing Events" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "4d360bc4-9762-4ae6-b5b1-1b937e2d2ed0", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_events_df = step_4_events_df[step_4_events_df[\"fishing\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "18ff38d6-9442-4742-9dc9-accfb1299e43", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_fishing_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_fishing_events_df[\"fishing\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "fc6ebae0-eba2-4a8a-892c-6dfc38822bd7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 351 entries, 0 to 350\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 351 non-null object \n", + " 1 name 351 non-null object \n", + " 2 ssvid 351 non-null object \n", + " 3 flag 351 non-null object \n", + " 4 type 351 non-null object \n", + " 5 public_authorizations 351 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 total_distance_km 351 non-null float64\n", + " 8 average_speed_knots 351 non-null float64\n", + " 9 average_duration_hours 0 non-null object \n", + " 10 potential_risk 351 non-null bool \n", + " 11 vessel_public_authorization_status 351 non-null object \n", + "dtypes: bool(1), float64(2), object(9)\n", + "memory usage: 30.6+ KB\n" + ] + } + ], + "source": [ + "step_4_fishing_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "8799e988-56a2-41d5-b472-bc83064e1807", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidtotal_distance_kmaverage_speed_knots
0ATLANTIC SURF III701024000117.5454504.351747
1ATLANTIC SURF III70102400010.4088513.791667
2ATLANTIC SURF III70102400061.3669114.448980
3ATLANTIC SURF III70102400092.1807044.485407
4ATLANTIC SURF III701024000974.7618714.051429
...............
346CAPESANTE70100660595.1280594.202542
347CAPESANTE701006605205.8262824.136848
348CAPESANTE701006605369.3366033.938255
349ATLANTIC SURF III701024000256.9088424.186333
350CAPESANTE701006605208.0719853.971505
\n", + "

351 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " name ssvid total_distance_km average_speed_knots\n", + "0 ATLANTIC SURF III 701024000 117.545450 4.351747\n", + "1 ATLANTIC SURF III 701024000 10.408851 3.791667\n", + "2 ATLANTIC SURF III 701024000 61.366911 4.448980\n", + "3 ATLANTIC SURF III 701024000 92.180704 4.485407\n", + "4 ATLANTIC SURF III 701024000 974.761871 4.051429\n", + ".. ... ... ... ...\n", + "346 CAPESANTE 701006605 95.128059 4.202542\n", + "347 CAPESANTE 701006605 205.826282 4.136848\n", + "348 CAPESANTE 701006605 369.336603 3.938255\n", + "349 ATLANTIC SURF III 701024000 256.908842 4.186333\n", + "350 CAPESANTE 701006605 208.071985 3.971505\n", + "\n", + "[351 rows x 4 columns]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"total_distance_km\",\n", + " \"average_speed_knots\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "3659c048-c8bf-463c-a6cb-fc29f818ed77", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "701024000 245\n", + "701006605 106\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "5da05a04-947e-4f87-b61e-bad015796e5f", + "metadata": {}, + "source": [ + "### Explore Port Visit Events" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "e806616b-6ed7-4c0c-9bf4-2b4a23de2046", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visit_events_df = step_4_events_df[step_4_events_df[\"port_visit\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "58a68605-9432-43fe-b8eb-4d0393f95f60", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visits_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_port_visit_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_port_visit_events_df[\"port_visit\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "685a746e-8091-4321-b851-79a5f3ca0f81", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 8 entries, 0 to 7\n", + "Data columns (total 37 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 8 non-null object \n", + " 1 name 8 non-null object \n", + " 2 ssvid 8 non-null object \n", + " 3 flag 8 non-null object \n", + " 4 type 8 non-null object \n", + " 5 public_authorizations 8 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 visit_id 8 non-null object \n", + " 8 confidence 8 non-null object \n", + " 9 duration_hrs 8 non-null float64\n", + " 10 start_anchorage_anchorage_id 8 non-null object \n", + " 11 start_anchorage_at_dock 8 non-null bool \n", + " 12 start_anchorage_distance_from_shore_km 8 non-null float64\n", + " 13 start_anchorage_flag 8 non-null object \n", + " 14 start_anchorage_id 8 non-null object \n", + " 15 start_anchorage_lat 8 non-null float64\n", + " 16 start_anchorage_lon 8 non-null float64\n", + " 17 start_anchorage_name 8 non-null object \n", + " 18 start_anchorage_top_destination 8 non-null object \n", + " 19 intermediate_anchorage_anchorage_id 8 non-null object \n", + " 20 intermediate_anchorage_at_dock 8 non-null bool \n", + " 21 intermediate_anchorage_distance_from_shore_km 8 non-null float64\n", + " 22 intermediate_anchorage_flag 8 non-null object \n", + " 23 intermediate_anchorage_id 8 non-null object \n", + " 24 intermediate_anchorage_lat 8 non-null float64\n", + " 25 intermediate_anchorage_lon 8 non-null float64\n", + " 26 intermediate_anchorage_name 8 non-null object \n", + " 27 intermediate_anchorage_top_destination 8 non-null object \n", + " 28 end_anchorage_anchorage_id 8 non-null object \n", + " 29 end_anchorage_at_dock 8 non-null bool \n", + " 30 end_anchorage_distance_from_shore_km 8 non-null float64\n", + " 31 end_anchorage_flag 8 non-null object \n", + " 32 end_anchorage_id 8 non-null object \n", + " 33 end_anchorage_lat 8 non-null float64\n", + " 34 end_anchorage_lon 8 non-null float64\n", + " 35 end_anchorage_name 8 non-null object \n", + " 36 end_anchorage_top_destination 8 non-null object \n", + "dtypes: bool(3), float64(10), object(24)\n", + "memory usage: 2.3+ KB\n" + ] + } + ], + "source": [ + "step_4_port_visits_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "0e77b956-f0f8-4fbd-8a49-0116e4401c12", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidconfidencestart_anchorage_nameintermediate_anchorage_nameend_anchorage_name
0ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
1CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
2CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
3ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
4CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
5ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
6CAPESANTE7010066054USHUAIAUSHUAIAUSHUAIA
7ATLANTIC SURF III7010240004MAR DEL PLATAMAR DEL PLATAMAR DEL PLATA
\n", + "
" + ], + "text/plain": [ + " name ssvid confidence start_anchorage_name \\\n", + "0 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "1 CAPESANTE 701006605 4 USHUAIA \n", + "2 CAPESANTE 701006605 4 USHUAIA \n", + "3 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "4 CAPESANTE 701006605 4 USHUAIA \n", + "5 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "6 CAPESANTE 701006605 4 USHUAIA \n", + "7 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "\n", + " intermediate_anchorage_name end_anchorage_name \n", + "0 MAR DEL PLATA MAR DEL PLATA \n", + "1 USHUAIA USHUAIA \n", + "2 USHUAIA USHUAIA \n", + "3 MAR DEL PLATA MAR DEL PLATA \n", + "4 USHUAIA USHUAIA \n", + "5 MAR DEL PLATA MAR DEL PLATA \n", + "6 USHUAIA USHUAIA \n", + "7 MAR DEL PLATA MAR DEL PLATA " + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"confidence\",\n", + " \"start_anchorage_name\",\n", + " \"intermediate_anchorage_name\",\n", + " \"end_anchorage_name\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "32ee1871-f1c7-4561-9384-5a681293e7e5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "701024000 4\n", + "701006605 4\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "61d59d0c-8919-40c4-ac30-bb9ab35a4d53", + "metadata": {}, + "source": [ + "### What We have learned from step 4" + ] + }, + { + "cell_type": "markdown", + "id": "4771fe04-5984-4576-b774-a83f104d7194", + "metadata": {}, + "source": [ + "- **Apparent Fishing Events:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025)\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025)\n", + "- **Port Visit Events:**\n", + " - `ATLANTIC SURF III (mmsi: 701024000, flag: ARG)`- potentially made multiple port visits, including stops at `MAR DEL PLATA`\n", + " - `CAPESANTE (mmsi: 701006605, flag: ARG)` - potentially made multiple port visits, including stops at `USHUAIA`\n", + "- **ENCOUNTER Events:** No explicit **ENCOUNTER** events were returned in the response dataset. Check more details [here](https://globalfishingwatch.org/faqs/what-is-a-vessel-encounter/). You can read more about transshipment behavior from our [report](https://globalfishingwatch.org/wp-content/uploads/GlobalViewOfTransshipment_Aug2017.pdf) or [scientific publication](https://www.frontiersin.org/articles/10.3389/fmars.2018.00240/full)." + ] + }, + { + "cell_type": "markdown", + "id": "f0cf3958-fb92-49c0-ba2f-2cfe971bcbc5", + "metadata": {}, + "source": [ + "**Potential Considerations:**\n", + "\n", + "- The vessel's fishing activities appear near the EEZ boundary, requiring further assessment of compliance with national or RFMO regulations.\n", + "- The absence of matching public authorizations in the RFMO registry does not necessarily indicate illegality, but it suggests that authorities may need to verify through national databases or official sources." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "### Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve apparent fishing effort for **trawlers** within Argentinian EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch **vessel identity**, **ownership history**, and **public authorizations**.\n", + "3. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** - Detect potential **port visits**, **encounters**, and **apparent fishing** events to analyze operational patterns.\n", + "4. **Assess potential risks** - Compare registry records, AIS data, and inferred vessel activity for enforcement follow-ups.\n", + "5. **Generate a report** - Provide a structured analysis for relevant authorities." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb b/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb new file mode 100644 index 0000000..a894429 --- /dev/null +++ b/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb @@ -0,0 +1,1996 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1b582ffc-7477-46c3-b5bf-2caf9d028bf2", + "metadata": {}, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "87eddf13-ac9c-45b0-ae10-24eb1620e07e", + "metadata": {}, + "source": [ + "# Analyze a fleet in Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "2006da5f-b6dc-491b-b64d-ad332e89e814", + "metadata": {}, + "source": [ + "This guide provides detailed instructions to on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to **Monitor a Fleet (a group of vessels) of Tuna Longliners in [Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400) region for Compliance** using **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)**, **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)**, and **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**." + ] + }, + { + "cell_type": "markdown", + "id": "7ac25ecf-ffd7-40d7-9ea0-a6514c9fcd85", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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." + ] + }, + { + "cell_type": "markdown", + "id": "71018cec-10c0-4619-9a7d-838a9f43cb15", + "metadata": {}, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "996ca24b-99e4-4546-805b-697e4c2eb321", + "metadata": {}, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "6be16f6f-19fc-4d19-a0ed-ba370c844fa6", + "metadata": {}, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "af48cf4e-e24c-47aa-a2c5-64cf87be9c33", + "metadata": {}, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "88c09924-87d2-4c86-ad60-aed623416193", + "metadata": {}, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "b7a03d8d-8dec-4096-8395-d8cfc599db69", + "metadata": {}, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d93d57ae-0ec7-4d97-8fea-f679e89fc3b1", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import datetime\n", + "import pandas as pd\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "0b398f94-cd59-49c8-95a3-0ee46cf17e77", + "metadata": {}, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception as exc:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "f5884635-6941-4f97-8b1a-5fd485a95bc4", + "metadata": {}, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b08a0e2c-3b9d-4c5e-b3a0-a5663fa32637", + "metadata": {}, + "source": [ + "## Introduction" + ] + }, + { + "cell_type": "markdown", + "id": "62fe47aa-ed77-4815-b08d-8c96f2480b04", + "metadata": {}, + "source": [ + "**Use Case: Monitoring a Fleet of Tuna Longliners for Compliance**" + ] + }, + { + "cell_type": "markdown", + "id": "5109f67f-aaae-4a7d-9a15-4db740542694", + "metadata": {}, + "source": [ + "Kwame is a fisheries compliance officer in Ghana, responsible for monitoring a fleet of tuna longliners operating within **[Ghanaian Exclusive Economic Zone (EEZ)](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**. His goal is to:\n", + "\n", + "1. Track apparent fishing effort for **longliners** over the last 12 months.\n", + "2. Identify potential vessels in this fleet, their operational patterns, and their activity levels.\n", + "3. Retrieve vessel details, including **flag state**, **ownership history**, and **authorizations**.\n", + "4. Analyze events such as **port visits** and **encounters (potential transshipment)** activities." + ] + }, + { + "cell_type": "markdown", + "id": "b16b1b52-6b68-494a-9d76-ca7a7ab485a0", + "metadata": {}, + "source": [ + "**APIs Used:**\n", + "️\n", + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** – Retrieve apparent fishing effort grouped by vessel ID in Ghanaian EEZ.\n", + "2. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** – Get vessel identity, ownership, and compliance details.\n", + "3. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** – Identify port visits and potential transshipment activities for vessels in the fleet." + ] + }, + { + "cell_type": "markdown", + "id": "0ebc365c-2c5c-413e-80a5-36a4825f3032", + "metadata": {}, + "source": [ + "**Important:** In order to avoid any misinterpretation of **GFW data**, please refer to our official **data caveats** documentations:\n", + "- [Apparent fishing effort](https://globalfishingwatch.org/dataset-and-code-fishing-effort/) \n", + "- [Exclusive economic zone boundaries definition](https://globalfishingwatch.org/our-apis/documentation#exclusive-economic-zone-boundaries-definition)\n", + "- [Vessel ID](https://globalfishingwatch.org/our-apis/documentation#vessel-id)\n", + "- [Vessel API - Vessel identity information](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)" + ] + }, + { + "cell_type": "markdown", + "id": "379460dd-ed9f-49ee-9c9b-e428ad5f4522", + "metadata": {}, + "source": [ + "**Important Caveats:**\n", + "\n", + "1. The [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api) only supports **one active report per user at a time**.\n", + "2. **Sending multiple requests simultaneously** results in a **429 Too Many Requests** error.\n", + "3. If a report takes over **100 seconds** to generate, it may return a **524 Gateway Timeout** error." + ] + }, + { + "cell_type": "markdown", + "id": "2c1e1858-c328-4719-8f10-40ae5b43ecb0", + "metadata": {}, + "source": [ + "## Step 0: Identify the Region of Interest (ROI) - Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "64b1bbab-9780-4821-ae4f-ccff0a4bb100", + "metadata": {}, + "source": [ + "Before making API requests, Kwame must specify the geographic area for analysis using a **Region ID**:" + ] + }, + { + "cell_type": "markdown", + "id": "362137ce-97eb-4965-a649-a038bd5d167f", + "metadata": {}, + "source": [ + "**Options to Define the Region:**\n", + "\n", + "1. **Using Region ID** - Each EEZ has a unique ID in the **[public-eez-areas](https://globalfishingwatch.org/our-apis/documentation#regions)** dataset.\n", + "2. **Custom Geometries** - Users can define a custom area using GeoJSON.\n", + " \n", + "For **[Ghanaian EEZ, the region ID is 8400](https://www.marineregions.org/gazetteer.php?p=details&id=8400)** (public-eez-areas dataset)." + ] + }, + { + "cell_type": "markdown", + "id": "6fe5edf3-8e96-4147-8c59-a6bc8982662d", + "metadata": {}, + "source": [ + "## Step 1: Retrieve Fishing Effort in Ghanaian EEZ" + ] + }, + { + "cell_type": "markdown", + "id": "eba86e0d-90f7-4494-857c-261f9b734dc0", + "metadata": {}, + "source": [ + "Kwame **first queries** the **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** to get **fishing effort for all vessels**, grouping them by **gear type** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort)." + ] + }, + { + "cell_type": "markdown", + "id": "8816740a-4871-49e8-862c-049e0a3d02d3", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - 8400 Ghanaian EEZ\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 12 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Gear Type" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "38c3bc74-e0f6-4f81-b830-3e3393d6b3d0", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"LOW\",\n", + " group_by=\"GEARTYPE\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " start_date=\"2024-01-01\",\n", + " end_date=\"2025-01-01\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8400\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5ee5daa3-6696-4552-8d1a-61df417b8873", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_report_df = step_1_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "35dac242-6479-437a-a35f-249ad22cf191", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 9 entries, 0 to 8\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 9 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 0 non-null object \n", + " 3 gear_type 9 non-null object \n", + " 4 hours 9 non-null float64\n", + " 5 vessel_ids 9 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 9 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: float64(1), int64(1), object(18)\n", + "memory usage: 1.5+ KB\n" + ] + } + ], + "source": [ + "step_1_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6a245cc8-0236-4554-b4c8-d9bbc11db235", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursvessel_ids
0Nonedrifting_longlines593.1383333
1Nonepurse_seines6.3405561
2Nonefishing20929.56333321
3Noneinconclusive30496.17361127
4Nonepole_and_line3481.5091675
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours vessel_ids\n", + "0 None drifting_longlines 593.138333 3\n", + "1 None purse_seines 6.340556 1\n", + "2 None fishing 20929.563333 21\n", + "3 None inconclusive 30496.173611 27\n", + "4 None pole_and_line 3481.509167 5" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_report_df[[\"flag\", \"gear_type\", \"hours\", \"vessel_ids\"]].head()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b56ec0e4-5f85-4a10-bd94-39ea55128920", + "metadata": {}, + "outputs": [], + "source": [ + "step_1_agg_report_df = (\n", + " step_1_report_df.groupby([\"gear_type\"], as_index=False)\n", + " .agg(hours=(\"hours\", \"sum\"), vessel_ids=(\"vessel_ids\", \"sum\"))\n", + " .sort_values(by=\"hours\", ascending=False)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "87289a41-0d54-44c9-a17a-f82b318af293", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
gear_typehoursvessel_ids
7trawlers46704.79722226
3inconclusive30496.17361127
1fishing20929.56333321
8tuna_purse_seines5146.62388923
5pole_and_line3481.5091675
0drifting_longlines593.1383333
4other_purse_seines26.5811111
6purse_seines6.3405561
2fixed_gear0.1636111
\n", + "
" + ], + "text/plain": [ + " gear_type hours vessel_ids\n", + "7 trawlers 46704.797222 26\n", + "3 inconclusive 30496.173611 27\n", + "1 fishing 20929.563333 21\n", + "8 tuna_purse_seines 5146.623889 23\n", + "5 pole_and_line 3481.509167 5\n", + "0 drifting_longlines 593.138333 3\n", + "4 other_purse_seines 26.581111 1\n", + "6 purse_seines 6.340556 1\n", + "2 fixed_gear 0.163611 1" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_1_agg_report_df" + ] + }, + { + "cell_type": "markdown", + "id": "09252564-51c1-4ed1-b938-76688a670cc6", + "metadata": {}, + "source": [ + "### What We have Learned from Step 1" + ] + }, + { + "cell_type": "markdown", + "id": "79fee5f2-f217-40e4-be1d-235190de64b5", + "metadata": {}, + "source": [ + "1. Kwame now has apparent fishing effort data for multiple gear types.\n", + "2. There are **potential 3 vessels** operating as a **longliners (i.e., drifting_longlines)** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)** with `593.138333 hours` logged." + ] + }, + { + "cell_type": "markdown", + "id": "80289282-d160-4901-9bf8-a7996785c898", + "metadata": {}, + "source": [ + "## Step 2: Retrieve Vessel IDs for Longliners" + ] + }, + { + "cell_type": "markdown", + "id": "33209132-cc4a-4711-8e96-0846a71b9c34", + "metadata": {}, + "source": [ + "Kwame refines his **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** request to group by **vessel ID**, and filtering only for **longliners** in **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**." + ] + }, + { + "cell_type": "markdown", + "id": "293c479b-497c-4472-9ce6-c813985b7533", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **[Region ID](https://globalfishingwatch.org/our-apis/documentation#regions)** - [8400 Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)\n", + "2. **[Date Range](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Last 12 Months\n", + "3. **[Grouped By](https://globalfishingwatch.org/our-apis/documentation#report-url-parameters-for-both-post-and-get-requests)** - Vessel ID " + ] + }, + { + "cell_type": "markdown", + "id": "f55f1862-ae0d-4ad5-b281-6a514ae9dcce", + "metadata": {}, + "source": [ + "**Why Use group-by=VESSEL_ID?**\n", + "\n", + "Grouping by **VESSEL_ID** allows **individual vessel identification** in the response. This is crucial for **tracking vessel activity** and, more importantly, linking each detected vessel to the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** in the next step. By structuring the query this way, we can fetch vessel details such as **flag, name, and ownership records** in **Step 3 below**.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "0797f962-6582-4d3b-bfba-3597d5513a73", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_result = await gfw_client.fourwings.create_fishing_effort_report(\n", + " spatial_resolution=\"LOW\",\n", + " group_by=\"VESSEL_ID\",\n", + " temporal_resolution=\"ENTIRE\",\n", + " filters=[\"geartype in ('drifting_longlines')\"],\n", + " start_date=\"2024-01-01\",\n", + " end_date=\"2025-01-01\",\n", + " spatial_aggregation=True,\n", + " region={\n", + " \"dataset\": \"public-eez-areas\",\n", + " \"id\": \"8400\",\n", + " },\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8be53e48-4b93-4140-ae0e-aa910a993da7", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_report_df = step_2_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "061b9fbf-88cf-47d8-9b30-b878c0b867cf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3 entries, 0 to 2\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 3 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 3 non-null object \n", + " 3 gear_type 3 non-null object \n", + " 4 hours 3 non-null float64 \n", + " 5 vessel_ids 0 non-null object \n", + " 6 vessel_id 3 non-null object \n", + " 7 vessel_type 3 non-null object \n", + " 8 entry_timestamp 3 non-null datetime64[ns, UTC]\n", + " 9 exit_timestamp 3 non-null datetime64[ns, UTC]\n", + " 10 first_transmission_date 3 non-null datetime64[ns, UTC]\n", + " 11 last_transmission_date 3 non-null datetime64[ns, UTC]\n", + " 12 imo 3 non-null object \n", + " 13 mmsi 3 non-null object \n", + " 14 call_sign 3 non-null object \n", + " 15 dataset 3 non-null object \n", + " 16 report_dataset 3 non-null object \n", + " 17 ship_name 3 non-null object \n", + " 18 lat 0 non-null object \n", + " 19 lon 0 non-null object \n", + "dtypes: datetime64[ns, UTC](4), float64(1), object(15)\n", + "memory usage: 612.0+ bytes\n" + ] + } + ], + "source": [ + "step_2_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "932bd692-c689-4e1d-985c-18eeccdf9ec3", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
flaggear_typehoursmmsiship_name
0CHNDRIFTING_LONGLINES2.750556412331032
1JPNDRIFTING_LONGLINES588.879722431100690SENSHU MARU NO.3
2TWNDRIFTING_LONGLINES1.508056416007496HUNG CHUAN SHUN
\n", + "
" + ], + "text/plain": [ + " flag gear_type hours mmsi ship_name\n", + "0 CHN DRIFTING_LONGLINES 2.750556 412331032 \n", + "1 JPN DRIFTING_LONGLINES 588.879722 431100690 SENSHU MARU NO.3\n", + "2 TWN DRIFTING_LONGLINES 1.508056 416007496 HUNG CHUAN SHUN" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_report_df[[\"flag\", \"gear_type\", \"hours\", \"mmsi\", \"ship_name\"]].head()" + ] + }, + { + "cell_type": "markdown", + "id": "e54e9165-3f02-46a5-b4ef-74dbfc618766", + "metadata": {}, + "source": [ + "### What We have Learned from Step 2" + ] + }, + { + "cell_type": "markdown", + "id": "72a9efeb-ae54-4bbd-ab85-77845f928376", + "metadata": {}, + "source": [ + "1. Kwame identifies `3 vessels` operating as longliners within **[Ghanaian EEZ](https://www.marineregions.org/gazetteer.php?p=details&id=8400)**.\n", + "2. The vessel `(mmsi: 431100690, ship_name: SENSHU MARU NO.3)` shows significant activity with `588.879722 hours` logged.\n", + "3. Other vessels `(mmsi: 416007496, ship_name: HUNG CHUAN SHUN)` and `(mmsi: 412331032)` shows apparent fishing effort over a short duration.\n", + "4. This response is based on **AIS self-reported** data and should be further validated.\n" + ] + }, + { + "cell_type": "markdown", + "id": "06b8fa5a-b2fd-415c-9bea-d8ef4902cbe6", + "metadata": {}, + "source": [ + "## Step 3: Retrieve Vessel Details Using the Vessels API" + ] + }, + { + "cell_type": "markdown", + "id": "f491fac4-0825-4c6b-aba2-d889d2ec678e", + "metadata": {}, + "source": [ + "Kwame queries the **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** to **get detailed vessel identity and ownership records**. Please [learn more about Vessels API here](https://globalfishingwatch.org/our-apis/documentation#vessels-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information)." + ] + }, + { + "cell_type": "markdown", + "id": "0ed8adac-33da-4168-90a6-5381e9b628f6", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel IDs** from 4Wings API, **Step 2 above**.\n", + "2. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)** - `public-global-vessel-identity:latest`.\n", + "3. **[Includes](https://globalfishingwatch.org/our-apis/documentation#get-vessels-by-ids-url-parameters)** - `POTENTIAL_RELATED_SELF_REPORTED_INFO`." + ] + }, + { + "cell_type": "markdown", + "id": "fa782e3d-3c9d-4236-a0e4-157e22e6aeed", + "metadata": {}, + "source": [ + "**Note:** Vessels may change identifiers over time, such as their `Maritime Mobile Service Identity (MMSI)`,` International Maritime Organization (IMO) number)`, `call sign`, or even their `name`. These changes can occur due to `re-registration`, `changes in ownership`, or other `operational reasons` within the `AIS transponder`. Parameter (`includes = POTENTIAL_RELATED_SELF_REPORTED_INFO`) helps group all **vessel ids** that are **potentially related** as part of the **same physical vessel** based on publicly available registry information." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "15889e5c-dea7-499d-bd77-68a12aca8d98", + "metadata": {}, + "outputs": [], + "source": [ + "step_2_vessel_ids = list(step_2_report_df[\"vessel_id\"].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8477d36f-27ea-4ca9-aaad-dfaf8d94cd80", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['f37ebdc1b-be44-0740-7904-49397360e29d',\n", + " 'b1dad8628-8c9c-2ee7-258b-3d8fb747f1c8',\n", + " '60f7bb972-2c90-4553-650b-23c38f9521bf']" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_2_vessel_ids" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "33d970d9-1321-46ec-87bc-91aed1f446ff", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_result = await gfw_client.vessels.get_vessels_by_ids(\n", + " ids=step_2_vessel_ids,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c1b9a6e9-683f-44fe-bb47-98825cf9d150", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_vessels_df = step_3_vessels_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d87c1cef-92d1-462d-a86e-c2af11912ed9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3 entries, 0 to 2\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 3 non-null object\n", + " 1 registry_info_total_records 3 non-null int64 \n", + " 2 registry_info 3 non-null object\n", + " 3 registry_owners 3 non-null object\n", + " 4 registry_public_authorizations 3 non-null object\n", + " 5 combined_sources_info 3 non-null object\n", + " 6 self_reported_info 3 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 300.0+ bytes\n" + ] + } + ], + "source": [ + "step_3_vessels_df.info()" + ] + }, + { + "cell_type": "markdown", + "id": "9a64a937-59af-414d-8fcc-28948c423117", + "metadata": {}, + "source": [ + "**Understanding Vessel Details Response Data**\n", + "\n", + "- **registryInfoTotalRecords** – This represents the **number of registry records** found for the vessels.\n", + "- **registryInfo** – Contains **public registry data**. This data is sourced from official **vessel registries**.\n", + "- **registryOwners** – Lists the **registered owners** of the vessel based on public sources.\n", + "- **registryPublicAuthorizations** – Represents known **fishing authorizations** from public sources. Users should verify against national registries and RFMO records for additional context.\n", + "- **combinedSourcesInfo** – Provides inferred data from multiple sources, including. This is not explicitly reported by vessels but determined through **GFW's classification methods**.\n", + "- **selfReportedInfo** – Contains **AIS self-reported** data, including `MMSI`, `ship name`, and `flag` as broadcast by the **vessel itself**. Self-reported data may not always align with registry data and should be cross-checked." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "348301a7-c290-4684-bb03-23298e8bc7e0", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
registry_inforegistry_ownersself_reported_info
0[{'id': '0b0dec977c1aad4ae6652c4076572cc7', 's...[{'name': 'TOMIOKA FISHERIES', 'flag': 'JPN', ...[{'id': 'c86d138c5-5d51-3620-fe01-a9e0ed37fb91...
1[][][{'id': 'f37ebdc1b-be44-0740-7904-49397360e29d...
2[{'id': '02eda7d2da02943eecd48813fb7d562a', 's...[{'name': 'HER RONG SHUN FISHERIES', 'flag': '...[{'id': '60f7bb972-2c90-4553-650b-23c38f9521bf...
\n", + "
" + ], + "text/plain": [ + " registry_info \\\n", + "0 [{'id': '0b0dec977c1aad4ae6652c4076572cc7', 's... \n", + "1 [] \n", + "2 [{'id': '02eda7d2da02943eecd48813fb7d562a', 's... \n", + "\n", + " registry_owners \\\n", + "0 [{'name': 'TOMIOKA FISHERIES', 'flag': 'JPN', ... \n", + "1 [] \n", + "2 [{'name': 'HER RONG SHUN FISHERIES', 'flag': '... \n", + "\n", + " self_reported_info \n", + "0 [{'id': 'c86d138c5-5d51-3620-fe01-a9e0ed37fb91... \n", + "1 [{'id': 'f37ebdc1b-be44-0740-7904-49397360e29d... \n", + "2 [{'id': '60f7bb972-2c90-4553-650b-23c38f9521bf... " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_vessels_df[[\"registry_info\", \"registry_owners\", \"self_reported_info\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "44ae4527-da01-4845-be11-b46ddd5575fc", + "metadata": {}, + "source": [ + "### Explore Vessels Registry Info" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "7e5cf6db-8f45-4c7e-a8c8-ccdb312eca7d", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_info\"].explode()\n", + ")\n", + "step_3_registry_info_df = step_3_registry_info_df.dropna()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "b350572a-93ec-434f-8f6f-d0418f693b46", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namegear_typessource_code
0431100690JPNSENSHU MARU NO.3SENSHUMARU3[DRIFTING_LONGLINES][CCSBT, GFCM, IATTC, ICCAT, IMO, IOTC, OPRT, R...
2416007496TWNHUNG CHUAN SHUNHUNGCHUANSHUN[DRIFTING_LONGLINES][ICCAT, IMO, ISSF, OPRT, TMT_ICCAT, TMT_OTHER_...
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name gear_types \\\n", + "0 431100690 JPN SENSHU MARU NO.3 SENSHUMARU3 [DRIFTING_LONGLINES] \n", + "2 416007496 TWN HUNG CHUAN SHUN HUNGCHUANSHUN [DRIFTING_LONGLINES] \n", + "\n", + " source_code \n", + "0 [CCSBT, GFCM, IATTC, ICCAT, IMO, IOTC, OPRT, R... \n", + "2 [ICCAT, IMO, ISSF, OPRT, TMT_ICCAT, TMT_OTHER_... " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"gear_types\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "5e0fb205-ea78-4074-b3bb-266d624d5f86", + "metadata": {}, + "source": [ + "### Explore Registry Owners" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "0ed351c2-104c-4132-bcae-a3c757ac2465", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_registry_owners_df = pd.json_normalize(\n", + " step_3_vessels_df[\"registry_owners\"].explode()\n", + ")\n", + "step_3_registry_owners_df = step_3_registry_owners_df.dropna()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d6bbbc39-1928-42cd-9866-71fa95a601d8", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagnamesource_code
0431100690JPNTOMIOKA FISHERIES[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
1431100690JPNTOMIOKA[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
2431100690JPNYAMAMOTO YUUKI[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
3431100690JPNYAMAMOTO HIROKI[TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF...
5416007496TWNHER RONG SHUN FISHERIES[TMT_ICCAT, TMT_OTHER_OFFICIAL]
\n", + "
" + ], + "text/plain": [ + " ssvid flag name \\\n", + "0 431100690 JPN TOMIOKA FISHERIES \n", + "1 431100690 JPN TOMIOKA \n", + "2 431100690 JPN YAMAMOTO YUUKI \n", + "3 431100690 JPN YAMAMOTO HIROKI \n", + "5 416007496 TWN HER RONG SHUN FISHERIES \n", + "\n", + " source_code \n", + "0 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "1 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "2 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "3 [TMT_CCSBT, TMT_IATTC, TMT_ICCAT, TMT_OTHER_OF... \n", + "5 [TMT_ICCAT, TMT_OTHER_OFFICIAL] " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_registry_owners_df[[\"ssvid\", \"flag\", \"name\", \"source_code\"]]" + ] + }, + { + "cell_type": "markdown", + "id": "e355771a-ec2a-41b2-ab51-801baf15fab1", + "metadata": {}, + "source": [ + "### Explore Vessels Self Reported Info" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "add8a66e-9736-4cdb-a74d-0607fcc530a2", + "metadata": {}, + "outputs": [], + "source": [ + "step_3_self_reported_info_df = pd.json_normalize(\n", + " step_3_vessels_df[\"self_reported_info\"].explode()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "fd0831dc-e29e-4ccc-864f-704eebee2686", + "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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ssvidflagship_namen_ship_namesource_code
0431100690JPNNoneNone[AIS]
1431100690JPNSENSHU MARU NO.3SENSHUMARU3[AIS]
2431100690JPNSENSHU MARU NO3SENSHUMARU3[AIS]
3412331032CHNNoneNone[AIS]
4416007496TWNHUNG CHUAN SHUNHUNGCHUANSHUN[AIS]
\n", + "
" + ], + "text/plain": [ + " ssvid flag ship_name n_ship_name source_code\n", + "0 431100690 JPN None None [AIS]\n", + "1 431100690 JPN SENSHU MARU NO.3 SENSHUMARU3 [AIS]\n", + "2 431100690 JPN SENSHU MARU NO3 SENSHUMARU3 [AIS]\n", + "3 412331032 CHN None None [AIS]\n", + "4 416007496 TWN HUNG CHUAN SHUN HUNGCHUANSHUN [AIS]" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_3_self_reported_info_df[\n", + " [\"ssvid\", \"flag\", \"ship_name\", \"n_ship_name\", \"source_code\"]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "a4e08576-803c-482f-afa5-3fbf4a86837d", + "metadata": {}, + "source": [ + "### What We have Learned from Step 3" + ] + }, + { + "cell_type": "markdown", + "id": "37e54952-ec16-4c85-a6c3-ee7e844d007b", + "metadata": {}, + "source": [ + "- The vessel `mmsi/ssvid: 412331032` appears to be a drifting longliner flagged under China.\n", + "- No public registry data is found for this vessel.\n", + "- The vessel's identity information is based on `AIS self-reported data`, which may not always align with official registries.\n", + "- The vessel appears to have been active since `2014`, based on `self-reported AIS records`.\n", + "- This vessel's data needs further validation against official public sources" + ] + }, + { + "cell_type": "markdown", + "id": "2dc21e2c-a261-44ee-a3b6-2065d4095bcb", + "metadata": {}, + "source": [ + "## Step 4: Detect Fleet Activity (Port Visits)" + ] + }, + { + "cell_type": "markdown", + "id": "ce91f54f-8938-428c-bb22-21c54c8b51f5", + "metadata": {}, + "source": [ + "Now that Kwame has identified vessels in the fleet, he examines their activity further by querying the **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)**. This allows him to detect `port visits`, `encounters (Potential Transshipment)` and `apparent fishing activity` based on vessel movement patterns. Please [learn more about Events API here](https://globalfishingwatch.org/our-apis/documentation#events-api) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated)." + ] + }, + { + "cell_type": "markdown", + "id": "af80cd9c-fe29-4650-9052-dbe7b623eb8d", + "metadata": {}, + "source": [ + "**Filters Used:**\n", + "\n", + "1. **Vessel ID** from 4Wings API\n", + "2. **[Event Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - Port visits, encounters (potential transshipment), and fishing events.\n", + "3. **Time Range** - Last 6 months.\n", + "4. **[Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset)**:\n", + " - `public-global-port-visits-events::latest` (Port Visits)\n", + " - `public-global-encounters-events:latest` (Encounters between vessels)\n", + " - `public-global-fishing-events:latest` (Fishing activity)\n", + "5. **[Encounter Types](https://globalfishingwatch.org/our-apis/documentation#events-post-body-parameters)** - FISHING-FISHING" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "ae1567e5-0594-4eb3-a78a-5e8902deb2ac", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_result = await gfw_client.events.get_all_events(\n", + " datasets=[\n", + " \"public-global-encounters-events:latest\",\n", + " \"public-global-fishing-events:latest\",\n", + " \"public-global-port-visits-events:latest\",\n", + " ],\n", + " vessels=step_2_vessel_ids,\n", + " types=[\"ENCOUNTER\", \"FISHING\", \"PORT_VISIT\"],\n", + " start_date=\"2024-08-01\",\n", + " end_date=\"2025-01-31\",\n", + " encounter_types=[\"FISHING-FISHING\"],\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "904c3745-e999-4fc7-a3fe-dd639c6a87c2", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_events_df = step_4_events_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7f2ef6a8-6eed-47c5-bb44-253bad118956", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 418 entries, 0 to 417\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 418 non-null datetime64[ns, UTC]\n", + " 1 end 418 non-null datetime64[ns, UTC]\n", + " 2 id 418 non-null object \n", + " 3 type 418 non-null object \n", + " 4 position 418 non-null object \n", + " 5 regions 418 non-null object \n", + " 6 bounding_box 418 non-null object \n", + " 7 distances 418 non-null object \n", + " 8 vessel 418 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 414 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 4 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 45.8+ KB\n" + ] + } + ], + "source": [ + "step_4_events_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "39b4f990-1da9-4862-b9fc-554f7b4c7dc0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "type\n", + "fishing 414\n", + "port_visit 4\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_events_df[\"type\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "ccb71753-df83-4ca1-8a43-89fa2cb344d4", + "metadata": {}, + "source": [ + "### Explore Apparent Fishing Events" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "87b32f2a-29ea-4f11-87c2-a16655ac5005", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_events_df = step_4_events_df[step_4_events_df[\"fishing\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "7ee57f28-eff1-40d7-865a-e3ad04103b4c", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_fishing_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_fishing_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_fishing_events_df[\"fishing\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "4a8deceb-aaef-4fe3-8a43-88b4c34d2a70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 414 entries, 0 to 413\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 414 non-null object \n", + " 1 name 389 non-null object \n", + " 2 ssvid 414 non-null object \n", + " 3 flag 414 non-null object \n", + " 4 type 414 non-null object \n", + " 5 public_authorizations 414 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 total_distance_km 414 non-null float64\n", + " 8 average_speed_knots 414 non-null float64\n", + " 9 average_duration_hours 0 non-null object \n", + " 10 potential_risk 414 non-null bool \n", + " 11 vessel_public_authorization_status 414 non-null object \n", + "dtypes: bool(1), float64(2), object(9)\n", + "memory usage: 36.1+ KB\n" + ] + } + ], + "source": [ + "step_4_fishing_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "0b95e76a-7fe8-45ba-87a3-ffab7d15c7d1", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namessvidtotal_distance_kmaverage_speed_knots
0HUNG CHUAN SHUN41600749618.4810568.841667
1HUNG CHUAN SHUN41600749634.8675598.240000
2HUNG CHUAN SHUN41600749611.0868508.208333
3HUNG CHUAN SHUN41600749612.6996508.266667
4HUNG CHUAN SHUN41600749656.7880346.248000
...............
409SENSHU MARU NO.343110069012.1644945.083333
410SENSHU MARU NO.343110069013.1911243.986957
411SENSHU MARU NO.34311006908.6856593.850000
412SENSHU MARU NO.343110069015.7219873.686667
413SENSHU MARU NO.343110069028.5537793.728571
\n", + "

414 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " name ssvid total_distance_km average_speed_knots\n", + "0 HUNG CHUAN SHUN 416007496 18.481056 8.841667\n", + "1 HUNG CHUAN SHUN 416007496 34.867559 8.240000\n", + "2 HUNG CHUAN SHUN 416007496 11.086850 8.208333\n", + "3 HUNG CHUAN SHUN 416007496 12.699650 8.266667\n", + "4 HUNG CHUAN SHUN 416007496 56.788034 6.248000\n", + ".. ... ... ... ...\n", + "409 SENSHU MARU NO.3 431100690 12.164494 5.083333\n", + "410 SENSHU MARU NO.3 431100690 13.191124 3.986957\n", + "411 SENSHU MARU NO.3 431100690 8.685659 3.850000\n", + "412 SENSHU MARU NO.3 431100690 15.721987 3.686667\n", + "413 SENSHU MARU NO.3 431100690 28.553779 3.728571\n", + "\n", + "[414 rows x 4 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"total_distance_km\",\n", + " \"average_speed_knots\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "2416d761-b334-4995-ba67-81ff96c3dd57", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ssvid\n", + "416007496 363\n", + "431100690 26\n", + "412331032 25\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_fishing_df[\"ssvid\"].value_counts()" + ] + }, + { + "cell_type": "markdown", + "id": "dfdc826c-d854-4f1c-bf0b-82560d23a2f4", + "metadata": {}, + "source": [ + "### Explore Port Visit Events" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "337ddf63-42ba-4ea7-a56d-2d8d602f5a22", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visit_events_df = step_4_events_df[step_4_events_df[\"port_visit\"].notna()]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "a77465d1-02ce-42bb-a0b3-7c243cf02a40", + "metadata": {}, + "outputs": [], + "source": [ + "step_4_port_visits_df = pd.concat(\n", + " [\n", + " pd.json_normalize(step_4_port_visit_events_df[\"vessel\"], sep=\"_\"),\n", + " pd.json_normalize(step_4_port_visit_events_df[\"port_visit\"], sep=\"_\"),\n", + " ],\n", + " axis=1,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "566e8a67-8fff-4d10-9749-83c6dae727b7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 4 entries, 0 to 3\n", + "Data columns (total 37 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 4 non-null object \n", + " 1 name 3 non-null object \n", + " 2 ssvid 4 non-null object \n", + " 3 flag 4 non-null object \n", + " 4 type 4 non-null object \n", + " 5 public_authorizations 4 non-null object \n", + " 6 nextPort 0 non-null object \n", + " 7 visit_id 4 non-null object \n", + " 8 confidence 4 non-null object \n", + " 9 duration_hrs 4 non-null float64\n", + " 10 start_anchorage_anchorage_id 4 non-null object \n", + " 11 start_anchorage_at_dock 4 non-null bool \n", + " 12 start_anchorage_distance_from_shore_km 4 non-null float64\n", + " 13 start_anchorage_flag 4 non-null object \n", + " 14 start_anchorage_id 4 non-null object \n", + " 15 start_anchorage_lat 4 non-null float64\n", + " 16 start_anchorage_lon 4 non-null float64\n", + " 17 start_anchorage_name 4 non-null object \n", + " 18 start_anchorage_top_destination 4 non-null object \n", + " 19 intermediate_anchorage_anchorage_id 4 non-null object \n", + " 20 intermediate_anchorage_at_dock 4 non-null bool \n", + " 21 intermediate_anchorage_distance_from_shore_km 4 non-null float64\n", + " 22 intermediate_anchorage_flag 4 non-null object \n", + " 23 intermediate_anchorage_id 4 non-null object \n", + " 24 intermediate_anchorage_lat 4 non-null float64\n", + " 25 intermediate_anchorage_lon 4 non-null float64\n", + " 26 intermediate_anchorage_name 4 non-null object \n", + " 27 intermediate_anchorage_top_destination 4 non-null object \n", + " 28 end_anchorage_anchorage_id 4 non-null object \n", + " 29 end_anchorage_at_dock 4 non-null bool \n", + " 30 end_anchorage_distance_from_shore_km 4 non-null float64\n", + " 31 end_anchorage_flag 4 non-null object \n", + " 32 end_anchorage_id 4 non-null object \n", + " 33 end_anchorage_lat 4 non-null float64\n", + " 34 end_anchorage_lon 4 non-null float64\n", + " 35 end_anchorage_name 4 non-null object \n", + " 36 end_anchorage_top_destination 4 non-null object \n", + "dtypes: bool(3), float64(10), object(24)\n", + "memory usage: 1.2+ KB\n" + ] + } + ], + "source": [ + "step_4_port_visits_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "0381a7bd-cf81-4b58-9f8d-f01601121ad2", + "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", + " \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", + " \n", + " \n", + "
namessvidconfidencestart_anchorage_nameintermediate_anchorage_nameend_anchorage_name
0HUNG CHUAN SHUN4160074964TEMATEMATEMA
1SENSHU MARU NO.34311006904TEMATEMATEMA
2None4123310324DAKARDAKARDAKAR
3SENSHU MARU NO.34311006904TEMATEMATEMA
\n", + "
" + ], + "text/plain": [ + " name ssvid confidence start_anchorage_name \\\n", + "0 HUNG CHUAN SHUN 416007496 4 TEMA \n", + "1 SENSHU MARU NO.3 431100690 4 TEMA \n", + "2 None 412331032 4 DAKAR \n", + "3 SENSHU MARU NO.3 431100690 4 TEMA \n", + "\n", + " intermediate_anchorage_name end_anchorage_name \n", + "0 TEMA TEMA \n", + "1 TEMA TEMA \n", + "2 DAKAR DAKAR \n", + "3 TEMA TEMA " + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "step_4_port_visits_df[\n", + " [\n", + " \"name\",\n", + " \"ssvid\",\n", + " \"confidence\",\n", + " \"start_anchorage_name\",\n", + " \"intermediate_anchorage_name\",\n", + " \"end_anchorage_name\",\n", + " ]\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "2d340b6b-3d88-4c48-a699-305a75e706a4", + "metadata": {}, + "source": [ + "### What We’ve Learned from Step 4" + ] + }, + { + "cell_type": "markdown", + "id": "709d2a5c-5246-4995-ab68-0997adf62349", + "metadata": {}, + "source": [ + "- `4: port visits`, `0: encounters`, and `414: fishing` events were found for the queried vessels in the given date range.\n", + "- Some events were missed due to **AIS data coverage gaps**.\n", + "- Different filters may need to be applied to refine results." + ] + }, + { + "cell_type": "markdown", + "id": "be4b21a0-f3ea-4f10-a61f-cf121cbe078e", + "metadata": {}, + "source": [ + "**Caveats & Considerations**" + ] + }, + { + "cell_type": "markdown", + "id": "c7625234-6210-4701-91b2-cca2cfe43494", + "metadata": {}, + "source": [ + "- **A lack of recorded encounters or any other events does not confirm the absence of such activities**—AIS coverage, reporting behavior, and dataset updates can impact results.\n", + "- **Further investigation may be required**, including manual validation using historical data or consulting additional sources." + ] + }, + { + "cell_type": "markdown", + "id": "8b951044-6905-4e38-9885-13a98cf3a7cf", + "metadata": {}, + "source": [ + "## Summary of API Flow" + ] + }, + { + "cell_type": "markdown", + "id": "c8f86731-be44-4b89-8abb-cf2f6693b4c9", + "metadata": {}, + "source": [ + "1. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Identify fishing effort by **gear type** in Ghanaian EEZ.\n", + "2. **[4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api)** - Retrieve vessel IDs for potential **longliners**.\n", + "3. **[Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)** - Fetch detailed **vessel identity** & **ownership**.\n", + "4. **[Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)** - Attempt to detect fleet activity (**port visits**, **encounters**, and **apparent fishing** events)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 84b4847ec4de452a8b605110f947ad05b91eff89 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Sat, 10 Jan 2026 23:35:28 +0300 Subject: [PATCH 17/22] docs(notebooks): format, lint and correct notebooks and guides This: - add missing `vessel_ids` in `docs/source/getting-started.md` - add jupyter notebooks to black dependency i.e `black[jupyter]` - add make tasks for formatting and linting notebooks --- Makefile | 13 + docs/source/getting-started.md | 7 +- docs/source/usage-guides/4wings-api.md | 58 +-- docs/source/usage-guides/datasets-api.md | 36 +- docs/source/usage-guides/events-api.md | 36 +- .../usage-guides/references-data-api.md | 52 +-- docs/source/usage-guides/vessels-api.md | 7 +- ...parent-fishing-effort-senegalese-eez.ipynb | 169 +++---- ...arent-fishing-effort-argentinian-eez.ipynb | 293 +++++++------ ...low-03-analyze-fleet-in-ghanaian-eez.ipynb | 155 ++++--- notebooks/getting-started.ipynb | 258 +++++------ notebooks/usage-guides/4wings-api.ipynb | 415 +++++++++++++----- notebooks/usage-guides/datasets-api.ipynb | 265 +++++++---- notebooks/usage-guides/events-api.ipynb | 170 +++++-- notebooks/usage-guides/insights-api.ipynb | 43 +- .../usage-guides/references-data-api.ipynb | 156 +++++-- notebooks/usage-guides/vessels-api.ipynb | 190 ++++++-- ...parent-fishing-effort-senegalese-eez.ipynb | 169 +++---- ...arent-fishing-effort-argentinian-eez.ipynb | 293 +++++++------ ...low-03-analyze-fleet-in-ghanaian-eez.ipynb | 155 ++++--- pyproject.toml | 2 +- 21 files changed, 1814 insertions(+), 1128 deletions(-) diff --git a/Makefile b/Makefile index 4b65f42..4261cd7 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ .DEFAULT_GOAL := help sources = src tests +notebooks-sources = notebooks .PHONY: install ## Install the package, dependencies, and pre-commit for local development install: @@ -14,12 +15,24 @@ format: python -m ruff check --fix $(sources) python -m ruff format $(sources) +.PHONY: format-notebooks ## Auto-format Jupyter Notebooks +format-notebooks: + python -m black $(notebooks-sources) + python -m ruff check --fix $(notebooks-sources) + python -m ruff format $(notebooks-sources) + .PHONY: lint ## Lint python source files lint: python -m ruff check $(sources) python -m ruff format --check $(sources) python -m black $(sources) --check --diff +.PHONY: lint-notebooks ## Lint Jupyter Notebooks +lint-notebooks: + python -m ruff check $(notebooks-sources) + python -m ruff format --check $(notebooks-sources) + python -m black $(notebooks-sources) --check --diff + .PHONY: codespell ## Use Codespell to do spellchecking codespell: python -m codespell_lib diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index cbb841d..f393894 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -47,8 +47,8 @@ For more detailed installation instructions, including setting up a virtual envi Once installed, you can import and use `gfw-api-python-client` in your Python codes: ```python -import os import datetime +import os import gfwapiclient as gfw @@ -103,6 +103,10 @@ vessel_self_reported_infos = [ for self_reported_info in vessel_item.self_reported_info ] +vessel_ids = [ + self_reported_info.id for self_reported_info in vessel_self_reported_infos +] + print(vessel_ids) ``` @@ -124,6 +128,7 @@ start_datetime = min( ] ) start_date = start_datetime.date() +start_date = max(start_date, datetime.date.fromisoformat("2020-01-01")) end_datetime = max( diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index e3b58cc..ec6a85f 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -293,7 +293,11 @@ report_result = await gfw_client.fourwings.create_report( spatial_resolution="LOW", temporal_resolution="MONTHLY", group_by="FLAG", - datasets=["public-global-fishing-effort:latest"], + datasets=[ + "public-global-fishing-effort:latest", + "public-global-sar-presence:latest", + "public-global-presence:latest", + ], start_date="2022-01-01", end_date="2022-05-01", region={ @@ -324,7 +328,7 @@ print(report_item.model_dump()) **Output:** ``` -('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0) +('2022-03', 'RUS', 1.0, 1, 52.1, 153.2) ``` ### Access the report data as a DataFrame @@ -340,32 +344,32 @@ print(report_df[["date", "flag", "hours", "lat", "lon"]].head()) ``` -RangeIndex: 32271 entries, 0 to 32270 +RangeIndex: 310599 entries, 0 to 310598 Data columns (total 20 columns): - # Column Non-Null Count Dtype ---- ------ -------------- ----- - 0 date 32271 non-null object - 1 detections 0 non-null object - 2 flag 32271 non-null object - 3 gear_type 0 non-null object - 4 hours 32271 non-null float64 - 5 vessel_ids 32271 non-null int64 - 6 vessel_id 0 non-null object - 7 vessel_type 0 non-null object - 8 entry_timestamp 0 non-null object - 9 exit_timestamp 0 non-null object - 10 first_transmission_date 0 non-null object - 11 last_transmission_date 0 non-null object - 12 imo 0 non-null object - 13 mmsi 0 non-null object - 14 call_sign 0 non-null object - 15 dataset 0 non-null object - 16 report_dataset 32271 non-null object - 17 ship_name 0 non-null object - 18 lat 32271 non-null float64 - 19 lon 32271 non-null float64 -dtypes: float64(3), int64(1), object(16) -memory usage: 4.9+ MB + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 date 310599 non-null object + 1 detections 3995 non-null float64 + 2 flag 310599 non-null object + 3 gear_type 0 non-null object + 4 hours 306604 non-null float64 + 5 vessel_ids 310599 non-null int64 + 6 vessel_id 0 non-null object + 7 vessel_type 0 non-null object + 8 entry_timestamp 0 non-null object + 9 exit_timestamp 0 non-null object + 10 first_transmission_date 0 non-null object + 11 last_transmission_date 0 non-null object + 12 imo 0 non-null object + 13 mmsi 0 non-null object + 14 call_sign 0 non-null object + 15 dataset 0 non-null object + 16 report_dataset 310599 non-null object + 17 ship_name 0 non-null object + 18 lat 310599 non-null float64 + 19 lon 310599 non-null float64 +dtypes: float64(4), int64(1), object(15) +memory usage: 47.4+ MB ``` ## Reference Data diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 3e9c587..617626a 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-api.md @@ -80,19 +80,19 @@ print(sar_infrastructure_df.head()) ``` -RangeIndex: 1106 entries, 0 to 1105 +RangeIndex: 1156 entries, 0 to 1155 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 structure_id 1106 non-null int64 - 1 lat 1106 non-null float64 - 2 lon 1106 non-null float64 - 3 label 1106 non-null object - 4 structure_start_date 1106 non-null datetime64[ns, UTC] - 5 structure_end_date 831 non-null datetime64[ns, UTC] - 6 label_confidence 1106 non-null object + 0 structure_id 1156 non-null int64 + 1 lat 1156 non-null float64 + 2 lon 1156 non-null float64 + 3 label 1156 non-null object + 4 structure_start_date 1156 non-null datetime64[ns, UTC] + 5 structure_end_date 857 non-null datetime64[ns, UTC] + 6 label_confidence 1156 non-null object dtypes: datetime64[ns, UTC](2), float64(2), int64(1), object(2) -memory usage: 60.6+ KB +memory usage: 63.3+ KB ``` ## Retrieving SAR Fixed Infrastructure Data by Geometry (`get_sar_fixed_infrastructure` with geometry) @@ -152,19 +152,19 @@ print(sar_infrastructure_df.head()) ``` -RangeIndex: 1106 entries, 0 to 1105 +RangeIndex: 1156 entries, 0 to 1155 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 structure_id 1106 non-null int64 - 1 lat 1106 non-null float64 - 2 lon 1106 non-null float64 - 3 label 1106 non-null object - 4 structure_start_date 1106 non-null datetime64[ns, UTC] - 5 structure_end_date 831 non-null datetime64[ns, UTC] - 6 label_confidence 1106 non-null object + 0 structure_id 1156 non-null int64 + 1 lat 1156 non-null float64 + 2 lon 1156 non-null float64 + 3 label 1156 non-null object + 4 structure_start_date 1156 non-null datetime64[ns, UTC] + 5 structure_end_date 857 non-null datetime64[ns, UTC] + 6 label_confidence 1156 non-null object dtypes: datetime64[ns, UTC](2), float64(2), int64(1), object(2) -memory usage: 60.6+ KB +memory usage: 63.3+ KB ``` ## Next Steps diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index f3afd85..11e4219 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-api.md @@ -45,7 +45,7 @@ events_result = await gfw_client.events.get_all_events( "dataset": "public-eez-areas", "id": "8371", }, - limit=1, + limit=5, ) ``` @@ -61,7 +61,7 @@ print(event.model_dump()) **Output:** ``` -('a0f5848d1a83b7f0b4b8cda6873699ba', 'fishing', '9e01144bf-f383-e634-3178-ca7e34477f34') +('bbbf5d0cfa9639e5eac0130fc2b742e9', 'fishing', '7374d1988-87f8-6037-66b4-59854a026efb') ``` ### Access the events as a DataFrame @@ -76,26 +76,26 @@ print(events_df[["id", "type"]].head()) ``` -RangeIndex: 1 entries, 0 to 0 +RangeIndex: 5 entries, 0 to 4 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 start 1 non-null datetime64[ns, UTC] - 1 end 1 non-null datetime64[ns, UTC] - 2 id 1 non-null object - 3 type 1 non-null object - 4 position 1 non-null object - 5 regions 1 non-null object - 6 bounding_box 1 non-null object - 7 distances 1 non-null object - 8 vessel 1 non-null object + 0 start 5 non-null datetime64[ns, UTC] + 1 end 5 non-null datetime64[ns, UTC] + 2 id 5 non-null object + 3 type 5 non-null object + 4 position 5 non-null object + 5 regions 5 non-null object + 6 bounding_box 5 non-null object + 7 distances 5 non-null object + 8 vessel 5 non-null object 9 encounter 0 non-null object - 10 fishing 1 non-null object + 10 fishing 5 non-null object 11 gap 0 non-null object 12 loitering 0 non-null object 13 port_visit 0 non-null object dtypes: datetime64[ns, UTC](2), object(12) -memory usage: 244.0+ bytes +memory usage: 692.0+ bytes ``` ## Retrieving a Single Event by ID (`get_event_by_id`) @@ -120,7 +120,7 @@ print(event.model_dump()) **Output:** ``` -('a0f5848d1a83b7f0b4b8cda6873699ba', 'fishing', '9e01144bf-f383-e634-3178-ca7e34477f34') +('c2f0967e061f99a01793edac065de003', 'port_visit', '8c7304226-6c71-edbe-0b63-c246734b3c01') ``` ### Access the event as a DataFrame @@ -149,10 +149,10 @@ Data columns (total 14 columns): 7 distances 1 non-null object 8 vessel 1 non-null object 9 encounter 0 non-null object - 10 fishing 1 non-null object + 10 fishing 0 non-null object 11 gap 0 non-null object 12 loitering 0 non-null object - 13 port_visit 0 non-null object + 13 port_visit 1 non-null object dtypes: datetime64[ns, UTC](2), object(12) memory usage: 244.0+ bytes ``` @@ -185,7 +185,7 @@ print(event_stat.model_dump()) **Output:** ``` -(24786, 1, 194) +(24770, 1, 196) ``` ### Access the statistics as a DataFrame diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index b54c014..6b4b8d4 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-api.md @@ -52,8 +52,8 @@ print(eez_region.model_dump()) **Output:** ``` -(26523, 'public-eez-areas') -{'id': 26523, 'label': 'Turkmenistan', 'iso3': 'TKM', 'dataset': 'public-eez-areas'} +(48999, 'public-eez-areas') +{'id': 48999, 'label': 'Overlapping claim Peñón de Vélez de la Gomera: Spain / Morocco', 'iso3': None, 'dataset': 'public-eez-areas'} ``` ### Access the EEZ regions as a DataFrame @@ -67,17 +67,17 @@ print(eez_regions_df[["id", "dataset"]].head()) **Output:** ``` -class 'pandas.core.frame.DataFrame'> -RangeIndex: 282 entries, 0 to 281 + +RangeIndex: 285 entries, 0 to 284 Data columns (total 4 columns): - # Column Non-Null Count Dtype ---- ------ -------------- ----- - 0 id 281 non-null float64 - 1 label 282 non-null object - 2 iso3 282 non-null object - 3 dataset 282 non-null object -dtypes: float64(1), object(3) -memory usage: 8.9+ KB + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 id 285 non-null int64 + 1 label 285 non-null object + 2 iso3 234 non-null object + 3 dataset 285 non-null object +dtypes: int64(1), object(3) +memory usage: 17.9+ KB ``` ## Retrieving Marine Protected Areas (MPAs) @@ -100,8 +100,8 @@ print(mpa_region.model_dump()) **Output:** ``` -('555790281', 'public-mpa-all') -{'id': '555790281', 'label': 'Iles Barren - Aire protegee', 'name': 'Iles Barren', 'dataset': 'public-mpa-all'} +('555799979', 'public-mpa-all') +{'id': '555799979', 'label': 'NAF Marine Protected Area - Marine Protected Area', 'name': None, 'dataset': 'public-mpa-all'} ``` ### Access the MPA regions as a DataFrame @@ -116,16 +116,16 @@ print(mpa_regions_df[["id", "dataset"]].head()) ``` -RangeIndex: 16621 entries, 0 to 16620 +RangeIndex: 16591 entries, 0 to 16590 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- - 0 id 16621 non-null object - 1 label 16621 non-null object - 2 name 16621 non-null object - 3 dataset 16621 non-null object + 0 id 16591 non-null object + 1 label 16591 non-null object + 2 name 0 non-null object + 3 dataset 16591 non-null object dtypes: object(4) -memory usage: 519.5+ K +memory usage: 518.6+ KB ``` ## Retrieving Regional Fisheries Management Organizations (RFMOs) @@ -148,8 +148,9 @@ print(rfmo_region.model_dump()) **Output:** ``` -('WCPFC', 'public-rfmo') +('BOBP-IGO', 'public-rfmo') {'id': 'WCPFC', 'label': 'WCPFC', 'rfb': None, 'dataset': 'public-rfmo'} +{'id': 'BOBP-IGO', 'label': 'BOBP-IGO', 'rfb': None, 'dataset': 'public-rfmo', 'ID': 'BOBP-IGO'} ``` ### Access the RFMO regions as a DataFrame @@ -165,15 +166,16 @@ print(rfmo_regions_df[["id", "dataset"]].head()) ``` RangeIndex: 42 entries, 0 to 41 -Data columns (total 4 columns): +Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 42 non-null object 1 label 42 non-null object - 2 rfb 35 non-null object + 2 rfb 0 non-null object 3 dataset 42 non-null object -dtypes: object(4) -memory usage: 1.4+ KB + 4 ID 42 non-null object +dtypes: object(5) +memory usage: 1.8+ KB ``` ## Next Steps diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index 4120d06..3e501d6 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-api.md @@ -39,7 +39,6 @@ The `search_vessels()` method allows you to find vessels based on a query and va ```python vessel_search_result = await gfw_client.vessels.search_vessels( where="ssvid='775998121' AND shipname='DON TITO'", - datasets=["public-global-vessel-identity:latest"], includes=["MATCH_CRITERIA", "OWNERSHIP"], ) ``` @@ -56,7 +55,7 @@ print(vessel.model_dump()) **Output:** ``` -('public-global-vessel-identity:v3.0', 'bae8f325c-cf0a-01fe-6d1a-9a275588d4ff') +('public-global-vessel-identity:v3.0', 'c54923e64-46f3-9338-9dcb-ff09724077a3') ``` ### Access the vessels as a DataFrame @@ -98,7 +97,6 @@ vessels_result = await gfw_client.vessels.get_vessels_by_ids( "6583c51e3-3626-5638-866a-f47c3bc7ef7c", "71e7da672-2451-17da-b239-857831602eca", ], - datasets=["public-global-vessel-identity:latest"], ) ``` @@ -114,7 +112,7 @@ print(vessel.model_dump()) **Output:** ``` -('public-global-vessel-identity:v3.0', '0cb77880e-ee49-2ce4-a849-c0b413b6ec89') +('public-global-vessel-identity:v3.0', 'aca119c29-95dd-f5c4-2057-ee45268dcd6f') ``` ### Access the vessels as a DataFrame @@ -151,7 +149,6 @@ The `get_vessel_by_id()` method retrieves detailed information for a specific ve ```python vessel_result = await gfw_client.vessels.get_vessel_by_id( id="c54923e64-46f3-9338-9dcb-ff09724077a3", - dataset="public-global-vessel-identity:latest", ) ``` diff --git a/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb b/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb index c37fb6a..765071b 100644 --- a/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb +++ b/docs/source/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "2532e150-f450-4ae6-b7a1-3433b5f25dac", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -383,41 +392,41 @@ " 0\n", " CHN\n", " TRAWLERS\n", - " 31.888889\n", - " 412444322\n", - " MIN LONG YU61146\n", + " 0.368056\n", + " 412209175\n", + " MENGXIN24\n", " \n", " \n", " 1\n", - " SEN\n", + " ESP\n", " TRAWLERS\n", - " 524.815556\n", - " 663093000\n", - " AMINE\n", + " 1.306389\n", + " 225987981\n", + " CIUDAD DE HUELVA\n", " \n", " \n", " 2\n", " CHN\n", " TRAWLERS\n", - " 0.368056\n", - " 412209175\n", - " MENGXIN24\n", + " 216.545000\n", + " 412549331\n", + " YUAN YU 886\n", " \n", " \n", " 3\n", - " ESP\n", + " SEN\n", " TRAWLERS\n", - " 1.306389\n", - " 225987981\n", - " CIUDAD DE HUELVA\n", + " 612.825556\n", + " 663123000\n", + " ILE AUX OISEAUX\n", " \n", " \n", " 4\n", " CHN\n", " TRAWLERS\n", - " 216.545000\n", - " 412549331\n", - " YUAN YU 886\n", + " 31.888889\n", + " 412444322\n", + " MIN LONG YU61146\n", " \n", " \n", "\n", @@ -425,11 +434,11 @@ ], "text/plain": [ " flag gear_type hours mmsi ship_name\n", - "0 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146\n", - "1 SEN TRAWLERS 524.815556 663093000 AMINE\n", - "2 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", - "3 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", - "4 CHN TRAWLERS 216.545000 412549331 YUAN YU 886" + "0 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", + "1 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", + "2 CHN TRAWLERS 216.545000 412549331 YUAN YU 886\n", + "3 SEN TRAWLERS 612.825556 663123000 ILE AUX OISEAUX\n", + "4 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146" ] }, "execution_count": 8, @@ -785,32 +794,32 @@ " \n", " \n", " 0\n", - " [{'id': '199483471cd2da3717552fddb1a3172a', 's...\n", - " [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...\n", - " [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...\n", - " \n", - " \n", - " 1\n", " [{'id': '29fef17154387858d8d4c777311c57f7', 's...\n", " [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ...\n", " [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e...\n", " \n", + " \n", + " 1\n", + " [{'id': '199483471cd2da3717552fddb1a3172a', 's...\n", + " [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...\n", + " [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...\n", + " \n", " \n", "\n", "" ], "text/plain": [ " registry_info \\\n", - "0 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", - "1 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "0 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "1 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", "\n", " registry_owners \\\n", - "0 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", - "1 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "0 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "1 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", "\n", " self_reported_info \n", - "0 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... \n", - "1 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... " + "0 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... \n", + "1 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... " ] }, "execution_count": 18, @@ -880,16 +889,16 @@ " \n", " \n", " 0\n", - " 663115000\n", + " 663178000\n", " SEN\n", - " BETTY\n", - " BETTY\n", + " NUEVO NOSO LAR\n", + " NUEVONOSOLAR\n", " [TRAWLERS]\n", " [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 1\n", - " 663178000\n", + " 762178000\n", " SEN\n", " NUEVO NOSO LAR\n", " NUEVONOSOLAR\n", @@ -898,7 +907,7 @@ " \n", " \n", " 2\n", - " 762178000\n", + " 552178000\n", " SEN\n", " NUEVO NOSO LAR\n", " NUEVONOSOLAR\n", @@ -907,10 +916,10 @@ " \n", " \n", " 3\n", - " 552178000\n", + " 663115000\n", " SEN\n", - " NUEVO NOSO LAR\n", - " NUEVONOSOLAR\n", + " BETTY\n", + " BETTY\n", " [TRAWLERS]\n", " [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", @@ -920,10 +929,10 @@ ], "text/plain": [ " ssvid flag ship_name n_ship_name gear_types \\\n", - "0 663115000 SEN BETTY BETTY [TRAWLERS] \n", - "1 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", - "2 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", - "3 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "0 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "1 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "2 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "3 663115000 SEN BETTY BETTY [TRAWLERS] \n", "\n", " source_code \n", "0 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", @@ -999,37 +1008,37 @@ " \n", " \n", " 0\n", - " 663115000\n", - " SEN\n", - " ARMEMENT SOPASEN\n", + " 663178000\n", + " ESP\n", + " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 1\n", - " 663178000\n", + " 663176000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 2\n", - " 663176000\n", + " 762178000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 3\n", - " 762178000\n", + " 552178000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 4\n", - " 552178000\n", - " ESP\n", - " SENEVISA\n", + " 663115000\n", + " SEN\n", + " ARMEMENT SOPASEN\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", @@ -1038,11 +1047,11 @@ ], "text/plain": [ " ssvid flag name source_code\n", - "0 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "1 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "2 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "3 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "4 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" + "0 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "1 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "2 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "3 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "4 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" ] }, "execution_count": 22, @@ -1111,14 +1120,6 @@ " \n", " \n", " 0\n", - " 663115000\n", - " SEN\n", - " BETTY\n", - " BETTY\n", - " [AIS]\n", - " \n", - " \n", - " 1\n", " 663178000\n", " SEN\n", " NUEVONOSOLAR\n", @@ -1126,7 +1127,7 @@ " [AIS]\n", " \n", " \n", - " 2\n", + " 1\n", " 663178000\n", " SEN\n", " NUEVO=NOSOLAR+3&!U.?\n", @@ -1134,7 +1135,7 @@ " [AIS]\n", " \n", " \n", - " 3\n", + " 2\n", " 762178000\n", " None\n", " NUEVO NOSOLAR\n", @@ -1142,7 +1143,7 @@ " [AIS]\n", " \n", " \n", - " 4\n", + " 3\n", " 552178000\n", " None\n", " NUEVO NOSOLAR\n", @@ -1150,25 +1151,33 @@ " [AIS]\n", " \n", " \n", - " 5\n", + " 4\n", " 663178000\n", " SEN\n", " NUEVO NOSOLAR\n", " NUEVONOSOLAR\n", " [AIS]\n", " \n", + " \n", + " 5\n", + " 663115000\n", + " SEN\n", + " BETTY\n", + " BETTY\n", + " [AIS]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name source_code\n", - "0 663115000 SEN BETTY BETTY [AIS]\n", - "1 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", - "2 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", - "3 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", - "4 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", - "5 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]" + "0 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", + "1 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", + "2 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "3 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "4 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "5 663115000 SEN BETTY BETTY [AIS]" ] }, "execution_count": 24, diff --git a/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb b/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb index 0953cfe..a146cfc 100644 --- a/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb +++ b/docs/source/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "420afe1c-ff77-40e2-9a07-7372dc95170c", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -368,15 +377,15 @@ " \n", " \n", " 0\n", - " inconclusive\n", - " 215.623889\n", - " 2\n", + " pots_and_traps\n", + " 92.029722\n", + " 3\n", " \n", " \n", " 1\n", - " set_longlines\n", - " 17.925833\n", - " 1\n", + " inconclusive\n", + " 215.623889\n", + " 2\n", " \n", " \n", " 2\n", @@ -386,15 +395,15 @@ " \n", " \n", " 3\n", - " other_purse_seines\n", - " 57.377500\n", + " set_longlines\n", + " 17.925833\n", " 1\n", " \n", " \n", " 4\n", - " set_longlines\n", - " 153.960278\n", - " 3\n", + " other_purse_seines\n", + " 57.377500\n", + " 1\n", " \n", " \n", "\n", @@ -402,11 +411,11 @@ ], "text/plain": [ " gear_type hours vessel_ids\n", - "0 inconclusive 215.623889 2\n", - "1 set_longlines 17.925833 1\n", + "0 pots_and_traps 92.029722 3\n", + "1 inconclusive 215.623889 2\n", "2 inconclusive 98.155833 2\n", - "3 other_purse_seines 57.377500 1\n", - "4 set_longlines 153.960278 3" + "3 set_longlines 17.925833 1\n", + "4 other_purse_seines 57.377500 1" ] }, "execution_count": 8, @@ -686,35 +695,35 @@ " \n", " \n", " 0\n", - " URY\n", + " ARG\n", " TRAWLERS\n", - " 10.023056\n", - " 770576463\n", - " KALATXORI\n", + " 714.842500\n", + " 701000882\n", + " FELIX AUGUSTO\n", " \n", " \n", " 1\n", " ARG\n", " TRAWLERS\n", - " 326.160833\n", - " 701079000\n", - " ENTRENA UNO\n", + " 641.522222\n", + " 701000932\n", + " ANTONIO ALVAREZ\n", " \n", " \n", " 2\n", - " ARG\n", + " URY\n", " TRAWLERS\n", - " 714.842500\n", - " 701000882\n", - " FELIX AUGUSTO\n", + " 10.023056\n", + " 770576463\n", + " KALATXORI\n", " \n", " \n", " 3\n", " ARG\n", " TRAWLERS\n", - " 641.522222\n", - " 701000932\n", - " ANTONIO ALVAREZ\n", + " 326.160833\n", + " 701079000\n", + " ENTRENA UNO\n", " \n", " \n", " 4\n", @@ -730,10 +739,10 @@ ], "text/plain": [ " flag gear_type hours mmsi ship_name\n", - "0 URY TRAWLERS 10.023056 770576463 KALATXORI\n", - "1 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", - "2 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", - "3 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "0 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", + "1 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "2 URY TRAWLERS 10.023056 770576463 KALATXORI\n", + "3 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", "4 ARG TRAWLERS 295.007500 701000820 CORAJE" ] }, @@ -1090,32 +1099,32 @@ " \n", " \n", " 0\n", - " [{'id': '45502524c9a150e77869ee647423dba1', 's...\n", - " [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...\n", - " [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...\n", - " \n", - " \n", - " 1\n", " [{'id': '2d939efefd3f45788ed103ff0723f564', 's...\n", " [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'...\n", " [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017...\n", " \n", + " \n", + " 1\n", + " [{'id': '45502524c9a150e77869ee647423dba1', 's...\n", + " [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...\n", + " [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...\n", + " \n", " \n", "\n", "" ], "text/plain": [ " registry_info \\\n", - "0 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", - "1 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "0 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "1 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", "\n", " registry_owners \\\n", - "0 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", - "1 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "0 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "1 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", "\n", " self_reported_info \n", - "0 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... \n", - "1 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... " + "0 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... \n", + "1 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... " ] }, "execution_count": 24, @@ -1185,15 +1194,6 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " ATLANTIC SURF III\n", - " ATLANTICSURF3\n", - " [TRAWLERS]\n", - " [IMO, TMT_OTHER_OFFICIAL]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " ARG\n", " CAPESANTE\n", @@ -1202,7 +1202,7 @@ " [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF...\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " ATLANTICLEADER\n", @@ -1210,19 +1210,28 @@ " [TRAWLERS]\n", " [IMO, TMT_OTHER_OFFICIAL]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " ATLANTIC SURF III\n", + " ATLANTICSURF3\n", + " [TRAWLERS]\n", + " [IMO, TMT_OTHER_OFFICIAL]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name gear_types \\\n", - "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", - "1 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", - "2 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "0 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", + "1 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "2 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", "\n", " source_code \n", - "0 [IMO, TMT_OTHER_OFFICIAL] \n", - "1 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "0 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "1 [IMO, TMT_OTHER_OFFICIAL] \n", "2 [IMO, TMT_OTHER_OFFICIAL] " ] }, @@ -1293,34 +1302,34 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " GLACIAR PESQUERA\n", - " [TMT_OTHER_OFFICIAL]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " CAN\n", " CLEARWATER SEAFOODS\n", " [RESEARCH-PAPER]\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " CS MANPAR\n", " [TMT_OTHER_OFFICIAL]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " GLACIAR PESQUERA\n", + " [TMT_OTHER_OFFICIAL]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag name source_code\n", - "0 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]\n", - "1 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", - "2 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]" + "0 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", + "1 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]\n", + "2 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]" ] }, "execution_count": 28, @@ -1389,14 +1398,6 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " ATLANTIC SURF III\n", - " ATLANTICSURF3\n", - " [AIS]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " ARG\n", " CAPESANTE\n", @@ -1404,22 +1405,30 @@ " [AIS]\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " ATLANTIC LEADER\n", " ATLANTICLEADER\n", " [AIS]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " ATLANTIC SURF III\n", + " ATLANTICSURF3\n", + " [AIS]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name source_code\n", - "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]\n", - "1 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", - "2 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]" + "0 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", + "1 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]\n", + "2 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]" ] }, "execution_count": 30, @@ -1689,36 +1698,36 @@ " 0\n", " ATLANTIC SURF III\n", " 701024000\n", - " 117.545450\n", - " 4.351747\n", + " 222.721610\n", + " 4.098386\n", " \n", " \n", " 1\n", " ATLANTIC SURF III\n", " 701024000\n", - " 10.408851\n", - " 3.791667\n", + " 7.905335\n", + " 4.590909\n", " \n", " \n", " 2\n", " ATLANTIC SURF III\n", " 701024000\n", - " 61.366911\n", - " 4.448980\n", + " 2.794681\n", + " 4.655555\n", " \n", " \n", " 3\n", " ATLANTIC SURF III\n", " 701024000\n", - " 92.180704\n", - " 4.485407\n", + " 2.012392\n", + " 2.953846\n", " \n", " \n", " 4\n", " ATLANTIC SURF III\n", " 701024000\n", - " 974.761871\n", - " 4.051429\n", + " 3.260040\n", + " 3.705556\n", " \n", " \n", " ...\n", @@ -1731,36 +1740,36 @@ " 346\n", " CAPESANTE\n", " 701006605\n", - " 95.128059\n", - " 4.202542\n", + " 25.568796\n", + " 4.074561\n", " \n", " \n", " 347\n", " CAPESANTE\n", " 701006605\n", - " 205.826282\n", - " 4.136848\n", + " 45.830980\n", + " 3.771852\n", " \n", " \n", " 348\n", " CAPESANTE\n", " 701006605\n", - " 369.336603\n", - " 3.938255\n", + " 74.611830\n", + " 4.087912\n", " \n", " \n", " 349\n", - " ATLANTIC SURF III\n", - " 701024000\n", - " 256.908842\n", - " 4.186333\n", + " CAPESANTE\n", + " 701006605\n", + " 82.607525\n", + " 3.788187\n", " \n", " \n", " 350\n", " CAPESANTE\n", " 701006605\n", - " 208.071985\n", - " 3.971505\n", + " 205.826282\n", + " 4.136848\n", " \n", " \n", "\n", @@ -1769,17 +1778,17 @@ ], "text/plain": [ " name ssvid total_distance_km average_speed_knots\n", - "0 ATLANTIC SURF III 701024000 117.545450 4.351747\n", - "1 ATLANTIC SURF III 701024000 10.408851 3.791667\n", - "2 ATLANTIC SURF III 701024000 61.366911 4.448980\n", - "3 ATLANTIC SURF III 701024000 92.180704 4.485407\n", - "4 ATLANTIC SURF III 701024000 974.761871 4.051429\n", + "0 ATLANTIC SURF III 701024000 222.721610 4.098386\n", + "1 ATLANTIC SURF III 701024000 7.905335 4.590909\n", + "2 ATLANTIC SURF III 701024000 2.794681 4.655555\n", + "3 ATLANTIC SURF III 701024000 2.012392 2.953846\n", + "4 ATLANTIC SURF III 701024000 3.260040 3.705556\n", ".. ... ... ... ...\n", - "346 CAPESANTE 701006605 95.128059 4.202542\n", - "347 CAPESANTE 701006605 205.826282 4.136848\n", - "348 CAPESANTE 701006605 369.336603 3.938255\n", - "349 ATLANTIC SURF III 701024000 256.908842 4.186333\n", - "350 CAPESANTE 701006605 208.071985 3.971505\n", + "346 CAPESANTE 701006605 25.568796 4.074561\n", + "347 CAPESANTE 701006605 45.830980 3.771852\n", + "348 CAPESANTE 701006605 74.611830 4.087912\n", + "349 CAPESANTE 701006605 82.607525 3.788187\n", + "350 CAPESANTE 701006605 205.826282 4.136848\n", "\n", "[351 rows x 4 columns]" ] @@ -1975,15 +1984,6 @@ " \n", " \n", " 2\n", - " CAPESANTE\n", - " 701006605\n", - " 4\n", - " USHUAIA\n", - " USHUAIA\n", - " USHUAIA\n", - " \n", - " \n", - " 3\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -1992,7 +1992,7 @@ " MAR DEL PLATA\n", " \n", " \n", - " 4\n", + " 3\n", " CAPESANTE\n", " 701006605\n", " 4\n", @@ -2001,7 +2001,7 @@ " USHUAIA\n", " \n", " \n", - " 5\n", + " 4\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -2010,7 +2010,7 @@ " MAR DEL PLATA\n", " \n", " \n", - " 6\n", + " 5\n", " CAPESANTE\n", " 701006605\n", " 4\n", @@ -2019,7 +2019,7 @@ " USHUAIA\n", " \n", " \n", - " 7\n", + " 6\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -2027,6 +2027,15 @@ " MAR DEL PLATA\n", " MAR DEL PLATA\n", " \n", + " \n", + " 7\n", + " CAPESANTE\n", + " 701006605\n", + " 4\n", + " USHUAIA\n", + " USHUAIA\n", + " USHUAIA\n", + " \n", " \n", "\n", "" @@ -2035,22 +2044,22 @@ " name ssvid confidence start_anchorage_name \\\n", "0 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", "1 CAPESANTE 701006605 4 USHUAIA \n", - "2 CAPESANTE 701006605 4 USHUAIA \n", - "3 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", - "4 CAPESANTE 701006605 4 USHUAIA \n", - "5 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", - "6 CAPESANTE 701006605 4 USHUAIA \n", - "7 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "2 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "3 CAPESANTE 701006605 4 USHUAIA \n", + "4 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "5 CAPESANTE 701006605 4 USHUAIA \n", + "6 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "7 CAPESANTE 701006605 4 USHUAIA \n", "\n", " intermediate_anchorage_name end_anchorage_name \n", "0 MAR DEL PLATA MAR DEL PLATA \n", "1 USHUAIA USHUAIA \n", - "2 USHUAIA USHUAIA \n", - "3 MAR DEL PLATA MAR DEL PLATA \n", - "4 USHUAIA USHUAIA \n", - "5 MAR DEL PLATA MAR DEL PLATA \n", - "6 USHUAIA USHUAIA \n", - "7 MAR DEL PLATA MAR DEL PLATA " + "2 MAR DEL PLATA MAR DEL PLATA \n", + "3 USHUAIA USHUAIA \n", + "4 MAR DEL PLATA MAR DEL PLATA \n", + "5 USHUAIA USHUAIA \n", + "6 MAR DEL PLATA MAR DEL PLATA \n", + "7 USHUAIA USHUAIA " ] }, "execution_count": 43, diff --git a/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb b/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb index a894429..76f7033 100644 --- a/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb +++ b/docs/source/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "53f445b9-02bb-425a-817a-2768941c7d5a", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -372,23 +381,23 @@ " \n", " 2\n", " None\n", - " fishing\n", - " 20929.563333\n", - " 21\n", + " pole_and_line\n", + " 3481.509167\n", + " 5\n", " \n", " \n", " 3\n", " None\n", - " inconclusive\n", - " 30496.173611\n", - " 27\n", + " other_purse_seines\n", + " 26.581111\n", + " 1\n", " \n", " \n", " 4\n", " None\n", - " pole_and_line\n", - " 3481.509167\n", - " 5\n", + " fishing\n", + " 20929.563333\n", + " 21\n", " \n", " \n", "\n", @@ -398,9 +407,9 @@ " flag gear_type hours vessel_ids\n", "0 None drifting_longlines 593.138333 3\n", "1 None purse_seines 6.340556 1\n", - "2 None fishing 20929.563333 21\n", - "3 None inconclusive 30496.173611 27\n", - "4 None pole_and_line 3481.509167 5" + "2 None pole_and_line 3481.509167 5\n", + "3 None other_purse_seines 26.581111 1\n", + "4 None fishing 20929.563333 21" ] }, "execution_count": 8, @@ -1578,36 +1587,36 @@ " 0\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 18.481056\n", - " 8.841667\n", + " 44.026882\n", + " 3.808824\n", " \n", " \n", " 1\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 34.867559\n", - " 8.240000\n", + " 9.353500\n", + " 8.200000\n", " \n", " \n", " 2\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 11.086850\n", - " 8.208333\n", + " 9.868050\n", + " 5.494444\n", " \n", " \n", " 3\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 12.699650\n", - " 8.266667\n", + " 10.955310\n", + " 8.555556\n", " \n", " \n", " 4\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 56.788034\n", - " 6.248000\n", + " 9.630687\n", + " 8.942857\n", " \n", " \n", " ...\n", @@ -1618,38 +1627,38 @@ " \n", " \n", " 409\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 12.164494\n", - " 5.083333\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 101.402263\n", + " 4.041791\n", " \n", " \n", " 410\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 13.191124\n", - " 3.986957\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 115.642159\n", + " 4.743357\n", " \n", " \n", " 411\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 8.685659\n", - " 3.850000\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 100.019456\n", + " 4.402564\n", " \n", " \n", " 412\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 15.721987\n", - " 3.686667\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 155.923138\n", + " 4.975000\n", " \n", " \n", " 413\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 28.553779\n", - " 3.728571\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 173.253137\n", + " 4.869231\n", " \n", " \n", "\n", @@ -1657,18 +1666,18 @@ "" ], "text/plain": [ - " name ssvid total_distance_km average_speed_knots\n", - "0 HUNG CHUAN SHUN 416007496 18.481056 8.841667\n", - "1 HUNG CHUAN SHUN 416007496 34.867559 8.240000\n", - "2 HUNG CHUAN SHUN 416007496 11.086850 8.208333\n", - "3 HUNG CHUAN SHUN 416007496 12.699650 8.266667\n", - "4 HUNG CHUAN SHUN 416007496 56.788034 6.248000\n", - ".. ... ... ... ...\n", - "409 SENSHU MARU NO.3 431100690 12.164494 5.083333\n", - "410 SENSHU MARU NO.3 431100690 13.191124 3.986957\n", - "411 SENSHU MARU NO.3 431100690 8.685659 3.850000\n", - "412 SENSHU MARU NO.3 431100690 15.721987 3.686667\n", - "413 SENSHU MARU NO.3 431100690 28.553779 3.728571\n", + " name ssvid total_distance_km average_speed_knots\n", + "0 HUNG CHUAN SHUN 416007496 44.026882 3.808824\n", + "1 HUNG CHUAN SHUN 416007496 9.353500 8.200000\n", + "2 HUNG CHUAN SHUN 416007496 9.868050 5.494444\n", + "3 HUNG CHUAN SHUN 416007496 10.955310 8.555556\n", + "4 HUNG CHUAN SHUN 416007496 9.630687 8.942857\n", + ".. ... ... ... ...\n", + "409 HUNG CHUAN SHUN 416007496 101.402263 4.041791\n", + "410 HUNG CHUAN SHUN 416007496 115.642159 4.743357\n", + "411 HUNG CHUAN SHUN 416007496 100.019456 4.402564\n", + "412 HUNG CHUAN SHUN 416007496 155.923138 4.975000\n", + "413 HUNG CHUAN SHUN 416007496 173.253137 4.869231\n", "\n", "[414 rows x 4 columns]" ] @@ -1847,6 +1856,15 @@ " \n", " \n", " 0\n", + " SENSHU MARU NO.3\n", + " 431100690\n", + " 4\n", + " TEMA\n", + " TEMA\n", + " TEMA\n", + " \n", + " \n", + " 1\n", " HUNG CHUAN SHUN\n", " 416007496\n", " 4\n", @@ -1855,7 +1873,7 @@ " TEMA\n", " \n", " \n", - " 1\n", + " 2\n", " SENSHU MARU NO.3\n", " 431100690\n", " 4\n", @@ -1864,7 +1882,7 @@ " TEMA\n", " \n", " \n", - " 2\n", + " 3\n", " None\n", " 412331032\n", " 4\n", @@ -1872,31 +1890,22 @@ " DAKAR\n", " DAKAR\n", " \n", - " \n", - " 3\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 4\n", - " TEMA\n", - " TEMA\n", - " TEMA\n", - " \n", " \n", "\n", "" ], "text/plain": [ " name ssvid confidence start_anchorage_name \\\n", - "0 HUNG CHUAN SHUN 416007496 4 TEMA \n", - "1 SENSHU MARU NO.3 431100690 4 TEMA \n", - "2 None 412331032 4 DAKAR \n", - "3 SENSHU MARU NO.3 431100690 4 TEMA \n", + "0 SENSHU MARU NO.3 431100690 4 TEMA \n", + "1 HUNG CHUAN SHUN 416007496 4 TEMA \n", + "2 SENSHU MARU NO.3 431100690 4 TEMA \n", + "3 None 412331032 4 DAKAR \n", "\n", " intermediate_anchorage_name end_anchorage_name \n", "0 TEMA TEMA \n", "1 TEMA TEMA \n", - "2 DAKAR DAKAR \n", - "3 TEMA TEMA " + "2 TEMA TEMA \n", + "3 DAKAR DAKAR " ] }, "execution_count": 39, diff --git a/notebooks/getting-started.ipynb b/notebooks/getting-started.ipynb index 4be4609..d764948 100644 --- a/notebooks/getting-started.ipynb +++ b/notebooks/getting-started.ipynb @@ -120,9 +120,9 @@ }, "outputs": [], "source": [ - "import os\n", "import datetime\n", - "import pandas as pd\n", + "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -139,7 +139,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -280,20 +280,20 @@ " []\n", " []\n", " []\n", - " [{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f...\n", - " [{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2...\n", - " [{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f...\n", + " [{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c...\n", + " [{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff...\n", + " [{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c...\n", " \n", " \n", " 1\n", " public-global-vessel-identity:v3.0\n", - " 1\n", - " [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's...\n", - " [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',...\n", - " [{'date_from': 2017-01-04 00:00:00+00:00, 'dat...\n", - " [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea...\n", - " [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b...\n", - " [{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea...\n", + " 0\n", + " []\n", + " []\n", + " []\n", + " [{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f...\n", + " [{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2...\n", + " [{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f...\n", " \n", " \n", " 2\n", @@ -302,20 +302,20 @@ " []\n", " []\n", " []\n", - " [{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c...\n", - " [{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff...\n", - " [{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c...\n", + " [{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75...\n", + " [{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80...\n", + " [{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75...\n", " \n", " \n", " 3\n", " public-global-vessel-identity:v3.0\n", - " 0\n", - " []\n", - " []\n", - " []\n", - " [{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d...\n", - " [{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741...\n", - " [{'reference': '108c5510b-b6aa-9cf2-8b86-0598d...\n", + " 1\n", + " [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's...\n", + " [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',...\n", + " [{'date_from': 2017-01-04 00:00:00+00:00, 'dat...\n", + " [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea...\n", + " [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b...\n", + " [{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea...\n", " \n", " \n", " 4\n", @@ -324,9 +324,9 @@ " []\n", " []\n", " []\n", - " [{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75...\n", - " [{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80...\n", - " [{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75...\n", + " [{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d...\n", + " [{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741...\n", + " [{'reference': '108c5510b-b6aa-9cf2-8b86-0598d...\n", " \n", " \n", "\n", @@ -335,52 +335,52 @@ "text/plain": [ " dataset registry_info_total_records \\\n", "0 public-global-vessel-identity:v3.0 0 \n", - "1 public-global-vessel-identity:v3.0 1 \n", + "1 public-global-vessel-identity:v3.0 0 \n", "2 public-global-vessel-identity:v3.0 0 \n", - "3 public-global-vessel-identity:v3.0 0 \n", + "3 public-global-vessel-identity:v3.0 1 \n", "4 public-global-vessel-identity:v3.0 0 \n", "\n", " registry_info \\\n", "0 [] \n", - "1 [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's... \n", + "1 [] \n", "2 [] \n", - "3 [] \n", + "3 [{'id': '4ef90bea19300c6a23f6ce627a80238b', 's... \n", "4 [] \n", "\n", " registry_owners \\\n", "0 [] \n", - "1 [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',... \n", + "1 [] \n", "2 [] \n", - "3 [] \n", + "3 [{'name': 'ZHOUSHAN SHUNHANG OCEAN FISHERIES',... \n", "4 [] \n", "\n", " registry_public_authorizations \\\n", "0 [] \n", - "1 [{'date_from': 2017-01-04 00:00:00+00:00, 'dat... \n", + "1 [] \n", "2 [] \n", - "3 [] \n", + "3 [{'date_from': 2017-01-04 00:00:00+00:00, 'dat... \n", "4 [] \n", "\n", " combined_sources_info \\\n", - "0 [{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", - "1 [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", - "2 [{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", - "3 [{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d... \n", - "4 [{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75... \n", + "0 [{'vessel_id': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", + "1 [{'vessel_id': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", + "2 [{'vessel_id': 'd2fbd05f5-57dd-1faa-c384-67a75... \n", + "3 [{'vessel_id': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", + "4 [{'vessel_id': '108c5510b-b6aa-9cf2-8b86-0598d... \n", "\n", " self_reported_info \\\n", - "0 [{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2... \n", - "1 [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b... \n", - "2 [{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff... \n", - "3 [{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741... \n", - "4 [{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80... \n", + "0 [{'id': 'a5ef97d59-9f40-3bdc-e247-daf9c892ceff... \n", + "1 [{'id': '91df2f8c7-74fd-5b5a-60f5-3d86f9c51ff2... \n", + "2 [{'id': 'd2fbd05f5-57dd-1faa-c384-67a75f27fc80... \n", + "3 [{'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b... \n", + "4 [{'id': '108c5510b-b6aa-9cf2-8b86-0598de546741... \n", "\n", " matchCriteria \n", - "0 [{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", - "1 [{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", - "2 [{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", - "3 [{'reference': '108c5510b-b6aa-9cf2-8b86-0598d... \n", - "4 [{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75... " + "0 [{'reference': 'a5ef97d59-9f40-3bdc-e247-daf9c... \n", + "1 [{'reference': '91df2f8c7-74fd-5b5a-60f5-3d86f... \n", + "2 [{'reference': 'd2fbd05f5-57dd-1faa-c384-67a75... \n", + "3 [{'reference': '755a48dd4-4bee-4bcf-7b5f-9baea... \n", + "4 [{'reference': '108c5510b-b6aa-9cf2-8b86-0598d... " ] }, "execution_count": 8, @@ -1018,85 +1018,85 @@ " \n", " \n", " 0\n", - " 2025-12-21 22:54:19+00:00\n", - " 2025-12-22 01:59:26+00:00\n", - " 20722d55b7a106978e2b55e65f7affa6\n", + " 2022-10-10 15:49:06+00:00\n", + " 2022-10-10 18:27:46+00:00\n", + " da35d28bfc433f251fe03c2ded3a5e23\n", " fishing\n", - " {'lat': -45.734, 'lon': -60.6275}\n", - " {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'...\n", - " [-60.638205, -45.736243333333334, -60.622215, ...\n", - " {'start_distance_from_shore_km': 390.0, 'end_d...\n", - " {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'...\n", + " {'lat': 42.9677, 'lon': 156.9126}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'NPFC'...\n", + " [156.90262, 42.93749, 156.92824, 42.979495]\n", + " {'start_distance_from_shore_km': 585.0, 'end_d...\n", + " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 1.553408717842079, 'aver...\n", + " {'total_distance_km': 5.313381753510874, 'aver...\n", " None\n", " None\n", " None\n", " \n", " \n", " 1\n", - " 2020-05-29 15:38:07+00:00\n", - " 2020-05-29 19:22:03+00:00\n", - " aa6f570aee327010bd4714aa6e459d08\n", + " 2022-10-08 23:28:16+00:00\n", + " 2022-10-09 04:06:15+00:00\n", + " 080bcd728a84f62fe901a3e5b02c6014\n", " fishing\n", - " {'lat': 41.4151, 'lon': 165.5954}\n", - " {'mpa': [], 'eez': [], 'rfmo': ['NPAFC', 'PICE...\n", - " [165.58234666666667, 41.404185, 165.602265, 41...\n", - " {'start_distance_from_shore_km': 1213.0, 'end_...\n", + " {'lat': 43.0665, 'lon': 156.4381}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['IWC', 'WCPFC'...\n", + " [156.38127166666666, 43.05014166666667, 156.49...\n", + " {'start_distance_from_shore_km': 549.0, 'end_d...\n", " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 3.2539329459390007, 'ave...\n", + " {'total_distance_km': 10.200405590755741, 'ave...\n", " None\n", " None\n", " None\n", " \n", " \n", " 2\n", - " 2025-12-31 23:00:02+00:00\n", - " 2026-01-01 07:57:31+00:00\n", - " 82ab07bcb2f0881dbdc2bea176f4d0eb\n", + " 2022-10-30 23:36:05+00:00\n", + " 2022-10-31 11:25:45+00:00\n", + " c79bf8fbab9e58bb3b279bf757bae197\n", " fishing\n", - " {'lat': -45.7853, 'lon': -60.6598}\n", - " {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'CCSBT...\n", - " [-60.66967666666667, -45.80526166666667, -60.6...\n", - " {'start_distance_from_shore_km': 390.0, 'end_d...\n", - " {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'...\n", + " {'lat': 41.0574, 'lon': 149.7023}\n", + " {'mpa': [], 'eez': ['48950'], 'rfmo': ['PICES'...\n", + " [149.66486666666665, 40.94216166666667, 149.73...\n", + " {'start_distance_from_shore_km': 392.0, 'end_d...\n", + " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 5.18218418253593, 'avera...\n", + " {'total_distance_km': 31.90361153133585, 'aver...\n", " None\n", " None\n", " None\n", " \n", " \n", " 3\n", - " 2021-03-23 22:31:06+00:00\n", - " 2021-03-24 06:45:12+00:00\n", - " 634e0f958283315e9850e1523e6f7a88\n", + " 2021-02-21 23:05:34+00:00\n", + " 2021-02-22 08:36:32+00:00\n", + " 3cdbebbfbf2b7c926158fa6955eecb30\n", " fishing\n", - " {'lat': -41.9474, 'lon': -57.9515}\n", - " {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'...\n", - " [-57.89071, -41.96338333333333, -57.9833649999...\n", - " {'start_distance_from_shore_km': 377.0, 'end_d...\n", + " {'lat': -45.8329, 'lon': -60.603}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['CCSBT', 'ICCA...\n", + " [-60.5669816667, -45.836216666666665, -60.6110...\n", + " {'start_distance_from_shore_km': 399.0, 'end_d...\n", " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 13.20298689870354, 'aver...\n", + " {'total_distance_km': 5.725649380735478, 'aver...\n", " None\n", " None\n", " None\n", " \n", " \n", " 4\n", - " 2022-06-17 12:52:22+00:00\n", - " 2022-06-17 18:55:39+00:00\n", - " 1c4ef3bc92b7a763c5f3b04d3a1a0779\n", + " 2020-05-26 16:43:39+00:00\n", + " 2020-05-26 18:25:46+00:00\n", + " 9b6a1c84d8daf3359a0d9917ff138d39\n", " fishing\n", - " {'lat': 42.8639, 'lon': 168.4996}\n", - " {'mpa': [], 'eez': [], 'rfmo': ['WCPFC', 'NPAF...\n", - " [168.47266833333333, 42.858135, 168.5181933333...\n", - " {'start_distance_from_shore_km': 1122.0, 'end_...\n", + " {'lat': 41.4176, 'lon': 165.3167}\n", + " {'mpa': [], 'eez': [], 'rfmo': ['IWC', 'NPFC',...\n", + " [165.315, 41.409706666666665, 165.31824, 41.42...\n", + " {'start_distance_from_shore_km': 1198.0, 'end_...\n", " {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'...\n", " None\n", - " {'total_distance_km': 4.430991184550807, 'aver...\n", + " {'total_distance_km': 2.3609454154613645, 'ave...\n", " None\n", " None\n", " None\n", @@ -1107,60 +1107,60 @@ ], "text/plain": [ " start end \\\n", - "0 2025-12-21 22:54:19+00:00 2025-12-22 01:59:26+00:00 \n", - "1 2020-05-29 15:38:07+00:00 2020-05-29 19:22:03+00:00 \n", - "2 2025-12-31 23:00:02+00:00 2026-01-01 07:57:31+00:00 \n", - "3 2021-03-23 22:31:06+00:00 2021-03-24 06:45:12+00:00 \n", - "4 2022-06-17 12:52:22+00:00 2022-06-17 18:55:39+00:00 \n", + "0 2022-10-10 15:49:06+00:00 2022-10-10 18:27:46+00:00 \n", + "1 2022-10-08 23:28:16+00:00 2022-10-09 04:06:15+00:00 \n", + "2 2022-10-30 23:36:05+00:00 2022-10-31 11:25:45+00:00 \n", + "3 2021-02-21 23:05:34+00:00 2021-02-22 08:36:32+00:00 \n", + "4 2020-05-26 16:43:39+00:00 2020-05-26 18:25:46+00:00 \n", "\n", " id type \\\n", - "0 20722d55b7a106978e2b55e65f7affa6 fishing \n", - "1 aa6f570aee327010bd4714aa6e459d08 fishing \n", - "2 82ab07bcb2f0881dbdc2bea176f4d0eb fishing \n", - "3 634e0f958283315e9850e1523e6f7a88 fishing \n", - "4 1c4ef3bc92b7a763c5f3b04d3a1a0779 fishing \n", + "0 da35d28bfc433f251fe03c2ded3a5e23 fishing \n", + "1 080bcd728a84f62fe901a3e5b02c6014 fishing \n", + "2 c79bf8fbab9e58bb3b279bf757bae197 fishing \n", + "3 3cdbebbfbf2b7c926158fa6955eecb30 fishing \n", + "4 9b6a1c84d8daf3359a0d9917ff138d39 fishing \n", "\n", - " position \\\n", - "0 {'lat': -45.734, 'lon': -60.6275} \n", - "1 {'lat': 41.4151, 'lon': 165.5954} \n", - "2 {'lat': -45.7853, 'lon': -60.6598} \n", - "3 {'lat': -41.9474, 'lon': -57.9515} \n", - "4 {'lat': 42.8639, 'lon': 168.4996} \n", + " position \\\n", + "0 {'lat': 42.9677, 'lon': 156.9126} \n", + "1 {'lat': 43.0665, 'lon': 156.4381} \n", + "2 {'lat': 41.0574, 'lon': 149.7023} \n", + "3 {'lat': -45.8329, 'lon': -60.603} \n", + "4 {'lat': 41.4176, 'lon': 165.3167} \n", "\n", " regions \\\n", - "0 {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'... \n", - "1 {'mpa': [], 'eez': [], 'rfmo': ['NPAFC', 'PICE... \n", - "2 {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'CCSBT... \n", - "3 {'mpa': [], 'eez': [], 'rfmo': ['ICCAT', 'IWC'... \n", - "4 {'mpa': [], 'eez': [], 'rfmo': ['WCPFC', 'NPAF... \n", + "0 {'mpa': [], 'eez': [], 'rfmo': ['ACAP', 'NPFC'... \n", + "1 {'mpa': [], 'eez': [], 'rfmo': ['IWC', 'WCPFC'... \n", + "2 {'mpa': [], 'eez': ['48950'], 'rfmo': ['PICES'... \n", + "3 {'mpa': [], 'eez': [], 'rfmo': ['CCSBT', 'ICCA... \n", + "4 {'mpa': [], 'eez': [], 'rfmo': ['IWC', 'NPFC',... \n", "\n", " bounding_box \\\n", - "0 [-60.638205, -45.736243333333334, -60.622215, ... \n", - "1 [165.58234666666667, 41.404185, 165.602265, 41... \n", - "2 [-60.66967666666667, -45.80526166666667, -60.6... \n", - "3 [-57.89071, -41.96338333333333, -57.9833649999... \n", - "4 [168.47266833333333, 42.858135, 168.5181933333... \n", + "0 [156.90262, 42.93749, 156.92824, 42.979495] \n", + "1 [156.38127166666666, 43.05014166666667, 156.49... \n", + "2 [149.66486666666665, 40.94216166666667, 149.73... \n", + "3 [-60.5669816667, -45.836216666666665, -60.6110... \n", + "4 [165.315, 41.409706666666665, 165.31824, 41.42... \n", "\n", " distances \\\n", - "0 {'start_distance_from_shore_km': 390.0, 'end_d... \n", - "1 {'start_distance_from_shore_km': 1213.0, 'end_... \n", - "2 {'start_distance_from_shore_km': 390.0, 'end_d... \n", - "3 {'start_distance_from_shore_km': 377.0, 'end_d... \n", - "4 {'start_distance_from_shore_km': 1122.0, 'end_... \n", + "0 {'start_distance_from_shore_km': 585.0, 'end_d... \n", + "1 {'start_distance_from_shore_km': 549.0, 'end_d... \n", + "2 {'start_distance_from_shore_km': 392.0, 'end_d... \n", + "3 {'start_distance_from_shore_km': 399.0, 'end_d... \n", + "4 {'start_distance_from_shore_km': 1198.0, 'end_... \n", "\n", " vessel encounter \\\n", - "0 {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'... None \n", + "0 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", "1 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", - "2 {'id': '755a48dd4-4bee-4bcf-7b5f-9baea058fc7b'... None \n", + "2 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", "3 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", "4 {'id': '3dad49b0b-b2e0-9347-0c4c-e39fea560f9f'... None \n", "\n", " fishing gap loitering \\\n", - "0 {'total_distance_km': 1.553408717842079, 'aver... None None \n", - "1 {'total_distance_km': 3.2539329459390007, 'ave... None None \n", - "2 {'total_distance_km': 5.18218418253593, 'avera... None None \n", - "3 {'total_distance_km': 13.20298689870354, 'aver... None None \n", - "4 {'total_distance_km': 4.430991184550807, 'aver... None None \n", + "0 {'total_distance_km': 5.313381753510874, 'aver... None None \n", + "1 {'total_distance_km': 10.200405590755741, 'ave... None None \n", + "2 {'total_distance_km': 31.90361153133585, 'aver... None None \n", + "3 {'total_distance_km': 5.725649380735478, 'aver... None None \n", + "4 {'total_distance_km': 2.3609454154613645, 'ave... None None \n", "\n", " port_visit \n", "0 None \n", diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index 6c4d5df..29de3e3 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "fe7df9a0-cd5e-4b99-94b4-07b2ca0481f0", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -165,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 38, "id": "338223ff-9c23-47f6-bf33-2aaaefc35081", "metadata": {}, "outputs": [], @@ -193,7 +202,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 39, "id": "3bff3854-9b54-44c9-a7f8-3ef2bf1b7719", "metadata": {}, "outputs": [], @@ -203,7 +212,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 40, "id": "21e8b553-20dd-43bb-92c3-0e7f5f6f29c3", "metadata": {}, "outputs": [], @@ -213,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 41, "id": "29bd8b84-1f22-4a11-9861-548237926012", "metadata": {}, "outputs": [ @@ -223,7 +232,7 @@ "('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0)" ] }, - "execution_count": 8, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -249,7 +258,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 42, "id": "a778ef19-f68d-4e0b-8b37-539db79868cb", "metadata": {}, "outputs": [], @@ -259,7 +268,51 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 43, + "id": "271d446a-702d-42bb-93a9-e576741a3fdd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 32271 entries, 0 to 32270\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 32271 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 32271 non-null object \n", + " 3 gear_type 0 non-null object \n", + " 4 hours 32271 non-null float64\n", + " 5 vessel_ids 32271 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 32271 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 32271 non-null float64\n", + " 19 lon 32271 non-null float64\n", + "dtypes: float64(3), int64(1), object(16)\n", + "memory usage: 4.9+ MB\n" + ] + } + ], + "source": [ + "fishing_effort_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, "id": "5145b645-c0fe-4780-b94f-261b534b7f04", "metadata": {}, "outputs": [ @@ -309,12 +362,12 @@ " \n", " \n", " 0\n", - " 2022-03\n", + " 2022-02\n", " None\n", " RUS\n", " None\n", - " 3.416944\n", - " 2\n", + " 58.298253\n", + " 18\n", " None\n", " None\n", " None\n", @@ -327,8 +380,8 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 75.6\n", - " 50.3\n", + " 54.5\n", + " 151.4\n", " \n", " \n", " 1\n", @@ -336,8 +389,8 @@ " None\n", " RUS\n", " None\n", - " 2.144444\n", - " 3\n", + " 53.717894\n", + " 9\n", " None\n", " None\n", " None\n", @@ -350,17 +403,17 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 51.4\n", - " 155.4\n", + " 70.4\n", + " 32.3\n", " \n", " \n", " 2\n", - " 2022-03\n", + " 2022-02\n", " None\n", " RUS\n", " None\n", - " 5.436944\n", - " 2\n", + " 1.083333\n", + " 1\n", " None\n", " None\n", " None\n", @@ -373,8 +426,8 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 58.6\n", - " 155.8\n", + " 56.2\n", + " 155.4\n", " \n", " \n", " 3\n", @@ -382,8 +435,8 @@ " None\n", " RUS\n", " None\n", - " 4.435556\n", - " 1\n", + " 5.364167\n", + " 2\n", " None\n", " None\n", " None\n", @@ -396,8 +449,8 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 45.7\n", - " 149.8\n", + " 50.0\n", + " 141.8\n", " \n", " \n", " 4\n", @@ -405,8 +458,8 @@ " None\n", " RUS\n", " None\n", - " 0.362778\n", - " 1\n", + " 2.393056\n", + " 2\n", " None\n", " None\n", " None\n", @@ -419,20 +472,20 @@ " None\n", " public-global-fishing-effort:v3.0\n", " None\n", - " 46.7\n", - " 141.9\n", + " 56.2\n", + " 162.5\n", " \n", " \n", "\n", "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-03 None RUS None 3.416944 2 None \n", - "1 2022-02 None RUS None 2.144444 3 None \n", - "2 2022-03 None RUS None 5.436944 2 None \n", - "3 2022-01 None RUS None 4.435556 1 None \n", - "4 2022-03 None RUS None 0.362778 1 None \n", + " date detections flag gear_type hours vessel_ids vessel_id \\\n", + "0 2022-02 None RUS None 58.298253 18 None \n", + "1 2022-02 None RUS None 53.717894 9 None \n", + "2 2022-02 None RUS None 1.083333 1 None \n", + "3 2022-01 None RUS None 5.364167 2 None \n", + "4 2022-03 None RUS None 2.393056 2 None \n", "\n", " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", "0 None None None None \n", @@ -449,14 +502,14 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-fishing-effort:v3.0 None 75.6 50.3 \n", - "1 public-global-fishing-effort:v3.0 None 51.4 155.4 \n", - "2 public-global-fishing-effort:v3.0 None 58.6 155.8 \n", - "3 public-global-fishing-effort:v3.0 None 45.7 149.8 \n", - "4 public-global-fishing-effort:v3.0 None 46.7 141.9 " + "0 public-global-fishing-effort:v3.0 None 54.5 151.4 \n", + "1 public-global-fishing-effort:v3.0 None 70.4 32.3 \n", + "2 public-global-fishing-effort:v3.0 None 56.2 155.4 \n", + "3 public-global-fishing-effort:v3.0 None 50.0 141.8 \n", + "4 public-global-fishing-effort:v3.0 None 56.2 162.5 " ] }, - "execution_count": 10, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -491,7 +544,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 45, "id": "0946a5ab-5090-4920-94dd-88c733528f5b", "metadata": {}, "outputs": [], @@ -519,7 +572,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 46, "id": "5a5d349d-f60f-4fd3-997e-f74c82d2d4f9", "metadata": {}, "outputs": [], @@ -529,7 +582,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 47, "id": "f4435324-5b39-40dd-897e-6a7ef7620a93", "metadata": {}, "outputs": [], @@ -539,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 49, "id": "b2990454-d924-4288-8e4f-90e4ab60015b", "metadata": {}, "outputs": [ @@ -549,7 +602,7 @@ "('2022-03', 'RUS', 1.0, 1, 52.1, 153.2)" ] }, - "execution_count": 14, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -575,7 +628,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 50, "id": "4ad188a4-fbaf-41ee-ab4b-6aeda56e0e57", "metadata": {}, "outputs": [], @@ -585,7 +638,51 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 51, + "id": "71bee1f2-2316-4908-9fdf-668854cd3c49", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 274333 entries, 0 to 274332\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 274333 non-null object \n", + " 1 detections 0 non-null object \n", + " 2 flag 274333 non-null object \n", + " 3 gear_type 0 non-null object \n", + " 4 hours 274333 non-null float64\n", + " 5 vessel_ids 274333 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 274333 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 274333 non-null float64\n", + " 19 lon 274333 non-null float64\n", + "dtypes: float64(3), int64(1), object(16)\n", + "memory usage: 41.9+ MB\n" + ] + } + ], + "source": [ + "ais_presence_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 52, "id": "b8c04941-74fc-4a46-bc00-9e66afc59e10", "metadata": {}, "outputs": [ @@ -782,7 +879,7 @@ "4 public-global-presence:v3.0 None 50.0 157.0 " ] }, - "execution_count": 16, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -817,7 +914,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "45789061-c4e1-4938-b061-79122adb25da", "metadata": {}, "outputs": [], @@ -845,7 +942,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 53, "id": "c8f3894f-9d4a-4b2a-8f18-751c8155fddb", "metadata": {}, "outputs": [], @@ -855,7 +952,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 54, "id": "c138eca3-4921-4056-8b68-6d658901fd17", "metadata": {}, "outputs": [], @@ -865,7 +962,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 55, "id": "50d60501-e2c2-4b41-a341-845440c8cc8f", "metadata": {}, "outputs": [ @@ -875,7 +972,7 @@ "('2022-04', '', 1, 1, 46.6, 142.6)" ] }, - "execution_count": 20, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -901,7 +998,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 56, "id": "05179b03-f391-45c7-86ce-c26e3f27eef0", "metadata": {}, "outputs": [], @@ -911,7 +1008,51 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 72, + "id": "e8fa4e6f-efb9-4e5a-96f9-679bbc3578f8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3995 entries, 0 to 3994\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 3995 non-null object \n", + " 1 detections 3995 non-null int64 \n", + " 2 flag 3995 non-null object \n", + " 3 gear_type 0 non-null object \n", + " 4 hours 0 non-null object \n", + " 5 vessel_ids 3995 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 3995 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 3995 non-null float64\n", + " 19 lon 3995 non-null float64\n", + "dtypes: float64(2), int64(2), object(16)\n", + "memory usage: 624.3+ KB\n" + ] + } + ], + "source": [ + "sar_presence_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 58, "id": "6b1fee79-c5ab-42f6-98fe-7c0be9312b1e", "metadata": {}, "outputs": [ @@ -961,9 +1102,9 @@ " \n", " \n", " 0\n", - " 2022-01\n", + " 2022-02\n", " 1\n", - " \n", + " LBR\n", " None\n", " None\n", " 1\n", @@ -979,17 +1120,17 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 44.6\n", - " 38.0\n", + " 47.2\n", + " 153.0\n", " \n", " \n", " 1\n", - " 2022-03\n", - " 3\n", - " RUS\n", + " 2022-02\n", + " 1\n", + " BHS\n", " None\n", " None\n", - " 3\n", + " 1\n", " None\n", " None\n", " None\n", @@ -1002,14 +1143,14 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 46.7\n", - " 141.8\n", + " 44.2\n", + " 37.3\n", " \n", " \n", " 2\n", - " 2022-04\n", + " 2022-02\n", " 1\n", - " RUS\n", + " \n", " None\n", " None\n", " 1\n", @@ -1025,17 +1166,17 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 46.8\n", - " 141.4\n", + " 46.3\n", + " 142.4\n", " \n", " \n", " 3\n", - " 2022-02\n", - " 2\n", - " GRC\n", + " 2022-04\n", + " 17\n", + " RUS\n", " None\n", " None\n", - " 2\n", + " 14\n", " None\n", " None\n", " None\n", @@ -1048,14 +1189,14 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 44.2\n", - " 37.4\n", + " 45.5\n", + " 36.7\n", " \n", " \n", " 4\n", - " 2022-01\n", + " 2022-04\n", " 1\n", - " MLT\n", + " SGP\n", " None\n", " None\n", " 1\n", @@ -1071,8 +1212,8 @@ " None\n", " public-global-sar-presence:v3.0\n", " None\n", - " 43.8\n", - " 38.7\n", + " 46.3\n", + " 151.9\n", " \n", " \n", "\n", @@ -1080,11 +1221,11 @@ ], "text/plain": [ " date detections flag gear_type hours vessel_ids vessel_id vessel_type \\\n", - "0 2022-01 1 None None 1 None None \n", - "1 2022-03 3 RUS None None 3 None None \n", - "2 2022-04 1 RUS None None 1 None None \n", - "3 2022-02 2 GRC None None 2 None None \n", - "4 2022-01 1 MLT None None 1 None None \n", + "0 2022-02 1 LBR None None 1 None None \n", + "1 2022-02 1 BHS None None 1 None None \n", + "2 2022-02 1 None None 1 None None \n", + "3 2022-04 17 RUS None None 14 None None \n", + "4 2022-04 1 SGP None None 1 None None \n", "\n", " entry_timestamp exit_timestamp first_transmission_date \\\n", "0 None None None \n", @@ -1101,14 +1242,14 @@ "4 None None None None None \n", "\n", " report_dataset ship_name lat lon \n", - "0 public-global-sar-presence:v3.0 None 44.6 38.0 \n", - "1 public-global-sar-presence:v3.0 None 46.7 141.8 \n", - "2 public-global-sar-presence:v3.0 None 46.8 141.4 \n", - "3 public-global-sar-presence:v3.0 None 44.2 37.4 \n", - "4 public-global-sar-presence:v3.0 None 43.8 38.7 " + "0 public-global-sar-presence:v3.0 None 47.2 153.0 \n", + "1 public-global-sar-presence:v3.0 None 44.2 37.3 \n", + "2 public-global-sar-presence:v3.0 None 46.3 142.4 \n", + "3 public-global-sar-presence:v3.0 None 45.5 36.7 \n", + "4 public-global-sar-presence:v3.0 None 46.3 151.9 " ] }, - "execution_count": 22, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1145,7 +1286,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "id": "d446f679-746a-4942-a5e0-ef1ca1324d65", "metadata": { "id": "d446f679-746a-4942-a5e0-ef1ca1324d65" @@ -1156,7 +1297,11 @@ " spatial_resolution=\"LOW\",\n", " temporal_resolution=\"MONTHLY\",\n", " group_by=\"FLAG\",\n", - " datasets=[\"public-global-fishing-effort:latest\"],\n", + " datasets=[\n", + " \"public-global-fishing-effort:latest\",\n", + " \"public-global-sar-presence:latest\",\n", + " \"public-global-presence:latest\",\n", + " ],\n", " start_date=\"2022-01-01\",\n", " end_date=\"2022-05-01\",\n", " region={\n", @@ -1178,7 +1323,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 67, "id": "cc7947e2-d2cb-45b1-b47b-818bf4bebc95", "metadata": { "id": "cc7947e2-d2cb-45b1-b47b-818bf4bebc95" @@ -1190,7 +1335,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 68, "id": "198ad2ee-a199-4d9e-8e76-0deb8395461f", "metadata": { "id": "198ad2ee-a199-4d9e-8e76-0deb8395461f" @@ -1202,7 +1347,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 69, "id": "2ba5f27b-f881-40a2-a75b-f00a139f1d34", "metadata": { "colab": { @@ -1215,10 +1360,10 @@ { "data": { "text/plain": [ - "('2022-03', 'RUS', 7.109166666666667, 3, 75.8, 44.0)" + "('2022-03', 'RUS', 1.0, 1, 52.1, 153.2)" ] }, - "execution_count": 26, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -1246,7 +1391,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 62, "id": "3720799b-192f-4b77-9ca2-a3614942d2d7", "metadata": { "id": "3720799b-192f-4b77-9ca2-a3614942d2d7" @@ -1258,7 +1403,51 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 66, + "id": "7f298c61-d038-4d2e-86f2-2d5a554aa267", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 310599 entries, 0 to 310598\n", + "Data columns (total 20 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 date 310599 non-null object \n", + " 1 detections 3995 non-null float64\n", + " 2 flag 310599 non-null object \n", + " 3 gear_type 0 non-null object \n", + " 4 hours 306604 non-null float64\n", + " 5 vessel_ids 310599 non-null int64 \n", + " 6 vessel_id 0 non-null object \n", + " 7 vessel_type 0 non-null object \n", + " 8 entry_timestamp 0 non-null object \n", + " 9 exit_timestamp 0 non-null object \n", + " 10 first_transmission_date 0 non-null object \n", + " 11 last_transmission_date 0 non-null object \n", + " 12 imo 0 non-null object \n", + " 13 mmsi 0 non-null object \n", + " 14 call_sign 0 non-null object \n", + " 15 dataset 0 non-null object \n", + " 16 report_dataset 310599 non-null object \n", + " 17 ship_name 0 non-null object \n", + " 18 lat 310599 non-null float64\n", + " 19 lon 310599 non-null float64\n", + "dtypes: float64(4), int64(1), object(15)\n", + "memory usage: 47.4+ MB\n" + ] + } + ], + "source": [ + "report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 64, "id": "8cce33de-675d-42c6-8eac-36974a9e7f48", "metadata": { "colab": { @@ -1316,7 +1505,7 @@ " \n", " 0\n", " 2022-03\n", - " None\n", + " NaN\n", " RUS\n", " None\n", " 3.416944\n", @@ -1339,7 +1528,7 @@ " \n", " 1\n", " 2022-02\n", - " None\n", + " NaN\n", " RUS\n", " None\n", " 2.144444\n", @@ -1362,7 +1551,7 @@ " \n", " 2\n", " 2022-03\n", - " None\n", + " NaN\n", " RUS\n", " None\n", " 5.436944\n", @@ -1385,7 +1574,7 @@ " \n", " 3\n", " 2022-01\n", - " None\n", + " NaN\n", " RUS\n", " None\n", " 4.435556\n", @@ -1408,7 +1597,7 @@ " \n", " 4\n", " 2022-03\n", - " None\n", + " NaN\n", " RUS\n", " None\n", " 0.362778\n", @@ -1433,12 +1622,12 @@ "" ], "text/plain": [ - " date detections flag gear_type hours vessel_ids vessel_id \\\n", - "0 2022-03 None RUS None 3.416944 2 None \n", - "1 2022-02 None RUS None 2.144444 3 None \n", - "2 2022-03 None RUS None 5.436944 2 None \n", - "3 2022-01 None RUS None 4.435556 1 None \n", - "4 2022-03 None RUS None 0.362778 1 None \n", + " date detections flag gear_type hours vessel_ids vessel_id \\\n", + "0 2022-03 NaN RUS None 3.416944 2 None \n", + "1 2022-02 NaN RUS None 2.144444 3 None \n", + "2 2022-03 NaN RUS None 5.436944 2 None \n", + "3 2022-01 NaN RUS None 4.435556 1 None \n", + "4 2022-03 NaN RUS None 0.362778 1 None \n", "\n", " vessel_type entry_timestamp exit_timestamp first_transmission_date \\\n", "0 None None None None \n", @@ -1462,7 +1651,7 @@ "4 public-global-fishing-effort:v3.0 None 46.7 141.9 " ] }, - "execution_count": 28, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/datasets-api.ipynb b/notebooks/usage-guides/datasets-api.ipynb index 41f53ea..364d63c 100644 --- a/notebooks/usage-guides/datasets-api.ipynb +++ b/notebooks/usage-guides/datasets-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "e0ca8a5b-2028-48e0-8cb4-0c3f9601dcf6", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -234,7 +243,7 @@ { "data": { "text/plain": [ - "(646348, 'oil', -39.15082587013905, 177.96658840984458)" + "(1065796, 'oil', -71.81842050325909, -12.6523216191814)" ] }, "execution_count": 9, @@ -276,6 +285,37 @@ { "cell_type": "code", "execution_count": 11, + "id": "de8e24ee-4c15-4c38-846b-fce96ec7c41a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1156 entries, 0 to 1155\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 structure_id 1156 non-null int64 \n", + " 1 lat 1156 non-null float64 \n", + " 2 lon 1156 non-null float64 \n", + " 3 label 1156 non-null object \n", + " 4 structure_start_date 1156 non-null datetime64[ns, UTC]\n", + " 5 structure_end_date 857 non-null datetime64[ns, UTC]\n", + " 6 label_confidence 1156 non-null object \n", + "dtypes: datetime64[ns, UTC](2), float64(2), int64(1), object(2)\n", + "memory usage: 63.3+ KB\n" + ] + } + ], + "source": [ + "sar_infrastructure_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, "id": "5350bf55-3a37-4fa9-a1d9-0642e9ece7ef", "metadata": { "colab": { @@ -319,52 +359,52 @@ " \n", " \n", " 0\n", - " 170796\n", - " 1.509645\n", - " -78.888106\n", - " unknown\n", - " 2021-11-01 00:00:00+00:00\n", - " 2021-12-01 00:00:00+00:00\n", - " high\n", - " \n", - " \n", - " 1\n", - " 254126\n", - " 1.029763\n", - " -79.745796\n", + " 128911\n", + " -14.374089\n", + " -170.707656\n", " oil\n", " 2017-01-01 00:00:00+00:00\n", " NaT\n", + " low\n", + " \n", + " \n", + " 1\n", + " 901458\n", + " -17.949867\n", + " -150.537969\n", + " unknown\n", + " 2020-01-01 00:00:00+00:00\n", + " 2020-01-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 2\n", - " 360586\n", - " 1.021449\n", - " -79.733240\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073932\n", + " -16.838022\n", + " -148.715736\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 3\n", - " 237733\n", - " 1.030971\n", - " -79.717878\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073227\n", + " -16.883566\n", + " -148.518017\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 4\n", - " 450717\n", - " 1.033458\n", - " -79.699540\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073521\n", + " -16.900634\n", + " -148.443097\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", @@ -372,22 +412,22 @@ "" ], "text/plain": [ - " structure_id lat lon label structure_start_date \\\n", - "0 170796 1.509645 -78.888106 unknown 2021-11-01 00:00:00+00:00 \n", - "1 254126 1.029763 -79.745796 oil 2017-01-01 00:00:00+00:00 \n", - "2 360586 1.021449 -79.733240 oil 2017-01-01 00:00:00+00:00 \n", - "3 237733 1.030971 -79.717878 oil 2017-01-01 00:00:00+00:00 \n", - "4 450717 1.033458 -79.699540 oil 2017-01-01 00:00:00+00:00 \n", + " structure_id lat lon label structure_start_date \\\n", + "0 128911 -14.374089 -170.707656 oil 2017-01-01 00:00:00+00:00 \n", + "1 901458 -17.949867 -150.537969 unknown 2020-01-01 00:00:00+00:00 \n", + "2 1073932 -16.838022 -148.715736 unknown 2025-04-01 00:00:00+00:00 \n", + "3 1073227 -16.883566 -148.518017 unknown 2025-04-01 00:00:00+00:00 \n", + "4 1073521 -16.900634 -148.443097 unknown 2025-04-01 00:00:00+00:00 \n", "\n", " structure_end_date label_confidence \n", - "0 2021-12-01 00:00:00+00:00 high \n", - "1 NaT high \n", - "2 NaT high \n", - "3 NaT high \n", - "4 NaT high " + "0 NaT low \n", + "1 2020-01-01 00:00:00+00:00 high \n", + "2 2025-04-01 00:00:00+00:00 high \n", + "3 2025-04-01 00:00:00+00:00 high \n", + "4 2025-04-01 00:00:00+00:00 high " ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -408,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "7b12622e-db12-4adb-9721-717070e026f8", "metadata": { "id": "7b12622e-db12-4adb-9721-717070e026f8" @@ -431,7 +471,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "02c19ae9-fb43-4f95-a9c2-e0e5b97a7089", "metadata": { "id": "02c19ae9-fb43-4f95-a9c2-e0e5b97a7089" @@ -445,7 +485,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "4ca75748-9258-4352-8286-ff3f2dacf2b0", "metadata": { "id": "4ca75748-9258-4352-8286-ff3f2dacf2b0" @@ -457,7 +497,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "276c553b-df26-43cc-a1f3-6319417552e9", "metadata": { "id": "276c553b-df26-43cc-a1f3-6319417552e9" @@ -469,7 +509,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "30f82972-50dc-4c60-a901-21c2acc17255", "metadata": { "colab": { @@ -482,10 +522,10 @@ { "data": { "text/plain": [ - "(646348, 'oil', -39.15082587013905, 177.96658840984458)" + "(1065796, 'oil', -71.81842050325909, -12.6523216191814)" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -511,7 +551,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "d29b4044-5ba2-44bf-a00f-f1b01cb35ab6", "metadata": { "id": "d29b4044-5ba2-44bf-a00f-f1b01cb35ab6" @@ -523,7 +563,38 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, + "id": "d7b179d5-4f23-49ce-b703-94f497230057", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1156 entries, 0 to 1155\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 structure_id 1156 non-null int64 \n", + " 1 lat 1156 non-null float64 \n", + " 2 lon 1156 non-null float64 \n", + " 3 label 1156 non-null object \n", + " 4 structure_start_date 1156 non-null datetime64[ns, UTC]\n", + " 5 structure_end_date 857 non-null datetime64[ns, UTC]\n", + " 6 label_confidence 1156 non-null object \n", + "dtypes: datetime64[ns, UTC](2), float64(2), int64(1), object(2)\n", + "memory usage: 63.3+ KB\n" + ] + } + ], + "source": [ + "sar_infrastructure_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, "id": "7ca536d1-dfa2-4ba7-b20a-72e739c66775", "metadata": { "colab": { @@ -567,52 +638,52 @@ " \n", " \n", " 0\n", - " 170796\n", - " 1.509645\n", - " -78.888106\n", - " unknown\n", - " 2021-11-01 00:00:00+00:00\n", - " 2021-12-01 00:00:00+00:00\n", - " high\n", - " \n", - " \n", - " 1\n", - " 254126\n", - " 1.029763\n", - " -79.745796\n", + " 128911\n", + " -14.374089\n", + " -170.707656\n", " oil\n", " 2017-01-01 00:00:00+00:00\n", " NaT\n", + " low\n", + " \n", + " \n", + " 1\n", + " 901458\n", + " -17.949867\n", + " -150.537969\n", + " unknown\n", + " 2020-01-01 00:00:00+00:00\n", + " 2020-01-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 2\n", - " 360586\n", - " 1.021449\n", - " -79.733240\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073932\n", + " -16.838022\n", + " -148.715736\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 3\n", - " 237733\n", - " 1.030971\n", - " -79.717878\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073227\n", + " -16.883566\n", + " -148.518017\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", " 4\n", - " 450717\n", - " 1.033458\n", - " -79.699540\n", - " oil\n", - " 2017-01-01 00:00:00+00:00\n", - " NaT\n", + " 1073521\n", + " -16.900634\n", + " -148.443097\n", + " unknown\n", + " 2025-04-01 00:00:00+00:00\n", + " 2025-04-01 00:00:00+00:00\n", " high\n", " \n", " \n", @@ -620,22 +691,22 @@ "" ], "text/plain": [ - " structure_id lat lon label structure_start_date \\\n", - "0 170796 1.509645 -78.888106 unknown 2021-11-01 00:00:00+00:00 \n", - "1 254126 1.029763 -79.745796 oil 2017-01-01 00:00:00+00:00 \n", - "2 360586 1.021449 -79.733240 oil 2017-01-01 00:00:00+00:00 \n", - "3 237733 1.030971 -79.717878 oil 2017-01-01 00:00:00+00:00 \n", - "4 450717 1.033458 -79.699540 oil 2017-01-01 00:00:00+00:00 \n", + " structure_id lat lon label structure_start_date \\\n", + "0 128911 -14.374089 -170.707656 oil 2017-01-01 00:00:00+00:00 \n", + "1 901458 -17.949867 -150.537969 unknown 2020-01-01 00:00:00+00:00 \n", + "2 1073932 -16.838022 -148.715736 unknown 2025-04-01 00:00:00+00:00 \n", + "3 1073227 -16.883566 -148.518017 unknown 2025-04-01 00:00:00+00:00 \n", + "4 1073521 -16.900634 -148.443097 unknown 2025-04-01 00:00:00+00:00 \n", "\n", " structure_end_date label_confidence \n", - "0 2021-12-01 00:00:00+00:00 high \n", - "1 NaT high \n", - "2 NaT high \n", - "3 NaT high \n", - "4 NaT high " + "0 NaT low \n", + "1 2020-01-01 00:00:00+00:00 high \n", + "2 2025-04-01 00:00:00+00:00 high \n", + "3 2025-04-01 00:00:00+00:00 high \n", + "4 2025-04-01 00:00:00+00:00 high " ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/events-api.ipynb b/notebooks/usage-guides/events-api.ipynb index 0893d10..556eb4d 100644 --- a/notebooks/usage-guides/events-api.ipynb +++ b/notebooks/usage-guides/events-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "6d37044e-0797-4e84-991a-c13ab9997f59", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -266,6 +275,44 @@ { "cell_type": "code", "execution_count": 10, + "id": "dafd51a8-8370-471e-9a2b-f523351a5b46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 5 entries, 0 to 4\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 5 non-null datetime64[ns, UTC]\n", + " 1 end 5 non-null datetime64[ns, UTC]\n", + " 2 id 5 non-null object \n", + " 3 type 5 non-null object \n", + " 4 position 5 non-null object \n", + " 5 regions 5 non-null object \n", + " 6 bounding_box 5 non-null object \n", + " 7 distances 5 non-null object \n", + " 8 vessel 5 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 5 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 0 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 692.0+ bytes\n" + ] + } + ], + "source": [ + "events_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "id": "33328ed3-e2c0-456c-89d2-e13df6cb6911", "metadata": { "colab": { @@ -326,7 +373,7 @@ " {'start_distance_from_shore_km': 2.0, 'end_dis...\n", " {'id': '9e01144bf-f383-e634-3178-ca7e34477f34'...\n", " None\n", - " {'total_distance_km': 3.4650098660546638, 'ave...\n", + " {'total_distance_km': 3.4650098660546633, 'ave...\n", " None\n", " None\n", " None\n", @@ -389,12 +436,12 @@ " bbbf5d0cfa9639e5eac0130fc2b742e9\n", " fishing\n", " {'lat': 14.9647, 'lon': -17.6039}\n", - " {'mpa': [], 'eez': ['8371'], 'rfmo': ['IWC', '...\n", + " {'mpa': [], 'eez': ['8371'], 'rfmo': ['ACAP', ...\n", " [-17.480231666700007, 14.8685916667, -17.67519...\n", " {'start_distance_from_shore_km': 11.0, 'end_di...\n", " {'id': '7374d1988-87f8-6037-66b4-59854a026efb'...\n", " None\n", - " {'total_distance_km': 93.25349267584731, 'aver...\n", + " {'total_distance_km': 93.2534926758473, 'avera...\n", " None\n", " None\n", " None\n", @@ -430,7 +477,7 @@ "1 {'mpa': ['555651502'], 'eez': ['8371'], 'rfmo'... \n", "2 {'mpa': ['555705172'], 'eez': ['8371'], 'rfmo'... \n", "3 {'mpa': [], 'eez': ['8371'], 'rfmo': ['SRFC', ... \n", - "4 {'mpa': [], 'eez': ['8371'], 'rfmo': ['IWC', '... \n", + "4 {'mpa': [], 'eez': ['8371'], 'rfmo': ['ACAP', ... \n", "\n", " bounding_box \\\n", "0 [-17.4119, 14.686378333333334, -17.41116833333... \n", @@ -454,11 +501,11 @@ "4 {'id': '7374d1988-87f8-6037-66b4-59854a026efb'... None \n", "\n", " fishing gap loitering \\\n", - "0 {'total_distance_km': 3.4650098660546638, 'ave... None None \n", + "0 {'total_distance_km': 3.4650098660546633, 'ave... None None \n", "1 {'total_distance_km': 294.3073276985627, 'aver... None None \n", "2 {'total_distance_km': 130.6216027333083, 'aver... None None \n", "3 {'total_distance_km': 111.11378725724042, 'ave... None None \n", - "4 {'total_distance_km': 93.25349267584731, 'aver... None None \n", + "4 {'total_distance_km': 93.2534926758473, 'avera... None None \n", "\n", " port_visit \n", "0 None \n", @@ -468,7 +515,7 @@ "4 None " ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -489,7 +536,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "7153066a-abe9-4b1a-9751-378f5486ed61", "metadata": { "id": "7153066a-abe9-4b1a-9751-378f5486ed61" @@ -514,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "07f3cec3-752b-494e-be95-f96ff7cda93a", "metadata": { "id": "07f3cec3-752b-494e-be95-f96ff7cda93a" @@ -526,7 +573,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "1598ba96-1e0e-40ce-ade8-c2ccd721cad7", "metadata": { "colab": { @@ -544,7 +591,7 @@ " '8c7304226-6c71-edbe-0b63-c246734b3c01')" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -565,7 +612,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "5924b8c6-da8e-42a9-94ee-9b67ebdb1e7e", "metadata": { "id": "5924b8c6-da8e-42a9-94ee-9b67ebdb1e7e" @@ -577,7 +624,45 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, + "id": "1754d20c-5a9c-42f1-8e02-d10fe24a43c3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 14 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 start 1 non-null datetime64[ns, UTC]\n", + " 1 end 1 non-null datetime64[ns, UTC]\n", + " 2 id 1 non-null object \n", + " 3 type 1 non-null object \n", + " 4 position 1 non-null object \n", + " 5 regions 1 non-null object \n", + " 6 bounding_box 1 non-null object \n", + " 7 distances 1 non-null object \n", + " 8 vessel 1 non-null object \n", + " 9 encounter 0 non-null object \n", + " 10 fishing 0 non-null object \n", + " 11 gap 0 non-null object \n", + " 12 loitering 0 non-null object \n", + " 13 port_visit 1 non-null object \n", + "dtypes: datetime64[ns, UTC](2), object(12)\n", + "memory usage: 244.0+ bytes\n" + ] + } + ], + "source": [ + "event_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "9e6befd3-f970-4a05-b2d0-63ddd4adcfe0", "metadata": { "colab": { @@ -633,7 +718,7 @@ " c2f0967e061f99a01793edac065de003\n", " port_visit\n", " {'lat': 20.7288, 'lon': -17.0148}\n", - " {'mpa': [], 'eez': ['8369'], 'rfmo': ['ICCAT',...\n", + " {'mpa': [], 'eez': ['8369'], 'rfmo': ['NAMMCO'...\n", " [-17.014774393446658, 20.72879719687954, -17.0...\n", " {'start_distance_from_shore_km': 7.0, 'end_dis...\n", " {'id': '8c7304226-6c71-edbe-0b63-c246734b3c01'...\n", @@ -658,7 +743,7 @@ "0 {'lat': 20.7288, 'lon': -17.0148} \n", "\n", " regions \\\n", - "0 {'mpa': [], 'eez': ['8369'], 'rfmo': ['ICCAT',... \n", + "0 {'mpa': [], 'eez': ['8369'], 'rfmo': ['NAMMCO'... \n", "\n", " bounding_box \\\n", "0 [-17.014774393446658, 20.72879719687954, -17.0... \n", @@ -673,7 +758,7 @@ "0 None {'visit_id': '38affb3e7bdc67e9c0c2e7e8f3b08da2... " ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -694,7 +779,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "aacbe1ad-9806-4f83-8d4c-e37d318e1a08", "metadata": { "id": "aacbe1ad-9806-4f83-8d4c-e37d318e1a08" @@ -725,7 +810,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "20bbb945-6c45-4ae9-98c6-029a833f0aeb", "metadata": { "id": "20bbb945-6c45-4ae9-98c6-029a833f0aeb" @@ -737,7 +822,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "24742d8a-d55f-4f1d-8d97-556fb2ec6572", "metadata": { "colab": { @@ -750,10 +835,10 @@ { "data": { "text/plain": [ - "(24750, 1, 197)" + "(24770, 1, 196)" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -774,7 +859,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "bcdf7d04-695c-4bd6-8cbe-6e522339ad58", "metadata": { "id": "bcdf7d04-695c-4bd6-8cbe-6e522339ad58" @@ -786,7 +871,36 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, + "id": "d97c2f90-6414-44f4-b82c-9a92731a18db", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 5 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 num_events 1 non-null int64 \n", + " 1 num_flags 1 non-null int64 \n", + " 2 num_vessels 1 non-null int64 \n", + " 3 flags 1 non-null object\n", + " 4 timeseries 1 non-null object\n", + "dtypes: int64(3), object(2)\n", + "memory usage: 172.0+ bytes\n" + ] + } + ], + "source": [ + "event_stat_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, "id": "0496f743-190f-497c-9433-a4981446c786", "metadata": { "colab": { @@ -828,9 +942,9 @@ " \n", " \n", " 0\n", - " 24750\n", + " 24770\n", " 1\n", - " 197\n", + " 196\n", " [RUS]\n", " [{'date': 2018-01-01 00:00:00+00:00, 'value': ...\n", " \n", @@ -840,13 +954,13 @@ ], "text/plain": [ " num_events num_flags num_vessels flags \\\n", - "0 24750 1 197 [RUS] \n", + "0 24770 1 196 [RUS] \n", "\n", " timeseries \n", "0 [{'date': 2018-01-01 00:00:00+00:00, 'value': ... " ] }, - "execution_count": 20, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 790a793..83e9683 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "6fa3c864-ab80-4dd9-844f-68f167aaeaf2", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -265,6 +274,36 @@ { "cell_type": "code", "execution_count": 9, + "id": "df544af4-bcbf-424a-921b-a8d9b815ea6e", + "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": [ + "insights_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "5dce404d-4318-44da-8811-c4bbc5fefb77", "metadata": { "colab": { @@ -329,7 +368,7 @@ "0 {'datasets': ['public-global-fishing-events:v3... None " ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/references-data-api.ipynb b/notebooks/usage-guides/references-data-api.ipynb index 49fa4c2..c6b31e4 100644 --- a/notebooks/usage-guides/references-data-api.ipynb +++ b/notebooks/usage-guides/references-data-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "b201b300-884d-4ef7-895e-45c025a12962", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -255,6 +264,38 @@ { "cell_type": "code", "execution_count": 10, + "id": "547bf861-ab6f-4362-99c5-ee70041fb6e0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 285 entries, 0 to 284\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 285 non-null int64 \n", + " 1 label 285 non-null object\n", + " 2 iso3 234 non-null object\n", + " 3 dataset 285 non-null object\n", + " 4 isoSov1 285 non-null object\n", + " 5 isoSov2 56 non-null object\n", + " 6 isoSov3 6 non-null object\n", + " 7 territory1 285 non-null object\n", + "dtypes: int64(1), object(7)\n", + "memory usage: 17.9+ KB\n" + ] + } + ], + "source": [ + "eez_regions_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "id": "3d2963b3-6ea1-489c-abdb-aad327ed4875", "metadata": { "colab": { @@ -297,21 +338,21 @@ " 0\n", " 8491\n", " Jordanian Exclusive Economic Zone\n", - " None\n", + " JOR\n", " public-eez-areas\n", " \n", " \n", " 1\n", " 8467\n", " Uruguayan Exclusive Economic Zone\n", - " None\n", + " URY\n", " public-eez-areas\n", " \n", " \n", " 2\n", " 5683\n", " Latvian Exclusive Economic Zone\n", - " None\n", + " LVA\n", " public-eez-areas\n", " \n", " \n", @@ -325,7 +366,7 @@ " 4\n", " 8327\n", " South Korean Exclusive Economic Zone\n", - " None\n", + " KOR\n", " public-eez-areas\n", " \n", " \n", @@ -334,11 +375,11 @@ ], "text/plain": [ " id label iso3 \\\n", - "0 8491 Jordanian Exclusive Economic Zone None \n", - "1 8467 Uruguayan Exclusive Economic Zone None \n", - "2 5683 Latvian Exclusive Economic Zone None \n", + "0 8491 Jordanian Exclusive Economic Zone JOR \n", + "1 8467 Uruguayan Exclusive Economic Zone URY \n", + "2 5683 Latvian Exclusive Economic Zone LVA \n", "3 48950 Overlapping claim Kuril Islands: Japan / Russia None \n", - "4 8327 South Korean Exclusive Economic Zone None \n", + "4 8327 South Korean Exclusive Economic Zone KOR \n", "\n", " dataset \n", "0 public-eez-areas \n", @@ -348,7 +389,7 @@ "4 public-eez-areas " ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -369,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "71915ac9-7cb4-4a11-aee6-0df2ee6f9cd5", "metadata": { "id": "71915ac9-7cb4-4a11-aee6-0df2ee6f9cd5" @@ -391,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "eee11224-fde4-4273-bfa7-da0b2c4bb9a2", "metadata": { "id": "eee11224-fde4-4273-bfa7-da0b2c4bb9a2" @@ -403,7 +444,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "845f42d9-1abe-404c-ae2c-8fc07579a612", "metadata": { "id": "845f42d9-1abe-404c-ae2c-8fc07579a612" @@ -415,7 +456,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "c8254eff-97da-4b10-b48d-bb8eea5845d8", "metadata": { "colab": { @@ -428,10 +469,10 @@ { "data": { "text/plain": [ - "('555790807', 'public-mpa-all')" + "('555799979', 'public-mpa-all')" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -452,7 +493,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "cb8f7439-5cf8-4ab9-88e1-2a84795adbb2", "metadata": { "id": "cb8f7439-5cf8-4ab9-88e1-2a84795adbb2" @@ -464,7 +505,35 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, + "id": "0e111e02-aed8-49fc-bbf4-5fd293bf58d1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 16591 entries, 0 to 16590\n", + "Data columns (total 4 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 16591 non-null object\n", + " 1 label 16591 non-null object\n", + " 2 name 0 non-null object\n", + " 3 dataset 16591 non-null object\n", + "dtypes: object(4)\n", + "memory usage: 518.6+ KB\n" + ] + } + ], + "source": [ + "mpa_regions_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, "id": "0dc3268f-e099-4fe2-821b-f17d579f9d68", "metadata": { "colab": { @@ -506,7 +575,7 @@ " \n", " 0\n", " 1\n", - " Diamond Reef and Salt Fish Tail Reef - Marine ...\n", + " Diamond Reef - Marine Reserve\n", " None\n", " public-mpa-all\n", " \n", @@ -544,14 +613,14 @@ ], "text/plain": [ " id label name dataset\n", - "0 1 Diamond Reef and Salt Fish Tail Reef - Marine ... None public-mpa-all\n", + "0 1 Diamond Reef - Marine Reserve None public-mpa-all\n", "1 2 Palaster Reef - Marine Reserve None public-mpa-all\n", "2 27 Folkstone - Marine Reserve None public-mpa-all\n", "3 46 Reserva Biológica Atol Das Rocas - Reserva Bio... None public-mpa-all\n", "4 57 Parque Nacional Do Cabo Orange - Parque None public-mpa-all" ] }, - "execution_count": 16, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -572,7 +641,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "ac6c6784-e839-44ed-8b47-50c9d7f0a68a", "metadata": { "id": "ac6c6784-e839-44ed-8b47-50c9d7f0a68a" @@ -594,7 +663,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "377f6c90-275f-4dbb-81d2-d1dd43e65fdd", "metadata": { "id": "377f6c90-275f-4dbb-81d2-d1dd43e65fdd" @@ -606,7 +675,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "69605d0f-c97f-4e49-a4f5-d55121e9533a", "metadata": { "id": "69605d0f-c97f-4e49-a4f5-d55121e9533a" @@ -618,7 +687,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "281fe6ca-f993-4158-a225-930173c52550", "metadata": { "colab": { @@ -634,7 +703,7 @@ "('BOBP-IGO', 'public-rfmo')" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -655,7 +724,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "id": "cf0c95fd-911d-4c0a-a663-5430a9c3d073", "metadata": { "id": "cf0c95fd-911d-4c0a-a663-5430a9c3d073" @@ -667,7 +736,36 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, + "id": "abcf14cc-8ddb-4b01-8a58-72885e55d435", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 42 entries, 0 to 41\n", + "Data columns (total 5 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 42 non-null object\n", + " 1 label 42 non-null object\n", + " 2 rfb 0 non-null object\n", + " 3 dataset 42 non-null object\n", + " 4 ID 42 non-null object\n", + "dtypes: object(5)\n", + "memory usage: 1.8+ KB\n" + ] + } + ], + "source": [ + "rfmo_regions_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, "id": "59d334e4-6b8a-469c-b401-72613b42bd68", "metadata": { "colab": { @@ -760,7 +858,7 @@ "4 IPHC IPHC None public-rfmo IPHC" ] }, - "execution_count": 22, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index 6915924..9d7a43e 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -101,6 +101,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "903a49ab-d6c0-4a4c-adf5-11d084edeaf1", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -111,6 +119,7 @@ "outputs": [], "source": [ "import os\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -127,7 +136,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -168,7 +177,6 @@ "source": [ "vessel_search_result = await gfw_client.vessels.search_vessels(\n", " where=\"ssvid='775998121' AND shipname='DON TITO'\",\n", - " datasets=[\"public-global-vessel-identity:latest\"],\n", " includes=[\"MATCH_CRITERIA\", \"OWNERSHIP\"],\n", ")" ] @@ -259,6 +267,38 @@ { "cell_type": "code", "execution_count": 10, + "id": "e7641cd3-b14d-4f6d-8702-26be4400f2e7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 2 entries, 0 to 1\n", + "Data columns (total 8 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 2 non-null object\n", + " 1 registry_info_total_records 2 non-null int64 \n", + " 2 registry_info 2 non-null object\n", + " 3 registry_owners 2 non-null object\n", + " 4 registry_public_authorizations 0 non-null object\n", + " 5 combined_sources_info 2 non-null object\n", + " 6 self_reported_info 2 non-null object\n", + " 7 matchCriteria 2 non-null object\n", + "dtypes: int64(1), object(7)\n", + "memory usage: 260.0+ bytes\n" + ] + } + ], + "source": [ + "vessel_search_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, "id": "9f7237f0-1de2-4a21-834b-b692cf4452b5", "metadata": { "colab": { @@ -349,7 +389,7 @@ "1 [{'reference': 'c54923e64-46f3-9338-9dcb-ff097... " ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -370,7 +410,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "03dbbff9-1768-4e0a-bcea-130ed46f96a0", "metadata": { "id": "03dbbff9-1768-4e0a-bcea-130ed46f96a0" @@ -383,7 +423,6 @@ " \"6583c51e3-3626-5638-866a-f47c3bc7ef7c\",\n", " \"71e7da672-2451-17da-b239-857831602eca\",\n", " ],\n", - " datasets=[\"public-global-vessel-identity:latest\"],\n", ")" ] }, @@ -399,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "a549433e-53ac-4b7c-969a-d6f20af18668", "metadata": { "id": "a549433e-53ac-4b7c-969a-d6f20af18668" @@ -411,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "3778b513-3cfe-49b5-9107-731d2f10d82e", "metadata": { "id": "3778b513-3cfe-49b5-9107-731d2f10d82e" @@ -423,7 +462,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "8c107871-c3eb-4544-bb6c-87188fa68675", "metadata": { "colab": { @@ -436,10 +475,10 @@ { "data": { "text/plain": [ - "('public-global-vessel-identity:v3.0', '55889aefb-bef9-224c-d2db-58ecd01e1d7c')" + "('public-global-vessel-identity:v3.0', 'aca119c29-95dd-f5c4-2057-ee45268dcd6f')" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -460,7 +499,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "d792efd2-c741-41e1-91df-f3822cd7ce46", "metadata": { "id": "d792efd2-c741-41e1-91df-f3822cd7ce46" @@ -472,7 +511,38 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, + "id": "608434ad-151f-4fec-b62b-0c1800427362", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 3 entries, 0 to 2\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 3 non-null object\n", + " 1 registry_info_total_records 3 non-null int64 \n", + " 2 registry_info 3 non-null object\n", + " 3 registry_owners 3 non-null object\n", + " 4 registry_public_authorizations 3 non-null object\n", + " 5 combined_sources_info 3 non-null object\n", + " 6 self_reported_info 3 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 300.0+ bytes\n" + ] + } + ], + "source": [ + "vessels_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, "id": "3da7dec8-4f2b-4db9-aed0-38163d591af0", "metadata": { "colab": { @@ -521,22 +591,12 @@ " [{'id': 'a8d00ce54b37add7f85a35fcce8e7a1b', 's...\n", " [{'name': 'COLINER', 'flag': 'RUS', 'ssvid': '...\n", " [{'date_from': 2023-01-01 00:00:00+00:00, 'dat...\n", - " [{'vessel_id': '3c81a942b-bf0a-f476-ea72-75c02...\n", + " [{'vessel_id': 'da1cd7e1b-b8d0-539c-6581-2b3df...\n", " [{'id': 'da1cd7e1b-b8d0-539c-6581-2b3df8d0a6af...\n", " \n", " \n", " 1\n", " public-global-vessel-identity:v3.0\n", - " 2\n", - " [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's...\n", - " [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ...\n", - " [{'date_from': 2015-10-08 00:00:00+00:00, 'dat...\n", - " [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452...\n", - " [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c...\n", - " \n", - " \n", - " 2\n", - " public-global-vessel-identity:v3.0\n", " 1\n", " [{'id': '685862e0626f6234c844919bc738a83a', 's...\n", " [{'name': 'TRANS PACIFIC JOURNEY FISHING', 'fl...\n", @@ -544,6 +604,16 @@ " [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd...\n", " [{'id': '71e7da672-2451-17da-b239-857831602eca...\n", " \n", + " \n", + " 2\n", + " public-global-vessel-identity:v3.0\n", + " 2\n", + " [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's...\n", + " [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ...\n", + " [{'date_from': 2015-10-08 00:00:00+00:00, 'dat...\n", + " [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452...\n", + " [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c...\n", + " \n", " \n", "\n", "" @@ -551,36 +621,36 @@ "text/plain": [ " dataset registry_info_total_records \\\n", "0 public-global-vessel-identity:v3.0 5 \n", - "1 public-global-vessel-identity:v3.0 2 \n", - "2 public-global-vessel-identity:v3.0 1 \n", + "1 public-global-vessel-identity:v3.0 1 \n", + "2 public-global-vessel-identity:v3.0 2 \n", "\n", " registry_info \\\n", "0 [{'id': 'a8d00ce54b37add7f85a35fcce8e7a1b', 's... \n", - "1 [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's... \n", - "2 [{'id': '685862e0626f6234c844919bc738a83a', 's... \n", + "1 [{'id': '685862e0626f6234c844919bc738a83a', 's... \n", + "2 [{'id': 'b82d02e5c2c11e5fe5367c91194fc3ba', 's... \n", "\n", " registry_owners \\\n", "0 [{'name': 'COLINER', 'flag': 'RUS', 'ssvid': '... \n", - "1 [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ... \n", - "2 [{'name': 'TRANS PACIFIC JOURNEY FISHING', 'fl... \n", + "1 [{'name': 'TRANS PACIFIC JOURNEY FISHING', 'fl... \n", + "2 [{'name': 'DONGWON INDUSTRIES', 'flag': 'KOR, ... \n", "\n", " registry_public_authorizations \\\n", "0 [{'date_from': 2023-01-01 00:00:00+00:00, 'dat... \n", - "1 [{'date_from': 2015-10-08 00:00:00+00:00, 'dat... \n", - "2 [{'date_from': 2012-01-01 00:00:00+00:00, 'dat... \n", + "1 [{'date_from': 2012-01-01 00:00:00+00:00, 'dat... \n", + "2 [{'date_from': 2015-10-08 00:00:00+00:00, 'dat... \n", "\n", " combined_sources_info \\\n", - "0 [{'vessel_id': '3c81a942b-bf0a-f476-ea72-75c02... \n", - "1 [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452... \n", - "2 [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd... \n", + "0 [{'vessel_id': 'da1cd7e1b-b8d0-539c-6581-2b3df... \n", + "1 [{'vessel_id': '55889aefb-bef9-224c-d2db-58ecd... \n", + "2 [{'vessel_id': 'aca119c29-95dd-f5c4-2057-ee452... \n", "\n", " self_reported_info \n", "0 [{'id': 'da1cd7e1b-b8d0-539c-6581-2b3df8d0a6af... \n", - "1 [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c... \n", - "2 [{'id': '71e7da672-2451-17da-b239-857831602eca... " + "1 [{'id': '71e7da672-2451-17da-b239-857831602eca... \n", + "2 [{'id': '6583c51e3-3626-5638-866a-f47c3bc7ef7c... " ] }, - "execution_count": 16, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -601,7 +671,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "id": "5b12f20c-9c0e-40f6-ac13-31ad7e0144ab", "metadata": { "id": "5b12f20c-9c0e-40f6-ac13-31ad7e0144ab" @@ -610,7 +680,6 @@ "source": [ "vessel_result = await gfw_client.vessels.get_vessel_by_id(\n", " id=\"c54923e64-46f3-9338-9dcb-ff09724077a3\",\n", - " dataset=\"public-global-vessel-identity:latest\",\n", ")" ] }, @@ -626,7 +695,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "id": "ba62e001-a8e9-4dac-9674-461f9cff191f", "metadata": { "id": "ba62e001-a8e9-4dac-9674-461f9cff191f" @@ -638,7 +707,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "id": "4bf8c038-2aab-49d9-acfc-86949d265dfb", "metadata": { "colab": { @@ -654,7 +723,7 @@ "('public-global-vessel-identity:v3.0', 'c54923e64-46f3-9338-9dcb-ff09724077a3')" ] }, - "execution_count": 19, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -675,7 +744,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "id": "6f146ff6-f669-466a-b3fc-810a30f14a4d", "metadata": { "id": "6f146ff6-f669-466a-b3fc-810a30f14a4d" @@ -687,7 +756,38 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, + "id": "591d90b1-58ca-4da6-8455-c506953824bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 7 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 dataset 1 non-null object\n", + " 1 registry_info_total_records 1 non-null int64 \n", + " 2 registry_info 1 non-null object\n", + " 3 registry_owners 1 non-null object\n", + " 4 registry_public_authorizations 1 non-null object\n", + " 5 combined_sources_info 1 non-null object\n", + " 6 self_reported_info 1 non-null object\n", + "dtypes: int64(1), object(6)\n", + "memory usage: 188.0+ bytes\n" + ] + } + ], + "source": [ + "vessel_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, "id": "f2b2b97d-bc5b-4dba-a17a-40eb9ada75ab", "metadata": { "colab": { @@ -757,7 +857,7 @@ "0 [{'id': 'c54923e64-46f3-9338-9dcb-ff09724077a3... " ] }, - "execution_count": 21, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } diff --git a/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb b/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb index c37fb6a..765071b 100644 --- a/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb +++ b/notebooks/workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "2532e150-f450-4ae6-b7a1-3433b5f25dac", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -383,41 +392,41 @@ " 0\n", " CHN\n", " TRAWLERS\n", - " 31.888889\n", - " 412444322\n", - " MIN LONG YU61146\n", + " 0.368056\n", + " 412209175\n", + " MENGXIN24\n", " \n", " \n", " 1\n", - " SEN\n", + " ESP\n", " TRAWLERS\n", - " 524.815556\n", - " 663093000\n", - " AMINE\n", + " 1.306389\n", + " 225987981\n", + " CIUDAD DE HUELVA\n", " \n", " \n", " 2\n", " CHN\n", " TRAWLERS\n", - " 0.368056\n", - " 412209175\n", - " MENGXIN24\n", + " 216.545000\n", + " 412549331\n", + " YUAN YU 886\n", " \n", " \n", " 3\n", - " ESP\n", + " SEN\n", " TRAWLERS\n", - " 1.306389\n", - " 225987981\n", - " CIUDAD DE HUELVA\n", + " 612.825556\n", + " 663123000\n", + " ILE AUX OISEAUX\n", " \n", " \n", " 4\n", " CHN\n", " TRAWLERS\n", - " 216.545000\n", - " 412549331\n", - " YUAN YU 886\n", + " 31.888889\n", + " 412444322\n", + " MIN LONG YU61146\n", " \n", " \n", "\n", @@ -425,11 +434,11 @@ ], "text/plain": [ " flag gear_type hours mmsi ship_name\n", - "0 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146\n", - "1 SEN TRAWLERS 524.815556 663093000 AMINE\n", - "2 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", - "3 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", - "4 CHN TRAWLERS 216.545000 412549331 YUAN YU 886" + "0 CHN TRAWLERS 0.368056 412209175 MENGXIN24\n", + "1 ESP TRAWLERS 1.306389 225987981 CIUDAD DE HUELVA\n", + "2 CHN TRAWLERS 216.545000 412549331 YUAN YU 886\n", + "3 SEN TRAWLERS 612.825556 663123000 ILE AUX OISEAUX\n", + "4 CHN TRAWLERS 31.888889 412444322 MIN LONG YU61146" ] }, "execution_count": 8, @@ -785,32 +794,32 @@ " \n", " \n", " 0\n", - " [{'id': '199483471cd2da3717552fddb1a3172a', 's...\n", - " [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...\n", - " [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...\n", - " \n", - " \n", - " 1\n", " [{'id': '29fef17154387858d8d4c777311c57f7', 's...\n", " [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ...\n", " [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e...\n", " \n", + " \n", + " 1\n", + " [{'id': '199483471cd2da3717552fddb1a3172a', 's...\n", + " [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '...\n", + " [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8...\n", + " \n", " \n", "\n", "" ], "text/plain": [ " registry_info \\\n", - "0 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", - "1 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "0 [{'id': '29fef17154387858d8d4c777311c57f7', 's... \n", + "1 [{'id': '199483471cd2da3717552fddb1a3172a', 's... \n", "\n", " registry_owners \\\n", - "0 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", - "1 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "0 [{'name': 'SENEVISA', 'flag': 'ESP', 'ssvid': ... \n", + "1 [{'name': 'ARMEMENT SOPASEN', 'flag': 'SEN', '... \n", "\n", " self_reported_info \n", - "0 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... \n", - "1 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... " + "0 [{'id': 'bf28c5a58-8c83-8690-8689-7f2d520f926e... \n", + "1 [{'id': '894bc3ec6-6ade-f09c-e792-ff2e947508d8... " ] }, "execution_count": 18, @@ -880,16 +889,16 @@ " \n", " \n", " 0\n", - " 663115000\n", + " 663178000\n", " SEN\n", - " BETTY\n", - " BETTY\n", + " NUEVO NOSO LAR\n", + " NUEVONOSOLAR\n", " [TRAWLERS]\n", " [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 1\n", - " 663178000\n", + " 762178000\n", " SEN\n", " NUEVO NOSO LAR\n", " NUEVONOSOLAR\n", @@ -898,7 +907,7 @@ " \n", " \n", " 2\n", - " 762178000\n", + " 552178000\n", " SEN\n", " NUEVO NOSO LAR\n", " NUEVONOSOLAR\n", @@ -907,10 +916,10 @@ " \n", " \n", " 3\n", - " 552178000\n", + " 663115000\n", " SEN\n", - " NUEVO NOSO LAR\n", - " NUEVONOSOLAR\n", + " BETTY\n", + " BETTY\n", " [TRAWLERS]\n", " [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", @@ -920,10 +929,10 @@ ], "text/plain": [ " ssvid flag ship_name n_ship_name gear_types \\\n", - "0 663115000 SEN BETTY BETTY [TRAWLERS] \n", - "1 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", - "2 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", - "3 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "0 663178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "1 762178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "2 552178000 SEN NUEVO NOSO LAR NUEVONOSOLAR [TRAWLERS] \n", + "3 663115000 SEN BETTY BETTY [TRAWLERS] \n", "\n", " source_code \n", "0 [IMO, TMT_NATIONAL, TMT_OTHER_OFFICIAL] \n", @@ -999,37 +1008,37 @@ " \n", " \n", " 0\n", - " 663115000\n", - " SEN\n", - " ARMEMENT SOPASEN\n", + " 663178000\n", + " ESP\n", + " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 1\n", - " 663178000\n", + " 663176000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 2\n", - " 663176000\n", + " 762178000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 3\n", - " 762178000\n", + " 552178000\n", " ESP\n", " SENEVISA\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", " 4\n", - " 552178000\n", - " ESP\n", - " SENEVISA\n", + " 663115000\n", + " SEN\n", + " ARMEMENT SOPASEN\n", " [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", " \n", " \n", @@ -1038,11 +1047,11 @@ ], "text/plain": [ " ssvid flag name source_code\n", - "0 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "1 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "2 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "3 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", - "4 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" + "0 663178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "1 663176000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "2 762178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "3 552178000 ESP SENEVISA [TMT_NATIONAL, TMT_OTHER_OFFICIAL]\n", + "4 663115000 SEN ARMEMENT SOPASEN [TMT_NATIONAL, TMT_OTHER_OFFICIAL]" ] }, "execution_count": 22, @@ -1111,14 +1120,6 @@ " \n", " \n", " 0\n", - " 663115000\n", - " SEN\n", - " BETTY\n", - " BETTY\n", - " [AIS]\n", - " \n", - " \n", - " 1\n", " 663178000\n", " SEN\n", " NUEVONOSOLAR\n", @@ -1126,7 +1127,7 @@ " [AIS]\n", " \n", " \n", - " 2\n", + " 1\n", " 663178000\n", " SEN\n", " NUEVO=NOSOLAR+3&!U.?\n", @@ -1134,7 +1135,7 @@ " [AIS]\n", " \n", " \n", - " 3\n", + " 2\n", " 762178000\n", " None\n", " NUEVO NOSOLAR\n", @@ -1142,7 +1143,7 @@ " [AIS]\n", " \n", " \n", - " 4\n", + " 3\n", " 552178000\n", " None\n", " NUEVO NOSOLAR\n", @@ -1150,25 +1151,33 @@ " [AIS]\n", " \n", " \n", - " 5\n", + " 4\n", " 663178000\n", " SEN\n", " NUEVO NOSOLAR\n", " NUEVONOSOLAR\n", " [AIS]\n", " \n", + " \n", + " 5\n", + " 663115000\n", + " SEN\n", + " BETTY\n", + " BETTY\n", + " [AIS]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name source_code\n", - "0 663115000 SEN BETTY BETTY [AIS]\n", - "1 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", - "2 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", - "3 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", - "4 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", - "5 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]" + "0 663178000 SEN NUEVONOSOLAR NUEVONOSOLAR [AIS]\n", + "1 663178000 SEN NUEVO=NOSOLAR+3&!U.? NUEVONOSOLAR3U [AIS]\n", + "2 762178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "3 552178000 None NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "4 663178000 SEN NUEVO NOSOLAR NUEVONOSOLAR [AIS]\n", + "5 663115000 SEN BETTY BETTY [AIS]" ] }, "execution_count": 24, diff --git a/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb b/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb index 0953cfe..a146cfc 100644 --- a/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb +++ b/notebooks/workflow-guides/workflow-02-analyze-apparent-fishing-effort-argentinian-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "420afe1c-ff77-40e2-9a07-7372dc95170c", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -368,15 +377,15 @@ " \n", " \n", " 0\n", - " inconclusive\n", - " 215.623889\n", - " 2\n", + " pots_and_traps\n", + " 92.029722\n", + " 3\n", " \n", " \n", " 1\n", - " set_longlines\n", - " 17.925833\n", - " 1\n", + " inconclusive\n", + " 215.623889\n", + " 2\n", " \n", " \n", " 2\n", @@ -386,15 +395,15 @@ " \n", " \n", " 3\n", - " other_purse_seines\n", - " 57.377500\n", + " set_longlines\n", + " 17.925833\n", " 1\n", " \n", " \n", " 4\n", - " set_longlines\n", - " 153.960278\n", - " 3\n", + " other_purse_seines\n", + " 57.377500\n", + " 1\n", " \n", " \n", "\n", @@ -402,11 +411,11 @@ ], "text/plain": [ " gear_type hours vessel_ids\n", - "0 inconclusive 215.623889 2\n", - "1 set_longlines 17.925833 1\n", + "0 pots_and_traps 92.029722 3\n", + "1 inconclusive 215.623889 2\n", "2 inconclusive 98.155833 2\n", - "3 other_purse_seines 57.377500 1\n", - "4 set_longlines 153.960278 3" + "3 set_longlines 17.925833 1\n", + "4 other_purse_seines 57.377500 1" ] }, "execution_count": 8, @@ -686,35 +695,35 @@ " \n", " \n", " 0\n", - " URY\n", + " ARG\n", " TRAWLERS\n", - " 10.023056\n", - " 770576463\n", - " KALATXORI\n", + " 714.842500\n", + " 701000882\n", + " FELIX AUGUSTO\n", " \n", " \n", " 1\n", " ARG\n", " TRAWLERS\n", - " 326.160833\n", - " 701079000\n", - " ENTRENA UNO\n", + " 641.522222\n", + " 701000932\n", + " ANTONIO ALVAREZ\n", " \n", " \n", " 2\n", - " ARG\n", + " URY\n", " TRAWLERS\n", - " 714.842500\n", - " 701000882\n", - " FELIX AUGUSTO\n", + " 10.023056\n", + " 770576463\n", + " KALATXORI\n", " \n", " \n", " 3\n", " ARG\n", " TRAWLERS\n", - " 641.522222\n", - " 701000932\n", - " ANTONIO ALVAREZ\n", + " 326.160833\n", + " 701079000\n", + " ENTRENA UNO\n", " \n", " \n", " 4\n", @@ -730,10 +739,10 @@ ], "text/plain": [ " flag gear_type hours mmsi ship_name\n", - "0 URY TRAWLERS 10.023056 770576463 KALATXORI\n", - "1 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", - "2 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", - "3 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "0 ARG TRAWLERS 714.842500 701000882 FELIX AUGUSTO\n", + "1 ARG TRAWLERS 641.522222 701000932 ANTONIO ALVAREZ\n", + "2 URY TRAWLERS 10.023056 770576463 KALATXORI\n", + "3 ARG TRAWLERS 326.160833 701079000 ENTRENA UNO\n", "4 ARG TRAWLERS 295.007500 701000820 CORAJE" ] }, @@ -1090,32 +1099,32 @@ " \n", " \n", " 0\n", - " [{'id': '45502524c9a150e77869ee647423dba1', 's...\n", - " [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...\n", - " [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...\n", - " \n", - " \n", - " 1\n", " [{'id': '2d939efefd3f45788ed103ff0723f564', 's...\n", " [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'...\n", " [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017...\n", " \n", + " \n", + " 1\n", + " [{'id': '45502524c9a150e77869ee647423dba1', 's...\n", + " [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '...\n", + " [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f...\n", + " \n", " \n", "\n", "" ], "text/plain": [ " registry_info \\\n", - "0 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", - "1 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "0 [{'id': '2d939efefd3f45788ed103ff0723f564', 's... \n", + "1 [{'id': '45502524c9a150e77869ee647423dba1', 's... \n", "\n", " registry_owners \\\n", - "0 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", - "1 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "0 [{'name': 'CLEARWATER SEAFOODS', 'flag': 'CAN'... \n", + "1 [{'name': 'GLACIAR PESQUERA', 'flag': 'ARG', '... \n", "\n", " self_reported_info \n", - "0 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... \n", - "1 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... " + "0 [{'id': 'de8a03acd-dc6c-8e08-2867-24e55ffc0017... \n", + "1 [{'id': '8e930bac5-594b-aa3f-081d-d12668819e1f... " ] }, "execution_count": 24, @@ -1185,15 +1194,6 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " ATLANTIC SURF III\n", - " ATLANTICSURF3\n", - " [TRAWLERS]\n", - " [IMO, TMT_OTHER_OFFICIAL]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " ARG\n", " CAPESANTE\n", @@ -1202,7 +1202,7 @@ " [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF...\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " ATLANTICLEADER\n", @@ -1210,19 +1210,28 @@ " [TRAWLERS]\n", " [IMO, TMT_OTHER_OFFICIAL]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " ATLANTIC SURF III\n", + " ATLANTICSURF3\n", + " [TRAWLERS]\n", + " [IMO, TMT_OTHER_OFFICIAL]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name gear_types \\\n", - "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", - "1 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", - "2 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "0 701006605 ARG CAPESANTE CAPESANTE [TRAWLERS] \n", + "1 316003980 CAN ATLANTICLEADER ATLANTICLEADER [TRAWLERS] \n", + "2 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [TRAWLERS] \n", "\n", " source_code \n", - "0 [IMO, TMT_OTHER_OFFICIAL] \n", - "1 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "0 [GFW-REVIEW, IMO, RESEARCH-PAPER, TMT_OTHER_OF... \n", + "1 [IMO, TMT_OTHER_OFFICIAL] \n", "2 [IMO, TMT_OTHER_OFFICIAL] " ] }, @@ -1293,34 +1302,34 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " GLACIAR PESQUERA\n", - " [TMT_OTHER_OFFICIAL]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " CAN\n", " CLEARWATER SEAFOODS\n", " [RESEARCH-PAPER]\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " CS MANPAR\n", " [TMT_OTHER_OFFICIAL]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " GLACIAR PESQUERA\n", + " [TMT_OTHER_OFFICIAL]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag name source_code\n", - "0 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]\n", - "1 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", - "2 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]" + "0 701006605 CAN CLEARWATER SEAFOODS [RESEARCH-PAPER]\n", + "1 316003980 CAN CS MANPAR [TMT_OTHER_OFFICIAL]\n", + "2 701024000 ARG GLACIAR PESQUERA [TMT_OTHER_OFFICIAL]" ] }, "execution_count": 28, @@ -1389,14 +1398,6 @@ " \n", " \n", " 0\n", - " 701024000\n", - " ARG\n", - " ATLANTIC SURF III\n", - " ATLANTICSURF3\n", - " [AIS]\n", - " \n", - " \n", - " 1\n", " 701006605\n", " ARG\n", " CAPESANTE\n", @@ -1404,22 +1405,30 @@ " [AIS]\n", " \n", " \n", - " 2\n", + " 1\n", " 316003980\n", " CAN\n", " ATLANTIC LEADER\n", " ATLANTICLEADER\n", " [AIS]\n", " \n", + " \n", + " 2\n", + " 701024000\n", + " ARG\n", + " ATLANTIC SURF III\n", + " ATLANTICSURF3\n", + " [AIS]\n", + " \n", " \n", "\n", "" ], "text/plain": [ " ssvid flag ship_name n_ship_name source_code\n", - "0 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]\n", - "1 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", - "2 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]" + "0 701006605 ARG CAPESANTE CAPESANTE [AIS]\n", + "1 316003980 CAN ATLANTIC LEADER ATLANTICLEADER [AIS]\n", + "2 701024000 ARG ATLANTIC SURF III ATLANTICSURF3 [AIS]" ] }, "execution_count": 30, @@ -1689,36 +1698,36 @@ " 0\n", " ATLANTIC SURF III\n", " 701024000\n", - " 117.545450\n", - " 4.351747\n", + " 222.721610\n", + " 4.098386\n", " \n", " \n", " 1\n", " ATLANTIC SURF III\n", " 701024000\n", - " 10.408851\n", - " 3.791667\n", + " 7.905335\n", + " 4.590909\n", " \n", " \n", " 2\n", " ATLANTIC SURF III\n", " 701024000\n", - " 61.366911\n", - " 4.448980\n", + " 2.794681\n", + " 4.655555\n", " \n", " \n", " 3\n", " ATLANTIC SURF III\n", " 701024000\n", - " 92.180704\n", - " 4.485407\n", + " 2.012392\n", + " 2.953846\n", " \n", " \n", " 4\n", " ATLANTIC SURF III\n", " 701024000\n", - " 974.761871\n", - " 4.051429\n", + " 3.260040\n", + " 3.705556\n", " \n", " \n", " ...\n", @@ -1731,36 +1740,36 @@ " 346\n", " CAPESANTE\n", " 701006605\n", - " 95.128059\n", - " 4.202542\n", + " 25.568796\n", + " 4.074561\n", " \n", " \n", " 347\n", " CAPESANTE\n", " 701006605\n", - " 205.826282\n", - " 4.136848\n", + " 45.830980\n", + " 3.771852\n", " \n", " \n", " 348\n", " CAPESANTE\n", " 701006605\n", - " 369.336603\n", - " 3.938255\n", + " 74.611830\n", + " 4.087912\n", " \n", " \n", " 349\n", - " ATLANTIC SURF III\n", - " 701024000\n", - " 256.908842\n", - " 4.186333\n", + " CAPESANTE\n", + " 701006605\n", + " 82.607525\n", + " 3.788187\n", " \n", " \n", " 350\n", " CAPESANTE\n", " 701006605\n", - " 208.071985\n", - " 3.971505\n", + " 205.826282\n", + " 4.136848\n", " \n", " \n", "\n", @@ -1769,17 +1778,17 @@ ], "text/plain": [ " name ssvid total_distance_km average_speed_knots\n", - "0 ATLANTIC SURF III 701024000 117.545450 4.351747\n", - "1 ATLANTIC SURF III 701024000 10.408851 3.791667\n", - "2 ATLANTIC SURF III 701024000 61.366911 4.448980\n", - "3 ATLANTIC SURF III 701024000 92.180704 4.485407\n", - "4 ATLANTIC SURF III 701024000 974.761871 4.051429\n", + "0 ATLANTIC SURF III 701024000 222.721610 4.098386\n", + "1 ATLANTIC SURF III 701024000 7.905335 4.590909\n", + "2 ATLANTIC SURF III 701024000 2.794681 4.655555\n", + "3 ATLANTIC SURF III 701024000 2.012392 2.953846\n", + "4 ATLANTIC SURF III 701024000 3.260040 3.705556\n", ".. ... ... ... ...\n", - "346 CAPESANTE 701006605 95.128059 4.202542\n", - "347 CAPESANTE 701006605 205.826282 4.136848\n", - "348 CAPESANTE 701006605 369.336603 3.938255\n", - "349 ATLANTIC SURF III 701024000 256.908842 4.186333\n", - "350 CAPESANTE 701006605 208.071985 3.971505\n", + "346 CAPESANTE 701006605 25.568796 4.074561\n", + "347 CAPESANTE 701006605 45.830980 3.771852\n", + "348 CAPESANTE 701006605 74.611830 4.087912\n", + "349 CAPESANTE 701006605 82.607525 3.788187\n", + "350 CAPESANTE 701006605 205.826282 4.136848\n", "\n", "[351 rows x 4 columns]" ] @@ -1975,15 +1984,6 @@ " \n", " \n", " 2\n", - " CAPESANTE\n", - " 701006605\n", - " 4\n", - " USHUAIA\n", - " USHUAIA\n", - " USHUAIA\n", - " \n", - " \n", - " 3\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -1992,7 +1992,7 @@ " MAR DEL PLATA\n", " \n", " \n", - " 4\n", + " 3\n", " CAPESANTE\n", " 701006605\n", " 4\n", @@ -2001,7 +2001,7 @@ " USHUAIA\n", " \n", " \n", - " 5\n", + " 4\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -2010,7 +2010,7 @@ " MAR DEL PLATA\n", " \n", " \n", - " 6\n", + " 5\n", " CAPESANTE\n", " 701006605\n", " 4\n", @@ -2019,7 +2019,7 @@ " USHUAIA\n", " \n", " \n", - " 7\n", + " 6\n", " ATLANTIC SURF III\n", " 701024000\n", " 4\n", @@ -2027,6 +2027,15 @@ " MAR DEL PLATA\n", " MAR DEL PLATA\n", " \n", + " \n", + " 7\n", + " CAPESANTE\n", + " 701006605\n", + " 4\n", + " USHUAIA\n", + " USHUAIA\n", + " USHUAIA\n", + " \n", " \n", "\n", "" @@ -2035,22 +2044,22 @@ " name ssvid confidence start_anchorage_name \\\n", "0 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", "1 CAPESANTE 701006605 4 USHUAIA \n", - "2 CAPESANTE 701006605 4 USHUAIA \n", - "3 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", - "4 CAPESANTE 701006605 4 USHUAIA \n", - "5 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", - "6 CAPESANTE 701006605 4 USHUAIA \n", - "7 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "2 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "3 CAPESANTE 701006605 4 USHUAIA \n", + "4 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "5 CAPESANTE 701006605 4 USHUAIA \n", + "6 ATLANTIC SURF III 701024000 4 MAR DEL PLATA \n", + "7 CAPESANTE 701006605 4 USHUAIA \n", "\n", " intermediate_anchorage_name end_anchorage_name \n", "0 MAR DEL PLATA MAR DEL PLATA \n", "1 USHUAIA USHUAIA \n", - "2 USHUAIA USHUAIA \n", - "3 MAR DEL PLATA MAR DEL PLATA \n", - "4 USHUAIA USHUAIA \n", - "5 MAR DEL PLATA MAR DEL PLATA \n", - "6 USHUAIA USHUAIA \n", - "7 MAR DEL PLATA MAR DEL PLATA " + "2 MAR DEL PLATA MAR DEL PLATA \n", + "3 USHUAIA USHUAIA \n", + "4 MAR DEL PLATA MAR DEL PLATA \n", + "5 USHUAIA USHUAIA \n", + "6 MAR DEL PLATA MAR DEL PLATA \n", + "7 USHUAIA USHUAIA " ] }, "execution_count": 43, diff --git a/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb b/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb index a894429..76f7033 100644 --- a/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb +++ b/notebooks/workflow-guides/workflow-03-analyze-fleet-in-ghanaian-eez.ipynb @@ -82,6 +82,14 @@ "## Usage" ] }, + { + "cell_type": "markdown", + "id": "53f445b9-02bb-425a-817a-2768941c7d5a", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -90,8 +98,9 @@ "outputs": [], "source": [ "import os\n", - "import datetime\n", + "\n", "import pandas as pd\n", + "\n", "import gfwapiclient as gfw" ] }, @@ -106,7 +115,7 @@ " from google.colab import userdata\n", "\n", " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", - "except Exception as exc:\n", + "except Exception:\n", " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", "\n", "access_token = access_token or \"\"" @@ -372,23 +381,23 @@ " \n", " 2\n", " None\n", - " fishing\n", - " 20929.563333\n", - " 21\n", + " pole_and_line\n", + " 3481.509167\n", + " 5\n", " \n", " \n", " 3\n", " None\n", - " inconclusive\n", - " 30496.173611\n", - " 27\n", + " other_purse_seines\n", + " 26.581111\n", + " 1\n", " \n", " \n", " 4\n", " None\n", - " pole_and_line\n", - " 3481.509167\n", - " 5\n", + " fishing\n", + " 20929.563333\n", + " 21\n", " \n", " \n", "\n", @@ -398,9 +407,9 @@ " flag gear_type hours vessel_ids\n", "0 None drifting_longlines 593.138333 3\n", "1 None purse_seines 6.340556 1\n", - "2 None fishing 20929.563333 21\n", - "3 None inconclusive 30496.173611 27\n", - "4 None pole_and_line 3481.509167 5" + "2 None pole_and_line 3481.509167 5\n", + "3 None other_purse_seines 26.581111 1\n", + "4 None fishing 20929.563333 21" ] }, "execution_count": 8, @@ -1578,36 +1587,36 @@ " 0\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 18.481056\n", - " 8.841667\n", + " 44.026882\n", + " 3.808824\n", " \n", " \n", " 1\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 34.867559\n", - " 8.240000\n", + " 9.353500\n", + " 8.200000\n", " \n", " \n", " 2\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 11.086850\n", - " 8.208333\n", + " 9.868050\n", + " 5.494444\n", " \n", " \n", " 3\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 12.699650\n", - " 8.266667\n", + " 10.955310\n", + " 8.555556\n", " \n", " \n", " 4\n", " HUNG CHUAN SHUN\n", " 416007496\n", - " 56.788034\n", - " 6.248000\n", + " 9.630687\n", + " 8.942857\n", " \n", " \n", " ...\n", @@ -1618,38 +1627,38 @@ " \n", " \n", " 409\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 12.164494\n", - " 5.083333\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 101.402263\n", + " 4.041791\n", " \n", " \n", " 410\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 13.191124\n", - " 3.986957\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 115.642159\n", + " 4.743357\n", " \n", " \n", " 411\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 8.685659\n", - " 3.850000\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 100.019456\n", + " 4.402564\n", " \n", " \n", " 412\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 15.721987\n", - " 3.686667\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 155.923138\n", + " 4.975000\n", " \n", " \n", " 413\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 28.553779\n", - " 3.728571\n", + " HUNG CHUAN SHUN\n", + " 416007496\n", + " 173.253137\n", + " 4.869231\n", " \n", " \n", "\n", @@ -1657,18 +1666,18 @@ "" ], "text/plain": [ - " name ssvid total_distance_km average_speed_knots\n", - "0 HUNG CHUAN SHUN 416007496 18.481056 8.841667\n", - "1 HUNG CHUAN SHUN 416007496 34.867559 8.240000\n", - "2 HUNG CHUAN SHUN 416007496 11.086850 8.208333\n", - "3 HUNG CHUAN SHUN 416007496 12.699650 8.266667\n", - "4 HUNG CHUAN SHUN 416007496 56.788034 6.248000\n", - ".. ... ... ... ...\n", - "409 SENSHU MARU NO.3 431100690 12.164494 5.083333\n", - "410 SENSHU MARU NO.3 431100690 13.191124 3.986957\n", - "411 SENSHU MARU NO.3 431100690 8.685659 3.850000\n", - "412 SENSHU MARU NO.3 431100690 15.721987 3.686667\n", - "413 SENSHU MARU NO.3 431100690 28.553779 3.728571\n", + " name ssvid total_distance_km average_speed_knots\n", + "0 HUNG CHUAN SHUN 416007496 44.026882 3.808824\n", + "1 HUNG CHUAN SHUN 416007496 9.353500 8.200000\n", + "2 HUNG CHUAN SHUN 416007496 9.868050 5.494444\n", + "3 HUNG CHUAN SHUN 416007496 10.955310 8.555556\n", + "4 HUNG CHUAN SHUN 416007496 9.630687 8.942857\n", + ".. ... ... ... ...\n", + "409 HUNG CHUAN SHUN 416007496 101.402263 4.041791\n", + "410 HUNG CHUAN SHUN 416007496 115.642159 4.743357\n", + "411 HUNG CHUAN SHUN 416007496 100.019456 4.402564\n", + "412 HUNG CHUAN SHUN 416007496 155.923138 4.975000\n", + "413 HUNG CHUAN SHUN 416007496 173.253137 4.869231\n", "\n", "[414 rows x 4 columns]" ] @@ -1847,6 +1856,15 @@ " \n", " \n", " 0\n", + " SENSHU MARU NO.3\n", + " 431100690\n", + " 4\n", + " TEMA\n", + " TEMA\n", + " TEMA\n", + " \n", + " \n", + " 1\n", " HUNG CHUAN SHUN\n", " 416007496\n", " 4\n", @@ -1855,7 +1873,7 @@ " TEMA\n", " \n", " \n", - " 1\n", + " 2\n", " SENSHU MARU NO.3\n", " 431100690\n", " 4\n", @@ -1864,7 +1882,7 @@ " TEMA\n", " \n", " \n", - " 2\n", + " 3\n", " None\n", " 412331032\n", " 4\n", @@ -1872,31 +1890,22 @@ " DAKAR\n", " DAKAR\n", " \n", - " \n", - " 3\n", - " SENSHU MARU NO.3\n", - " 431100690\n", - " 4\n", - " TEMA\n", - " TEMA\n", - " TEMA\n", - " \n", " \n", "\n", "" ], "text/plain": [ " name ssvid confidence start_anchorage_name \\\n", - "0 HUNG CHUAN SHUN 416007496 4 TEMA \n", - "1 SENSHU MARU NO.3 431100690 4 TEMA \n", - "2 None 412331032 4 DAKAR \n", - "3 SENSHU MARU NO.3 431100690 4 TEMA \n", + "0 SENSHU MARU NO.3 431100690 4 TEMA \n", + "1 HUNG CHUAN SHUN 416007496 4 TEMA \n", + "2 SENSHU MARU NO.3 431100690 4 TEMA \n", + "3 None 412331032 4 DAKAR \n", "\n", " intermediate_anchorage_name end_anchorage_name \n", "0 TEMA TEMA \n", "1 TEMA TEMA \n", - "2 DAKAR DAKAR \n", - "3 TEMA TEMA " + "2 TEMA TEMA \n", + "3 DAKAR DAKAR " ] }, "execution_count": 39, diff --git a/pyproject.toml b/pyproject.toml index f33e3b3..ffaaa5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,7 @@ dependencies = [ [project.optional-dependencies] # Linting and code quality tools lint = [ - "black>=25.9.0", # Code formatting tool + "black[jupyter]>=25.9.0", # Code formatting tool "isort>=7.0.0", # Python imports sorting tool "mypy>=1.18.2", # Static type checker "pydocstyle>=6.3.0", # Python docstring style checker From 74fe51fdb16b21d2095595f0776177878460acb3 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Sun, 11 Jan 2026 02:49:54 +0300 Subject: [PATCH 18/22] docs(bulk-downloads): add api usage guides and jupyter notebooks --- docs/source/getting-started.md | 2 +- docs/source/index.md | 1 + docs/source/usage-guides/4wings-api.md | 1 + .../source/usage-guides/bulk-downloads-api.md | 380 +++++ docs/source/usage-guides/datasets-api.md | 1 + docs/source/usage-guides/events-api.md | 1 + docs/source/usage-guides/index.md | 1 + docs/source/usage-guides/insights-api.md | 3 +- .../usage-guides/references-data-api.md | 1 + docs/source/usage-guides/vessels-api.md | 1 + .../usage-guides/bulk-downloads-api.ipynb | 1409 +++++++++++++++++ 11 files changed, 1799 insertions(+), 2 deletions(-) create mode 100644 docs/source/usage-guides/bulk-downloads-api.md create mode 100644 notebooks/usage-guides/bulk-downloads-api.ipynb diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index f393894..32ae523 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -231,6 +231,6 @@ memory usage: 43.7+ KB This guide has provided you with the fundamental steps to install and use the `gfw-api-python-client` for making basic API requests. -To further explore the capabilities of our APIs (`4Wings`, `Vessels`, `Events`, `Insights`, `Datasets`, `References`, etc.), please refer to the detailed [Usage Guides](usage-guides/index) and [Workflow Guides](workflow-guides/index). These guides delve into specific use cases and demonstrate how to effectively leverage the `gfw-api-python-client` for your data exploration needs. +To further explore the capabilities of our APIs (`4Wings`, `Vessels`, `Events`, `Insights`, `Datasets`, `Bulk Download`, `References`, etc.), please refer to the detailed [Usage Guides](usage-guides/index) and [Workflow Guides](workflow-guides/index). These guides delve into specific use cases and demonstrate how to effectively leverage the `gfw-api-python-client` for your data exploration needs. Happy coding and data exploring! diff --git a/docs/source/index.md b/docs/source/index.md index 188bcd3..b857b62 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -49,6 +49,7 @@ To learn about how to use `gfw-api-python-client`, check out the following resou - [Events API](usage-guides/events-api) - [Insights API](usage-guides/insights-api) - [Datasets API](usage-guides/datasets-api) + - [Bulk Download API](usage-guides/bulk-downloads-api) - [References Data API](usage-guides/references-data-api) - [Workflow Guides](workflow-guides/index) - [Analyze apparent fishing effort in Senegalese EEZ](workflow-guides/workflow-01-analyze-apparent-fishing-effort-senegalese-eez) diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index ec6a85f..2fc50c1 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -384,4 +384,5 @@ Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index - [Events API](events-api) - [Insights API](insights-api) - [Datasets API](datasets-api) +- [Bulk Download API](bulk-downloads-api) - [Reference Data API](references-data-api) diff --git a/docs/source/usage-guides/bulk-downloads-api.md b/docs/source/usage-guides/bulk-downloads-api.md new file mode 100644 index 0000000..a9c744f --- /dev/null +++ b/docs/source/usage-guides/bulk-downloads-api.md @@ -0,0 +1,380 @@ +# Bulk Download API + +Open In Colab + +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the [Bulk Download API](https://globalfishingwatch.org/our-apis/documentation#bulk-download-api), which is designed to support workflows that require bulk access to data, including integration with platforms and tools used by data engineers and researchers. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/bulk-downloads-api.ipynb) version of this guide with more usage examples. + +> **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats), 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 + +- Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](../getting-started) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens). + +## Getting Started + +To interact with the 4Wings endpoints, you first need to instantiate the `gfw.Client` and then access the `fourwings` resource: + +```python +import time +import os + +import gfwapiclient as gfw + + +access_token = os.environ.get( + "GFW_API_ACCESS_TOKEN", + "", +) + +gfw_client = gfw.Client( + access_token=access_token, +) +``` + +The `gfw_client.bulk_downloads` object provides methods to: + +- Create bulk reports based on specific filters and spatial parameters. +- Monitor previously created bulk report generation status. +- Get signed URL to download previously created bulk report data, metadata and + region geometry (in GeoJSON format) files. +- Query previously created bulk report data records in JSON format. + +These methods return a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. + +## Create a Bulk Report (`create_bulk_report`) + +The `create_bulk_report()` method allows you create a bulk report based on specified filters and spatial parameters. The `name` parameter is mandatory. Please [learn more about create a bulk report here](https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). + +```python +timestamp = int(time.time() * 1000) +dataset = "public-fixed-infrastructure-data:latest" +region_dataset = "public-eez-areas" +region_id = "8466" # Argentinian Exclusive Economic Zone +name = f"{dataset.split(':')[0]}_{region_dataset}__{region_id}_{timestamp}" + +create_bulk_report_result = await gfw_client.bulk_downloads.create_bulk_report( + name=name, + dataset=dataset, + region={ + "dataset": region_dataset, + "id": region_id, + }, + filters=["label = 'oil'", "label_confidence = 'high'"], +) +``` + +### Access Create a Bulk Report Result as Pydantic models + +```python +create_bulk_report_data = create_bulk_report_result.data() +print(( + create_bulk_report_data.id, + create_bulk_report_data.name, + create_bulk_report_data.status, + create_bulk_report_data.created_at, +)) +``` + +**Output:** + +``` +('c5e32895-4374-41d2-8b2e-ac414ed6757f', + 'public-fixed-infrastructure-data_public-eez-areas__8466_1768085547174', + 'pending', + datetime.datetime(2026, 1, 10, 22, 52, 30, 9000, tzinfo=TzInfo(0))) +``` + +### Access Create a Bulk Report Result as a DataFrame + +```python +create_bulk_report_df = create_bulk_report_result.df() + +print(create_bulk_report_df.info()) +print(create_bulk_report_df.head()) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 12 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 id 1 non-null object + 1 name 1 non-null object + 2 file_path 1 non-null object + 3 format 1 non-null object + 4 filters 1 non-null object + 5 geom 1 non-null object + 6 status 1 non-null object + 7 owner_id 1 non-null int64 + 8 owner_type 1 non-null object + 9 created_at 1 non-null datetime64[ns, UTC] + 10 updated_at 1 non-null datetime64[ns, UTC] + 11 file_size 0 non-null object +dtypes: datetime64[ns, UTC](2), int64(1), object(9) +memory usage: 228.0+ bytes +``` + +## Get Bulk Report by ID (`get_bulk_report_by_id`) + +The `get_bulk_report_by_id()` method allows you retrieves metadata and status of the previously created bulk report based on the provided bulk report ID. The `id` parameter is mandatory. Please [learn more about get bulk report by id report here](https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). + +> **Important:** We recommend to use this method to poll the status of previously created bulk report, if it takes **several minutes or hours** to generate until it status is `done` or `failed`. + +```python +bulk_report_result = await gfw_client.bulk_downloads.get_bulk_report_by_id( + id=create_bulk_report_data.id +) +``` + +### Access Get Bulk Report by ID Result as Pydantic models + +```python +bulk_report_data = bulk_report_result.data() + +print(( + create_bulk_report_data.id, + create_bulk_report_data.name, + create_bulk_report_data.status, + create_bulk_report_data.created_at, +)) +``` + +**Output:** + +``` +('c5e32895-4374-41d2-8b2e-ac414ed6757f', + 'public-fixed-infrastructure-data_public-eez-areas__8466_1768085547174', + 'pending', + datetime.datetime(2026, 1, 10, 22, 52, 30, 9000, tzinfo=TzInfo(0))) +``` + +### Access Get Bulk Report by ID Result as a DataFrame + +```python +bulk_report_df = bulk_report_result.df() + +print(bulk_report_df.info()) +print(bulk_report_df.head()) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 12 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 id 1 non-null object + 1 name 1 non-null object + 2 file_path 1 non-null object + 3 format 1 non-null object + 4 filters 1 non-null object + 5 geom 1 non-null object + 6 status 1 non-null object + 7 owner_id 1 non-null int64 + 8 owner_type 1 non-null object + 9 created_at 1 non-null datetime64[ns, UTC] + 10 updated_at 1 non-null datetime64[ns, UTC] + 11 file_size 0 non-null object +dtypes: datetime64[ns, UTC](2), int64(1), object(9) +memory usage: 228.0+ bytes +``` + +## Get All Bulk Reports Created by User or Application (`get_all_bulk_reports`) + +The `get_all_bulk_reports()` method allows you retrieves a list of **metadata and status** of the previously created bulk reports based on specified pagination, sorting, and filtering criteria. Please [learn more about get all bulk reports created by user or application here](https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). + +```python +bulk_reports_result = await gfw_client.bulk_downloads.get_all_bulk_reports( + status="done", +) +``` + +### Access All Created Bulk Reports Result as Pydantic models + +```python +bulk_reports_data = bulk_reports_result.data() +bulk_report_item = bulk_reports_data[-1] + +print(( + bulk_report_item.id, + bulk_report_item.name, + bulk_report_item.status, + bulk_report_item.created_at, +)) +``` + +**Output:** + +``` +('0c0cada1-72dd-4fb0-bdf6-7fe8c7fdb1e3', + 'sar-fixed-infrastructure-data-20241207-region-1', + 'done', + datetime.datetime(2025, 12, 7, 10, 3, 12, 371000, tzinfo=TzInfo(0))) +``` + +### Access All Created Bulk Reports Result as a DataFrame + +```python +bulk_reports_df = bulk_reports_result.df() + +print(bulk_reports_df.info()) +print(bulk_reports_df.head()) +``` + +**Output:** + +``` + +RangeIndex: 7 entries, 0 to 6 +Data columns (total 12 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 id 7 non-null object + 1 name 7 non-null object + 2 file_path 7 non-null object + 3 format 7 non-null object + 4 filters 7 non-null object + 5 geom 4 non-null object + 6 status 7 non-null object + 7 owner_id 7 non-null int64 + 8 owner_type 7 non-null object + 9 created_at 7 non-null datetime64[ns, UTC] + 10 updated_at 7 non-null datetime64[ns, UTC] + 11 file_size 7 non-null float64 +dtypes: datetime64[ns, UTC](2), float64(1), int64(1), object(8) +memory usage: 804.0+ bytes +``` + +## Get Bulk Report File Download URL (`get_bulk_report_file_download_url`) + +The `get_bulk_report_file_download_url()` method allows you retrieves **signed URL** that points to a **downloadable file** hosted on Global Fishing Watch's cloud infrastructure to **download file(s)** (i.e., `"DATA"`, `"README"`, or `"GEOM"`) of the previously created bulk report. The `id` parameter is mandatory. Please [learn more about get bulk report file download url here](https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). + +```python +bulk_report_file_download_url_result = ( + await gfw_client.bulk_downloads.get_bulk_report_file_download_url( + id=bulk_reports_data[0].id, file="DATA" + ) +) +``` + +### Access Get Bulk Report File Download URL Result as Pydantic models + +```python +bulk_report_file_download_url_data = bulk_report_file_download_url_result.data() + +print(bulk_report_file_download_url_data.url) +``` + +**Output:** + +``` +'https://storage.googleapis.com/gfw-api-bulk-pro-us-central1/705f2f9a-f695-43f1-a4bf-7746f3deb091/data.json.gz?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=api-bulk-pro%40gfw-production.iam.gserviceaccount.com%2F20260110%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260110T225232Z&X-Goog-Expires=60&X-Goog-SignedHeaders=host&X-Goog-Signature=481a4ff7244b7286f303b37bb7941c291a26d1e3502debdb7611b8cb2d5edf37bc7aa0287b15a11c2f69f72e88791da3f76873a2fd7d08f911691c35ee8e095b825615510de8256f8cd275211997141e026837e118d86e01c026c457dc1f47d43ff2cb07131c3d21e7908c847bf1e3d87cd4773f02e8e4512a7c15e93799de186b9ea004be50cd3e53292f01e9393595a81c42cc3686f65d280f4f16076759da4722c17c2a6a698393c919cdd083402421a1bbf425b618244b3a9b30e48b770a9dc7f9eed8e63af04f8e31f0b6723fdf76fa7262ded89e7a375fbaea3b031bf29db22b1961878facd79c92d633ab6aa2309c0ce3982104d9835058ecd829bee8' +``` + +### Access Get Bulk Report File Download URL Result as a DataFrame + +```python +bulk_report_file_download_url_df = bulk_report_file_download_url_result.df() + +print(bulk_report_file_download_url_df.info()) +print(bulk_report_file_download_url_df.iloc[0]["url"]) +``` + +**Output:** + +``` + +RangeIndex: 1 entries, 0 to 0 +Data columns (total 1 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 url 1 non-null object +dtypes: object(1) +memory usage: 140.0+ bytes +``` + +## Query Bulk Fixed Infrastructure Data Report (`query_bulk_fixed_infrastructure_data_report`) + +The `query_bulk_fixed_infrastructure_data_report()` method allows you retrieves **data records** of a previously created **fixed infrastructure data** (i.e., `public-fixed-infrastructure-data:latest` dataset) bulk report data in JSON format based on specified pagination, sorting, and including criteria. The `id` parameter is mandatory. Please [learn more about query bulk fixed infrastructure data report in JSON format here](https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). + +```python +bulk_fixed_infrastructure_data_report_result = ( + await gfw_client.bulk_downloads.query_bulk_fixed_infrastructure_data_report( + id=bulk_reports_data[0].id + ) +) +``` + +### Access Query Bulk Fixed Infrastructure Data Report Result as Pydantic models + +```python +bulk_fixed_infrastructure_data_report_data = ( + bulk_fixed_infrastructure_data_report_result.data() +) + +bulk_fixed_infrastructure_data_report_item = bulk_fixed_infrastructure_data_report_data[ + -1 +] + +print(( + bulk_fixed_infrastructure_data_report_item.structure_id, + bulk_fixed_infrastructure_data_report_item.lat, + bulk_fixed_infrastructure_data_report_item.lon, + bulk_fixed_infrastructure_data_report_item.label, + bulk_fixed_infrastructure_data_report_item.label_confidence, +)) +``` + +**Output:** + +``` +('1051638', -53.0895574340617, -67.32289149541135, 'oil', 'high') +``` + +### Access Query Bulk Fixed Infrastructure Data Report Result as a DataFrame + +```python +bulk_fixed_infrastructure_data_report_result_df = ( + bulk_fixed_infrastructure_data_report_result.df() +) + +print(bulk_fixed_infrastructure_data_report_result_df.info()) +print(bulk_fixed_infrastructure_data_report_result_df.head()) +``` + +**Output:** + +``` + +RangeIndex: 1238 entries, 0 to 1237 +Data columns (total 9 columns): + # Column Non-Null Count Dtype +--- ------ -------------- ----- + 0 detection_id 1237 non-null object + 1 detection_date 1238 non-null datetime64[ns] + 2 structure_id 1238 non-null object + 3 lat 1238 non-null float64 + 4 lon 1238 non-null float64 + 5 structure_start_date 1238 non-null datetime64[ns] + 6 structure_end_date 7 non-null datetime64[ns] + 7 label 1238 non-null object + 8 label_confidence 1238 non-null object +dtypes: datetime64[ns](3), float64(2), object(4) +memory usage: 87.2+ KB +``` + +## Next Steps + +Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index) for other API resources to understand how you can combine the reporting and statistical capabilities of the 4Wings API with vessel information, event data, and more. Check out the following resources: + +- [4Wings API](4wings-api) +- [Vessels API](vessels-api) +- [Events API](events-api) +- [Insights API](insights-api) +- [Datasets API](datasets-api) +- [Reference Data API](references-data-api) diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 617626a..03819a5 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-api.md @@ -175,4 +175,5 @@ Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index - [Vessels API](vessels-api) - [Events API](events-api) - [Insights API](insights-api) +- [Bulk Download API](bulk-downloads-api) - [Reference Data API](references-data-api) diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index 11e4219..e7b939c 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-api.md @@ -225,4 +225,5 @@ Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index - [Vessels API](vessels-api) - [Insights API](insights-api) - [Datasets API](datasets-api) +- [Bulk Download API](bulk-downloads-api) - [Reference Data API](references-data-api) diff --git a/docs/source/usage-guides/index.md b/docs/source/usage-guides/index.md index 00ec833..1f72ad4 100644 --- a/docs/source/usage-guides/index.md +++ b/docs/source/usage-guides/index.md @@ -12,5 +12,6 @@ vessels-api events-api insights-api datasets-api +bulk-downloads-api references-data-api ``` diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index 51c0813..c00a76a 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -100,8 +100,9 @@ memory usage: 180.0+ bytes 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: +- [4Wings API](4wings-api) - [Vessels API](vessels-api) - [Events API](events-api) -- [4Wings API](4wings-api) - [Datasets API](datasets-api) +- [Bulk Download API](bulk-downloads-api) - [Reference Data API](references-data-api) diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index 6b4b8d4..5ef6589 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-api.md @@ -187,3 +187,4 @@ Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index - [Events API](events-api) - [Insights API](insights-api) - [Datasets API](datasets-api) +- [Bulk Download API](bulk-downloads-api) diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index 3e501d6..7160d28 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-api.md @@ -201,4 +201,5 @@ Explore the [Usage Guides](index) and [Workflow Guides](../workflow-guides/index - [Events API](events-api) - [Insights API](insights-api) - [Datasets API](datasets-api) +- [Bulk Download API](bulk-downloads-api) - [Reference Data API](references-data-api) diff --git a/notebooks/usage-guides/bulk-downloads-api.ipynb b/notebooks/usage-guides/bulk-downloads-api.ipynb new file mode 100644 index 0000000..fb7b832 --- /dev/null +++ b/notebooks/usage-guides/bulk-downloads-api.ipynb @@ -0,0 +1,1409 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7f3b7119", + "metadata": { + "colab_type": "text", + "id": "view-in-github" + }, + "source": [ + "\"Open" + ] + }, + { + "cell_type": "markdown", + "id": "493f86ff-cee9-4fb0-8e5f-b3a0903df39e", + "metadata": { + "id": "493f86ff-cee9-4fb0-8e5f-b3a0903df39e" + }, + "source": [ + "# Bulk Download API" + ] + }, + { + "cell_type": "markdown", + "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958", + "metadata": { + "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958" + }, + "source": [ + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the [Bulk Download API](https://globalfishingwatch.org/our-apis/documentation#bulk-download-api), which is designed to support workflows that require bulk access to data, including integration with platforms and tools used by data engineers and researchers." + ] + }, + { + "cell_type": "markdown", + "id": "3d31e934-e291-453d-aad9-6e0e61d1318e", + "metadata": {}, + "source": [ + "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats), 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." + ] + }, + { + "cell_type": "markdown", + "id": "cb352526-90e2-45fd-8732-e34f0342f30f", + "metadata": { + "id": "cb352526-90e2-45fd-8732-e34f0342f30f" + }, + "source": [ + "## Prerequisites" + ] + }, + { + "cell_type": "markdown", + "id": "57109889-5f3f-45b3-a594-2f82b94bcadb", + "metadata": { + "id": "57109889-5f3f-45b3-a594-2f82b94bcadb" + }, + "source": [ + "Before using the `gfw-api-python-client`, ensure it is installed (see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide) and that you have obtained an API access token from the [Global Fishing Watch API portal](https://globalfishingwatch.org/our-apis/tokens)." + ] + }, + { + "cell_type": "markdown", + "id": "3d1d4bf0-e6f7-4bda-9a79-4c6b6a42d1a1", + "metadata": { + "id": "3d1d4bf0-e6f7-4bda-9a79-4c6b6a42d1a1" + }, + "source": [ + "## Installation" + ] + }, + { + "cell_type": "markdown", + "id": "e8ed8d6d-214c-4888-bbb9-3798adabe12b", + "metadata": { + "id": "e8ed8d6d-214c-4888-bbb9-3798adabe12b" + }, + "source": [ + "The `gfw-api-python-client` can be easily installed using pip:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d863fe42-f9f6-4a6e-b736-f0adc82581fe", + "metadata": { + "id": "d863fe42-f9f6-4a6e-b736-f0adc82581fe" + }, + "outputs": [], + "source": [ + "# %pip install gfw-api-python-client" + ] + }, + { + "cell_type": "markdown", + "id": "9c023a54-4d23-4cc2-bd36-659d4d78789e", + "metadata": { + "id": "9c023a54-4d23-4cc2-bd36-659d4d78789e" + }, + "source": [ + "## Usage" + ] + }, + { + "cell_type": "markdown", + "id": "fe7df9a0-cd5e-4b99-94b4-07b2ca0481f0", + "metadata": {}, + "source": [ + "Import and use `gfw-api-python-client` in your Python codes" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2420e772-c8c6-4eec-bbab-db0708733b50", + "metadata": { + "id": "2420e772-c8c6-4eec-bbab-db0708733b50" + }, + "outputs": [], + "source": [ + "import time\n", + "import os\n", + "\n", + "import gfwapiclient as gfw" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "c1fae7c8-2806-4468-84f0-2ca90b4f5653", + "metadata": { + "id": "c1fae7c8-2806-4468-84f0-2ca90b4f5653" + }, + "outputs": [], + "source": [ + "try:\n", + " from google.colab import userdata\n", + "\n", + " access_token = userdata.get(\"GFW_API_ACCESS_TOKEN\")\n", + "except Exception:\n", + " access_token = os.environ.get(\"GFW_API_ACCESS_TOKEN\")\n", + "\n", + "access_token = access_token or \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "08c9daef-552d-4906-ac21-eaedcea7b102", + "metadata": { + "id": "08c9daef-552d-4906-ac21-eaedcea7b102" + }, + "outputs": [], + "source": [ + "gfw_client = gfw.Client(\n", + " access_token=access_token,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "1528b997-f892-46d3-976f-4b81794b1f3a", + "metadata": {}, + "source": [ + "## Create a Bulk Report (`create_bulk_report`)" + ] + }, + { + "cell_type": "markdown", + "id": "73b742ef-d9f5-4903-8ff9-743d7486b126", + "metadata": {}, + "source": [ + "The `create_bulk_report()` method allows you **create** a bulk report based on specified filters and spatial parameters. The `name` parameter is mandatory. Please [learn more about create a bulk report here](https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a0496b62-ca37-4d36-adb8-42ab8b69690e", + "metadata": {}, + "outputs": [], + "source": [ + "timestamp = int(time.time() * 1000)\n", + "dataset = \"public-fixed-infrastructure-data:latest\"\n", + "region_dataset = \"public-eez-areas\"\n", + "region_id = \"8466\" # Argentinian Exclusive Economic Zone\n", + "name = f\"{dataset.split(':')[0]}_{region_dataset}__{region_id}_{timestamp}\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "aebdbd17-f0da-4f76-929d-ad26a53d5e1b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'public-fixed-infrastructure-data_public-eez-areas__8466_1768085547174'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "name" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "802695e0-d728-4194-967d-7a6eba3a5916", + "metadata": {}, + "outputs": [], + "source": [ + "create_bulk_report_result = await gfw_client.bulk_downloads.create_bulk_report(\n", + " name=name,\n", + " dataset=dataset,\n", + " region={\n", + " \"dataset\": region_dataset,\n", + " \"id\": region_id,\n", + " },\n", + " filters=[\"label = 'oil'\", \"label_confidence = 'high'\"],\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b1bb0495-6fd0-48e3-9583-429dd8d8b778", + "metadata": {}, + "source": [ + "### Access Create a Bulk Report Result as Pydantic models" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "fb381ffe-1441-4543-866d-f47ea4675f40", + "metadata": {}, + "outputs": [], + "source": [ + "create_bulk_report_data = create_bulk_report_result.data()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d2dc3e1e-c332-4d91-9209-a0680a67d31c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('c5e32895-4374-41d2-8b2e-ac414ed6757f',\n", + " 'public-fixed-infrastructure-data_public-eez-areas__8466_1768085547174',\n", + " 'pending',\n", + " datetime.datetime(2026, 1, 10, 22, 52, 30, 9000, tzinfo=TzInfo(0)))" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " create_bulk_report_data.id,\n", + " create_bulk_report_data.name,\n", + " create_bulk_report_data.status,\n", + " create_bulk_report_data.created_at,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "b9d29b17-db63-4b07-9736-8fab781833d6", + "metadata": {}, + "source": [ + "### Access Create a Bulk Report Result as a DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "f68b5906-3811-47f1-ad3d-a4a3ab14b374", + "metadata": {}, + "outputs": [], + "source": [ + "create_bulk_report_df = create_bulk_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "6744d8c2-a550-4635-8aed-4a58c0f2d64d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 1 non-null object \n", + " 1 name 1 non-null object \n", + " 2 file_path 1 non-null object \n", + " 3 format 1 non-null object \n", + " 4 filters 1 non-null object \n", + " 5 geom 1 non-null object \n", + " 6 status 1 non-null object \n", + " 7 owner_id 1 non-null int64 \n", + " 8 owner_type 1 non-null object \n", + " 9 created_at 1 non-null datetime64[ns, UTC]\n", + " 10 updated_at 1 non-null datetime64[ns, UTC]\n", + " 11 file_size 0 non-null object \n", + "dtypes: datetime64[ns, UTC](2), int64(1), object(9)\n", + "memory usage: 228.0+ bytes\n" + ] + } + ], + "source": [ + "create_bulk_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "d152ac16-99f6-4675-8f6e-a7f92302e4c2", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamefile_pathformatfiltersgeomstatusowner_idowner_typecreated_atupdated_atfile_size
0c5e32895-4374-41d2-8b2e-ac414ed6757fpublic-fixed-infrastructure-data_public-eez-ar...sar_fixed_infrastructure_202409.csvJSON[label = 'oil', label_confidence = 'high']{'type': 'dataset', 'dataset': 'public-eez-are...pending39application2026-01-10 22:52:30.009000+00:002026-01-10 22:52:30.009000+00:00None
\n", + "
" + ], + "text/plain": [ + " id \\\n", + "0 c5e32895-4374-41d2-8b2e-ac414ed6757f \n", + "\n", + " name \\\n", + "0 public-fixed-infrastructure-data_public-eez-ar... \n", + "\n", + " file_path format \\\n", + "0 sar_fixed_infrastructure_202409.csv JSON \n", + "\n", + " filters \\\n", + "0 [label = 'oil', label_confidence = 'high'] \n", + "\n", + " geom status owner_id \\\n", + "0 {'type': 'dataset', 'dataset': 'public-eez-are... pending 39 \n", + "\n", + " owner_type created_at \\\n", + "0 application 2026-01-10 22:52:30.009000+00:00 \n", + "\n", + " updated_at file_size \n", + "0 2026-01-10 22:52:30.009000+00:00 None " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "create_bulk_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "ba3d1019-43d4-4d78-8b05-1b9a875aff73", + "metadata": {}, + "source": [ + "## Get Bulk Report by ID (`get_bulk_report_by_id`)" + ] + }, + { + "cell_type": "markdown", + "id": "b577a216-dd60-420f-aeef-51243eb09a32", + "metadata": {}, + "source": [ + "The `get_bulk_report_by_id()` method allows you retrieves **metadata and status** of the previously created bulk report based on the provided bulk report ID. The `id` parameter is mandatory. Please [learn more about get bulk report by id report here](https://globalfishingwatch.org/our-apis/documentation#get-bulk-report-by-id) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats)." + ] + }, + { + "cell_type": "markdown", + "id": "60e5e9ba-33a2-438f-8528-0366779e6e70", + "metadata": {}, + "source": [ + " **Important:** We recommend to use this method to poll the status of previously created bulk report, if it takes **several minutes or hours** to generate until it status is `done` or `failed`." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "1a05b7ff-26fb-40ad-b578-74e7647eb687", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_result = await gfw_client.bulk_downloads.get_bulk_report_by_id(\n", + " id=create_bulk_report_data.id\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "da68ee08-c25d-40aa-b0a7-520e8408f529", + "metadata": {}, + "source": [ + "### Access Get Bulk Report by ID Result as Pydantic models" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "2f064920-a66c-48d8-9f20-2fb36b7dc4bc", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_data = bulk_report_result.data()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a966e319-3214-410e-b063-e0f51f68d04c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('c5e32895-4374-41d2-8b2e-ac414ed6757f',\n", + " 'public-fixed-infrastructure-data_public-eez-areas__8466_1768085547174',\n", + " 'pending',\n", + " datetime.datetime(2026, 1, 10, 22, 52, 30, 9000, tzinfo=TzInfo(0)))" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " create_bulk_report_data.id,\n", + " create_bulk_report_data.name,\n", + " create_bulk_report_data.status,\n", + " create_bulk_report_data.created_at,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d33878dc-be26-47c1-9e28-68127c4c2869", + "metadata": {}, + "source": [ + "### Access Get Bulk Report by ID Result as a DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "7cf258fa-e0d0-45c3-9f39-06f547f61529", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_df = bulk_report_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "57381d93-fdf1-4fd3-aec2-71bbdf877bc8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 1 non-null object \n", + " 1 name 1 non-null object \n", + " 2 file_path 1 non-null object \n", + " 3 format 1 non-null object \n", + " 4 filters 1 non-null object \n", + " 5 geom 1 non-null object \n", + " 6 status 1 non-null object \n", + " 7 owner_id 1 non-null int64 \n", + " 8 owner_type 1 non-null object \n", + " 9 created_at 1 non-null datetime64[ns, UTC]\n", + " 10 updated_at 1 non-null datetime64[ns, UTC]\n", + " 11 file_size 0 non-null object \n", + "dtypes: datetime64[ns, UTC](2), int64(1), object(9)\n", + "memory usage: 228.0+ bytes\n" + ] + } + ], + "source": [ + "bulk_report_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "89f76538-0bc2-4258-bb27-410cd9cc5b85", + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamefile_pathformatfiltersgeomstatusowner_idowner_typecreated_atupdated_atfile_size
0c5e32895-4374-41d2-8b2e-ac414ed6757fpublic-fixed-infrastructure-data_public-eez-ar...sar_fixed_infrastructure_202409.csvJSON[label = 'oil', label_confidence = 'high']{'type': 'dataset', 'dataset': 'public-eez-are...pending39application2026-01-10 22:52:30.009000+00:002026-01-10 22:52:30.009000+00:00None
\n", + "
" + ], + "text/plain": [ + " id \\\n", + "0 c5e32895-4374-41d2-8b2e-ac414ed6757f \n", + "\n", + " name \\\n", + "0 public-fixed-infrastructure-data_public-eez-ar... \n", + "\n", + " file_path format \\\n", + "0 sar_fixed_infrastructure_202409.csv JSON \n", + "\n", + " filters \\\n", + "0 [label = 'oil', label_confidence = 'high'] \n", + "\n", + " geom status owner_id \\\n", + "0 {'type': 'dataset', 'dataset': 'public-eez-are... pending 39 \n", + "\n", + " owner_type created_at \\\n", + "0 application 2026-01-10 22:52:30.009000+00:00 \n", + "\n", + " updated_at file_size \n", + "0 2026-01-10 22:52:30.009000+00:00 None " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bulk_report_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "c30c9de1-8fcc-45cc-91ad-339d1e1944ee", + "metadata": {}, + "source": [ + "## Get All Bulk Reports Created by User or Application (`get_all_bulk_reports`)" + ] + }, + { + "cell_type": "markdown", + "id": "d5f9e8ad-f137-446b-a38f-9caa4f233925", + "metadata": {}, + "source": [ + "The `get_all_bulk_reports()` method allows you retrieves a list of **metadata and status** of the previously created bulk reports based on specified pagination, sorting, and filtering criteria. Please [learn more about get all bulk reports created by user or application here](https://globalfishingwatch.org/our-apis/documentation#get-all-bulk-reports-by-user) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats)." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "338223ff-9c23-47f6-bf33-2aaaefc35081", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_reports_result = await gfw_client.bulk_downloads.get_all_bulk_reports(\n", + " status=\"done\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "86738d44-fed7-4dd9-8014-d72ae3c22ae7", + "metadata": {}, + "source": [ + "### Access All Created Bulk Reports Result as Pydantic models" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "3bff3854-9b54-44c9-a7f8-3ef2bf1b7719", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_reports_data = bulk_reports_result.data()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "21e8b553-20dd-43bb-92c3-0e7f5f6f29c3", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_item = bulk_reports_data[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "29bd8b84-1f22-4a11-9861-548237926012", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('0c0cada1-72dd-4fb0-bdf6-7fe8c7fdb1e3',\n", + " 'sar-fixed-infrastructure-data-20241207-region-1',\n", + " 'done',\n", + " datetime.datetime(2025, 12, 7, 10, 3, 12, 371000, tzinfo=TzInfo(0)))" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " bulk_report_item.id,\n", + " bulk_report_item.name,\n", + " bulk_report_item.status,\n", + " bulk_report_item.created_at,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "f1294498-7b8c-4054-85b3-a24ecee90340", + "metadata": {}, + "source": [ + "### Access All Created Bulk Reports Result as a DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "a778ef19-f68d-4e0b-8b37-539db79868cb", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_reports_df = bulk_reports_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "271d446a-702d-42bb-93a9-e576741a3fdd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 7 entries, 0 to 6\n", + "Data columns (total 12 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 id 7 non-null object \n", + " 1 name 7 non-null object \n", + " 2 file_path 7 non-null object \n", + " 3 format 7 non-null object \n", + " 4 filters 7 non-null object \n", + " 5 geom 4 non-null object \n", + " 6 status 7 non-null object \n", + " 7 owner_id 7 non-null int64 \n", + " 8 owner_type 7 non-null object \n", + " 9 created_at 7 non-null datetime64[ns, UTC]\n", + " 10 updated_at 7 non-null datetime64[ns, UTC]\n", + " 11 file_size 7 non-null float64 \n", + "dtypes: datetime64[ns, UTC](2), float64(1), int64(1), object(8)\n", + "memory usage: 804.0+ bytes\n" + ] + } + ], + "source": [ + "bulk_reports_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "5145b645-c0fe-4780-b94f-261b534b7f04", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idnamefile_pathformatfiltersgeomstatusowner_idowner_typecreated_atupdated_atfile_size
0705f2f9a-f695-43f1-a4bf-7746f3deb091public-fixed-infrastructure-data_public-eez-ar...sar_fixed_infrastructure_202409.csvJSON[label = 'oil', label_confidence = 'high']{'type': 'dataset', 'dataset': 'public-eez-are...done39application2026-01-10 22:47:37.506000+00:002026-01-10 22:47:37.506000+00:0022224.0
189e29012-bd90-4718-a6ba-71c0e3ea6260public-fixed-infrastructure-data_public-eez-ar...sar_fixed_infrastructure_202409.csvJSON[label = 'oil', label_confidence = 'high']{'type': 'dataset', 'dataset': 'public-eez-are...done39application2026-01-10 21:57:03.520000+00:002026-01-10 21:57:03.520000+00:0022224.0
29e8d0d20-a635-4d36-83f4-4179c3aad156sar-fixed-infrastructure-data-20241207-all-oil...sar_fixed_infrastructure_202409.csvJSON[label = 'oil', label_confidence = 'high']Nonedone39application2025-12-07 14:09:17.712000+00:002025-12-07 14:09:17.712000+00:0018223879.0
37a036b8f-21fc-4c53-a6cb-2d90caf1c2a5sar-fixed-infrastructure-data-20241207-all-lab...sar_fixed_infrastructure_202409.csvJSON[label_confidence = 'high' or label_confidence...Nonedone39application2025-12-07 12:21:33.424000+00:002025-12-07 12:21:33.424000+00:00122605450.0
4568d2d08-82f8-4243-a120-103c6417eef2sar-fixed-infrastructure-data-20241207-all-1sar_fixed_infrastructure_202409.csvJSON[label_confidence = 'high']Nonedone39application2025-12-07 10:12:40.192000+00:002025-12-07 10:12:40.192000+00:00117135274.0
\n", + "
" + ], + "text/plain": [ + " id \\\n", + "0 705f2f9a-f695-43f1-a4bf-7746f3deb091 \n", + "1 89e29012-bd90-4718-a6ba-71c0e3ea6260 \n", + "2 9e8d0d20-a635-4d36-83f4-4179c3aad156 \n", + "3 7a036b8f-21fc-4c53-a6cb-2d90caf1c2a5 \n", + "4 568d2d08-82f8-4243-a120-103c6417eef2 \n", + "\n", + " name \\\n", + "0 public-fixed-infrastructure-data_public-eez-ar... \n", + "1 public-fixed-infrastructure-data_public-eez-ar... \n", + "2 sar-fixed-infrastructure-data-20241207-all-oil... \n", + "3 sar-fixed-infrastructure-data-20241207-all-lab... \n", + "4 sar-fixed-infrastructure-data-20241207-all-1 \n", + "\n", + " file_path format \\\n", + "0 sar_fixed_infrastructure_202409.csv JSON \n", + "1 sar_fixed_infrastructure_202409.csv JSON \n", + "2 sar_fixed_infrastructure_202409.csv JSON \n", + "3 sar_fixed_infrastructure_202409.csv JSON \n", + "4 sar_fixed_infrastructure_202409.csv JSON \n", + "\n", + " filters \\\n", + "0 [label = 'oil', label_confidence = 'high'] \n", + "1 [label = 'oil', label_confidence = 'high'] \n", + "2 [label = 'oil', label_confidence = 'high'] \n", + "3 [label_confidence = 'high' or label_confidence... \n", + "4 [label_confidence = 'high'] \n", + "\n", + " geom status owner_id \\\n", + "0 {'type': 'dataset', 'dataset': 'public-eez-are... done 39 \n", + "1 {'type': 'dataset', 'dataset': 'public-eez-are... done 39 \n", + "2 None done 39 \n", + "3 None done 39 \n", + "4 None done 39 \n", + "\n", + " owner_type created_at \\\n", + "0 application 2026-01-10 22:47:37.506000+00:00 \n", + "1 application 2026-01-10 21:57:03.520000+00:00 \n", + "2 application 2025-12-07 14:09:17.712000+00:00 \n", + "3 application 2025-12-07 12:21:33.424000+00:00 \n", + "4 application 2025-12-07 10:12:40.192000+00:00 \n", + "\n", + " updated_at file_size \n", + "0 2026-01-10 22:47:37.506000+00:00 22224.0 \n", + "1 2026-01-10 21:57:03.520000+00:00 22224.0 \n", + "2 2025-12-07 14:09:17.712000+00:00 18223879.0 \n", + "3 2025-12-07 12:21:33.424000+00:00 122605450.0 \n", + "4 2025-12-07 10:12:40.192000+00:00 117135274.0 " + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bulk_reports_df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "d00c4ba7-cc57-4503-8160-b42634c67777", + "metadata": {}, + "source": [ + "## Get Bulk Report File Download URL (`get_bulk_report_file_download_url`)" + ] + }, + { + "cell_type": "markdown", + "id": "65f7ae75-ae94-40d2-95b6-1b7eecc78356", + "metadata": {}, + "source": [ + "The `get_bulk_report_file_download_url()` method allows you retrieves **signed URL** that points to a **downloadable file** hosted on Global Fishing Watch's cloud infrastructure to **download file(s)** (i.e., `\"DATA\"`, `\"README\"`, or `\"GEOM\"`) of the previously created bulk report. The `id` parameter is mandatory. Please [learn more about get bulk report file download url here](https://globalfishingwatch.org/our-apis/documentation#download-bulk-report-url-file) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats)." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "70c51654-a7b9-46a9-991b-c9c97dcfe41e", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_file_download_url_result = (\n", + " await gfw_client.bulk_downloads.get_bulk_report_file_download_url(\n", + " id=bulk_reports_data[0].id, file=\"DATA\"\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "74dbe00c-7503-473a-aac7-5f99984d41dc", + "metadata": {}, + "source": [ + "### Access Get Bulk Report File Download URL Result as Pydantic models" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "5330ef22-3ef7-4482-ae34-f1e9f6f48ccf", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_file_download_url_data = bulk_report_file_download_url_result.data()" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "4e3d4575-4c59-4c8e-b15e-2206bdb995ec", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://storage.googleapis.com/gfw-api-bulk-pro-us-central1/705f2f9a-f695-43f1-a4bf-7746f3deb091/data.json.gz?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=api-bulk-pro%40gfw-production.iam.gserviceaccount.com%2F20260110%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260110T225232Z&X-Goog-Expires=60&X-Goog-SignedHeaders=host&X-Goog-Signature=481a4ff7244b7286f303b37bb7941c291a26d1e3502debdb7611b8cb2d5edf37bc7aa0287b15a11c2f69f72e88791da3f76873a2fd7d08f911691c35ee8e095b825615510de8256f8cd275211997141e026837e118d86e01c026c457dc1f47d43ff2cb07131c3d21e7908c847bf1e3d87cd4773f02e8e4512a7c15e93799de186b9ea004be50cd3e53292f01e9393595a81c42cc3686f65d280f4f16076759da4722c17c2a6a698393c919cdd083402421a1bbf425b618244b3a9b30e48b770a9dc7f9eed8e63af04f8e31f0b6723fdf76fa7262ded89e7a375fbaea3b031bf29db22b1961878facd79c92d633ab6aa2309c0ce3982104d9835058ecd829bee8'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bulk_report_file_download_url_data.url" + ] + }, + { + "cell_type": "markdown", + "id": "a7115103-5942-429d-a247-2947f01e139f", + "metadata": {}, + "source": [ + "### Access Get Bulk Report File Download URL Result as a DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "7750da1f-e4cd-4fcd-9fe2-472e2d4e98b9", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_report_file_download_url_df = bulk_report_file_download_url_result.df()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "ac6aada1-e0a2-4a31-9421-ce88c55aebb4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1 entries, 0 to 0\n", + "Data columns (total 1 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 url 1 non-null object\n", + "dtypes: object(1)\n", + "memory usage: 140.0+ bytes\n" + ] + } + ], + "source": [ + "bulk_report_file_download_url_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "b6fe6c39-3e0a-43c2-8279-8fa1eebb18e6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://storage.googleapis.com/gfw-api-bulk-pro-us-central1/705f2f9a-f695-43f1-a4bf-7746f3deb091/data.json.gz?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=api-bulk-pro%40gfw-production.iam.gserviceaccount.com%2F20260110%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260110T225232Z&X-Goog-Expires=60&X-Goog-SignedHeaders=host&X-Goog-Signature=481a4ff7244b7286f303b37bb7941c291a26d1e3502debdb7611b8cb2d5edf37bc7aa0287b15a11c2f69f72e88791da3f76873a2fd7d08f911691c35ee8e095b825615510de8256f8cd275211997141e026837e118d86e01c026c457dc1f47d43ff2cb07131c3d21e7908c847bf1e3d87cd4773f02e8e4512a7c15e93799de186b9ea004be50cd3e53292f01e9393595a81c42cc3686f65d280f4f16076759da4722c17c2a6a698393c919cdd083402421a1bbf425b618244b3a9b30e48b770a9dc7f9eed8e63af04f8e31f0b6723fdf76fa7262ded89e7a375fbaea3b031bf29db22b1961878facd79c92d633ab6aa2309c0ce3982104d9835058ecd829bee8'" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bulk_report_file_download_url_df.iloc[0][\"url\"]" + ] + }, + { + "cell_type": "markdown", + "id": "775f0875-6fef-45d7-ad1a-c589927a3f4b", + "metadata": {}, + "source": [ + "## Query Bulk Fixed Infrastructure Data Report (`query_bulk_fixed_infrastructure_data_report`)" + ] + }, + { + "cell_type": "markdown", + "id": "8f321b5e-3405-46fe-a92e-4d2bb698df36", + "metadata": {}, + "source": [ + "The `query_bulk_fixed_infrastructure_data_report()` method allows you retrieves **data records** of a previously created **fixed infrastructure data** (i.e., `public-fixed-infrastructure-data:latest` dataset) bulk report data in JSON format based on specified pagination, sorting, and including criteria. The `id` parameter is mandatory. Please [learn more about query bulk fixed infrastructure data report in JSON format here](https://globalfishingwatch.org/our-apis/documentation#get-data-in-json-format) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats)." + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "cd2f2b83-c2c6-4729-b229-1564ff9b4bbe", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_fixed_infrastructure_data_report_result = (\n", + " await gfw_client.bulk_downloads.query_bulk_fixed_infrastructure_data_report(\n", + " id=bulk_reports_data[0].id\n", + " )\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "79b3a72d-ec5b-4d6f-ace3-519ac1949592", + "metadata": {}, + "source": [ + "### Access Query Bulk Fixed Infrastructure Data Report Result as Pydantic models" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "fc0e5713-8747-4afe-b7de-6cd5de4527af", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_fixed_infrastructure_data_report_data = (\n", + " bulk_fixed_infrastructure_data_report_result.data()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "d45b9472-9051-4c15-9085-a4d904baef67", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_fixed_infrastructure_data_report_item = bulk_fixed_infrastructure_data_report_data[\n", + " -1\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "032db92c-3a8d-4f73-a5cb-b567abe5de03", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('1051638', -53.0895574340617, -67.32289149541135, 'oil', 'high')" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "(\n", + " bulk_fixed_infrastructure_data_report_item.structure_id,\n", + " bulk_fixed_infrastructure_data_report_item.lat,\n", + " bulk_fixed_infrastructure_data_report_item.lon,\n", + " bulk_fixed_infrastructure_data_report_item.label,\n", + " bulk_fixed_infrastructure_data_report_item.label_confidence,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "32b433f4-baed-4b0e-9989-9a02fbbc5fd9", + "metadata": {}, + "source": [ + "### Access Query Bulk Fixed Infrastructure Data Report Result as a DataFrame" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "b38b2a5b-bfd7-4308-a8fa-1efb609d70c8", + "metadata": {}, + "outputs": [], + "source": [ + "bulk_fixed_infrastructure_data_report_result_df = (\n", + " bulk_fixed_infrastructure_data_report_result.df()\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "a10e881e-928c-41aa-b47e-c33e9fdfb95d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1238 entries, 0 to 1237\n", + "Data columns (total 9 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 detection_id 1237 non-null object \n", + " 1 detection_date 1238 non-null datetime64[ns]\n", + " 2 structure_id 1238 non-null object \n", + " 3 lat 1238 non-null float64 \n", + " 4 lon 1238 non-null float64 \n", + " 5 structure_start_date 1238 non-null datetime64[ns]\n", + " 6 structure_end_date 7 non-null datetime64[ns]\n", + " 7 label 1238 non-null object \n", + " 8 label_confidence 1238 non-null object \n", + "dtypes: datetime64[ns](3), float64(2), object(4)\n", + "memory usage: 87.2+ KB\n" + ] + } + ], + "source": [ + "bulk_fixed_infrastructure_data_report_result_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "2c0bb2d5-c119-4a74-800b-aef1efbc5df4", + "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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + "
detection_iddetection_datestructure_idlatlonstructure_start_datestructure_end_datelabellabel_confidence
0S1AB_AD_MEDIAN_COMP_20170902T000000_20180301T0...2017-12-01313068-52.612197-68.4492922017-01-01NaToilhigh
1S1AB_AD_MEDIAN_COMP_20231101T000000_20240501T0...2024-02-01313068-52.612197-68.4492922017-01-01NaToilhigh
2S1AB_AD_MEDIAN_COMP_20230501T000000_20231101T0...2023-08-01313068-52.612197-68.4492922017-01-01NaToilhigh
3S1AB_AD_MEDIAN_COMP_20220901T000000_20230301T0...2022-12-01313068-52.612197-68.4492922017-01-01NaToilhigh
4S1AB_AD_MEDIAN_COMP_20220701T000000_20230101T0...2022-10-01313068-52.612197-68.4492922017-01-01NaToilhigh
\n", + "
" + ], + "text/plain": [ + " detection_id detection_date \\\n", + "0 S1AB_AD_MEDIAN_COMP_20170902T000000_20180301T0... 2017-12-01 \n", + "1 S1AB_AD_MEDIAN_COMP_20231101T000000_20240501T0... 2024-02-01 \n", + "2 S1AB_AD_MEDIAN_COMP_20230501T000000_20231101T0... 2023-08-01 \n", + "3 S1AB_AD_MEDIAN_COMP_20220901T000000_20230301T0... 2022-12-01 \n", + "4 S1AB_AD_MEDIAN_COMP_20220701T000000_20230101T0... 2022-10-01 \n", + "\n", + " structure_id lat lon structure_start_date structure_end_date \\\n", + "0 313068 -52.612197 -68.449292 2017-01-01 NaT \n", + "1 313068 -52.612197 -68.449292 2017-01-01 NaT \n", + "2 313068 -52.612197 -68.449292 2017-01-01 NaT \n", + "3 313068 -52.612197 -68.449292 2017-01-01 NaT \n", + "4 313068 -52.612197 -68.449292 2017-01-01 NaT \n", + "\n", + " label label_confidence \n", + "0 oil high \n", + "1 oil high \n", + "2 oil high \n", + "3 oil high \n", + "4 oil high " + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bulk_fixed_infrastructure_data_report_result_df.head()" + ] + } + ], + "metadata": { + "colab": { + "include_colab_link": true, + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From fbbb0651313cd506ebd3e1a2b44612989c79dbd7 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Mon, 12 Jan 2026 15:05:29 +0300 Subject: [PATCH 19/22] docs: clarify async-first usage and improve API guide references This: - document async-first behavior in getting-started guide - add tips for running async code in interactive environments - link usage guides and notebooks to official GFW API documentation pages --- docs/source/getting-started.md | 4 ++++ docs/source/usage-guides/4wings-api.md | 4 +++- docs/source/usage-guides/bulk-downloads-api.md | 4 +++- docs/source/usage-guides/datasets-api.md | 4 +++- docs/source/usage-guides/events-api.md | 4 +++- docs/source/usage-guides/insights-api.md | 6 +++++- docs/source/usage-guides/references-data-api.md | 4 +++- docs/source/usage-guides/vessels-api.md | 4 +++- notebooks/usage-guides/4wings-api.ipynb | 2 +- notebooks/usage-guides/datasets-api.ipynb | 2 +- notebooks/usage-guides/events-api.ipynb | 2 +- notebooks/usage-guides/insights-api.ipynb | 2 +- notebooks/usage-guides/references-data-api.ipynb | 2 +- notebooks/usage-guides/vessels-api.ipynb | 2 +- 14 files changed, 33 insertions(+), 13 deletions(-) diff --git a/docs/source/getting-started.md b/docs/source/getting-started.md index 32ae523..fa7d8a7 100644 --- a/docs/source/getting-started.md +++ b/docs/source/getting-started.md @@ -63,6 +63,10 @@ gfw_client = gfw.Client( ) ``` +> **Important:** The `gfw-api-python-client` is **async-first**: all API methods are asynchronous and must be executed using Python's `async` / `await` syntax. **Environments with built-in async support** (e.g., _Jupyter Notebook_, _Google Colab_, and async web frameworks such as _FastAPI_) can call client methods directly using `await`, with no additional setup. **Environments without built-in async support** (e.g., _plain Python scripts_, _Python modules_, or synchronous web frameworks such as _Flask_ and _Django_) must explicitly run asynchronous code using an event loop. This can be done with tools such as [`asyncio.run`](https://docs.python.org/3/library/asyncio.html), [`trio.run`](https://trio.readthedocs.io/en/stable/), [`anyio.run`](https://anyio.readthedocs.io/en/stable/), or framework-specific async integration. + +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Making API Requests ### Searching for a Vessel by MMSI diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index 2fc50c1..d1a8c08 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-api.md @@ -2,7 +2,7 @@ Open In Colab -This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the 4Wings API, which is designed for generating reports and statistics on activities within specified regions. This API is particularly useful for creating data visualizations related to fishing effort and other vessel activities. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/4wings-api.ipynb) version of this guide with more usage examples. +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), which is designed for generating reports and statistics on activities within specified regions. This API is particularly useful for creating data visualizations related to fishing effort and other vessel activities. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/4wings-api.ipynb) version of this guide with more usage examples. > **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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. @@ -32,6 +32,8 @@ gfw_client = gfw.Client( The `gfw_client.fourwings` object provides methods to generate reports, retrieve the last generated report, and get global fishing effort statistics. These methods return a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Creating a Fishing Effort Report (`create_fishing_effort_report`) Generates **AIS (Automatic Identification System) apparent fishing effort** reports to visualize fishing activity. Please [learn more about apparent fishing effort here](https://globalfishingwatch.org/our-apis/documentation#ais-apparent-fishing-effort) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort). diff --git a/docs/source/usage-guides/bulk-downloads-api.md b/docs/source/usage-guides/bulk-downloads-api.md index a9c744f..e199643 100644 --- a/docs/source/usage-guides/bulk-downloads-api.md +++ b/docs/source/usage-guides/bulk-downloads-api.md @@ -12,7 +12,7 @@ This guide provides detailed instructions on how to use the [gfw-api-python-clie ## Getting Started -To interact with the 4Wings endpoints, you first need to instantiate the `gfw.Client` and then access the `fourwings` resource: +To interact with the Bulk Download endpoints, you first need to instantiate the `gfw.Client` and then access the `bulk_downloads` resource: ```python import time @@ -41,6 +41,8 @@ The `gfw_client.bulk_downloads` object provides methods to: These methods return a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Create a Bulk Report (`create_bulk_report`) The `create_bulk_report()` method allows you create a bulk report based on specified filters and spatial parameters. The `name` parameter is mandatory. Please [learn more about create a bulk report here](https://globalfishingwatch.org/our-apis/documentation#create-a-bulk-report) and [check its data caveats here](https://globalfishingwatch.org/our-apis/documentation#data-caveat) and [here](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats). diff --git a/docs/source/usage-guides/datasets-api.md b/docs/source/usage-guides/datasets-api.md index 03819a5..9babfb5 100644 --- a/docs/source/usage-guides/datasets-api.md +++ b/docs/source/usage-guides/datasets-api.md @@ -2,7 +2,7 @@ Open In Colab -This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access various datasets available through the Global Fishing Watch API. Currently, it focuses on retrieving SAR (Synthetic Aperture Radar) fixed infrastructure data. The Datasets API allows you to retrieve this information, either by specifying `tile coordinates` or a `geographic geometry`. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/datasets-api.ipynb) version of this guide with more usage examples. +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access various datasets available through the Global Fishing Watch API. Currently, it focuses on retrieving SAR (Synthetic Aperture Radar) fixed infrastructure data. The [Datasets API](https://globalfishingwatch.org/our-apis/documentation#datasets-api) allows you to retrieve this information, either by specifying `tile coordinates` or a `geographic geometry`. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/datasets-api.ipynb) version of this guide with more usage examples. > **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [SAR (Synthetic-Aperture Radar) Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-fixed-infrastructure-data-caveats), 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. @@ -32,6 +32,8 @@ gfw_client = gfw.Client( The `gfw_client.datasets` object provides methods to retrieve data from various datasets. The `get_sar_fixed_infrastructure` method allows you to access SAR fixed infrastructure data. This method returns a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Retrieving SAR Fixed Infrastructure Data by Tile Coordinates (`get_sar_fixed_infrastructure` with z, x, y) You can retrieve SAR fixed infrastructure data for a specific tile using its zoom level (`z`), x-coordinate (`x`), and y-coordinate (`y`). diff --git a/docs/source/usage-guides/events-api.md b/docs/source/usage-guides/events-api.md index e7b939c..1da9787 100644 --- a/docs/source/usage-guides/events-api.md +++ b/docs/source/usage-guides/events-api.md @@ -2,7 +2,7 @@ Open In Colab -This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about various activities of a vessel, including fishing activity, encounters, port visits, loitering, and gaps in AIS reporting. The Events API allows you to retrieve lists of events, get details for a specific event, and obtain statistics on event occurrences. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/events-api.ipynb) version of this guide with more usage examples. +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about various activities of a vessel, including fishing activity, encounters, port visits, loitering, and gaps in AIS reporting. The [Events API](https://globalfishingwatch.org/our-apis/documentation#events-api) allows you to retrieve lists of events, get details for a specific event, and obtain statistics on event occurrences. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/events-api.ipynb) version of this guide with more usage examples. > **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Events Data Caveats](https://globalfishingwatch.org/our-apis/documentation#how-are-the-events-estimated), 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. @@ -32,6 +32,8 @@ gfw_client = gfw.Client( The `gfw_client.events` object provides methods to retrieve event data and statistics. Each of these methods returns a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Retrieving All Events (`get_all_events`) The `get_all_events()` method allows you to retrieve a list of events based on specified criteria. The `datasets` parameter is mandatory. diff --git a/docs/source/usage-guides/insights-api.md b/docs/source/usage-guides/insights-api.md index c00a76a..840f848 100644 --- a/docs/source/usage-guides/insights-api.md +++ b/docs/source/usage-guides/insights-api.md @@ -2,7 +2,7 @@ Open In Colab -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 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. +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. @@ -32,6 +32,10 @@ gfw_client = gfw.Client( ) ``` +The `gfw_client.insights` object provides methods for retrieving insights data for specified vessels. Each of these methods returns a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. + +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Getting Insights by Vessel (`get_vessel_insights`) The `get_vessel_insights()` method allows you to retrieve aggregated insights for a specific vessel within a given time range. diff --git a/docs/source/usage-guides/references-data-api.md b/docs/source/usage-guides/references-data-api.md index 5ef6589..57927ba 100644 --- a/docs/source/usage-guides/references-data-api.md +++ b/docs/source/usage-guides/references-data-api.md @@ -2,7 +2,7 @@ Open In Colab -This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access reference data, specifically geographic regions. The Reference Data API offers access to static datasets, currently focusing on Exclusive Economic Zones (EEZs), Marine Protected Areas (MPAs), and Regional Fisheries Management Organizations (RFMOs). Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/references-data-api.ipynb) version of this guide with more usage examples. +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access reference data, specifically geographic regions. The [Reference Data API](https://globalfishingwatch.org/our-apis/documentation#regions) offers access to static datasets, currently focusing on Exclusive Economic Zones (EEZs), Marine Protected Areas (MPAs), and Regional Fisheries Management Organizations (RFMOs). Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/references-data-api.ipynb) version of this guide with more usage examples. > **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Reference Data Caveats](https://globalfishingwatch.org/our-apis/documentation#reference-data), 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. @@ -32,6 +32,8 @@ gfw_client = gfw.Client( The `gfw_client.references` object provides methods to retrieve different types of geographic regions. Each of these methods returns a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Retrieving Exclusive Economic Zones (EEZs) To get a list of available Exclusive Economic Zone (EEZ) regions, use the `get_eez_regions()` method: diff --git a/docs/source/usage-guides/vessels-api.md b/docs/source/usage-guides/vessels-api.md index 7160d28..2196890 100644 --- a/docs/source/usage-guides/vessels-api.md +++ b/docs/source/usage-guides/vessels-api.md @@ -2,7 +2,7 @@ Open In Colab -This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about vessels. The Vessels API allows you to search for vessels, retrieve lists of vessels by their IDs, and get detailed information for a specific vessel, drawing from various datasets like identity, authorizations, and ownership. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/vessels-api.ipynb) version of this guide with more usage examples. +This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about vessels. The [Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api) allows you to search for vessels, retrieve lists of vessels by their IDs, and get detailed information for a specific vessel, drawing from various datasets like identity, authorizations, and ownership. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/vessels-api.ipynb) version of this guide with more usage examples. > **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Vessel Data Caveats](https://globalfishingwatch.org/our-apis/documentation#vessel-api-vessel-identity-information), 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. @@ -32,6 +32,8 @@ gfw_client = gfw.Client( The `gfw_client.vessels` object provides methods to search for and retrieve vessel information. Each of these methods returns a `result` object, which offers convenient ways to access the data as Pydantic models using `.data()` or as pandas DataFrames using `.df()`. +> **Tip:** Use [IPython](https://ipython.readthedocs.io/en/stable/) or Python 3.11+ with `python -m asyncio` to run `gfw-api-python-client` code interactively, as these environments support executing `async` / `await` expressions directly in the console. + ## Searching for Vessels (`search_vessels`) The `search_vessels()` method allows you to find vessels based on a query and various filters within specified datasets. diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index 29de3e3..203ffac 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -28,7 +28,7 @@ "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958" }, "source": [ - "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the 4Wings API, which is designed for generating reports and statistics on activities within specified regions." + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access the [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), which is designed for generating reports and statistics on activities within specified regions." ] }, { diff --git a/notebooks/usage-guides/datasets-api.ipynb b/notebooks/usage-guides/datasets-api.ipynb index 364d63c..03fd43f 100644 --- a/notebooks/usage-guides/datasets-api.ipynb +++ b/notebooks/usage-guides/datasets-api.ipynb @@ -28,7 +28,7 @@ "id": "41006fe2-f552-4dfc-b6d0-4b6b46aadf27" }, "source": [ - "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access various datasets available through the Global Fishing Watch API. Currently, it focuses on retrieving SAR (Synthetic Aperture Radar) fixed infrastructure data." + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access various datasets available through the Global Fishing Watch [Datasets API](https://globalfishingwatch.org/our-apis/documentation#datasets-api). Currently, it focuses on retrieving SAR (Synthetic Aperture Radar) fixed infrastructure data." ] }, { diff --git a/notebooks/usage-guides/events-api.ipynb b/notebooks/usage-guides/events-api.ipynb index 556eb4d..bed1978 100644 --- a/notebooks/usage-guides/events-api.ipynb +++ b/notebooks/usage-guides/events-api.ipynb @@ -28,7 +28,7 @@ "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958" }, "source": [ - "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about various activities of a vessel, including fishing activity, encounters, port visits, loitering, and gaps in AIS reporting." + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about various activities of a vessel, including fishing activity, encounters, port visits, loitering, and gaps in AIS reporting through the Global Fishing Watch [Events API](https://globalfishingwatch.org/our-apis/documentation#events-api)." ] }, { diff --git a/notebooks/usage-guides/insights-api.ipynb b/notebooks/usage-guides/insights-api.ipynb index 83e9683..5b7c2ad 100644 --- a/notebooks/usage-guides/insights-api.ipynb +++ b/notebooks/usage-guides/insights-api.ipynb @@ -28,7 +28,7 @@ "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958" }, "source": [ - "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." + "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 through the Global Fishing Watch [Insights API](https://globalfishingwatch.org/our-apis/documentation#insights-api)." ] }, { diff --git a/notebooks/usage-guides/references-data-api.ipynb b/notebooks/usage-guides/references-data-api.ipynb index c6b31e4..1f2d52c 100644 --- a/notebooks/usage-guides/references-data-api.ipynb +++ b/notebooks/usage-guides/references-data-api.ipynb @@ -28,7 +28,7 @@ "id": "5d8e4401-2090-47a0-b3e1-be4d3ba5cc00" }, "source": [ - "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access reference data, specifically geographic regions." + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access reference data, specifically geographic regions through the Global Fishing Watch [Reference Data API](https://globalfishingwatch.org/our-apis/documentation#regions)." ] }, { diff --git a/notebooks/usage-guides/vessels-api.ipynb b/notebooks/usage-guides/vessels-api.ipynb index 9d7a43e..1f6bcc7 100644 --- a/notebooks/usage-guides/vessels-api.ipynb +++ b/notebooks/usage-guides/vessels-api.ipynb @@ -28,7 +28,7 @@ "id": "e9ca2eda-18f1-4f9c-9717-fb1a06423958" }, "source": [ - "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about vessels." + "This guide provides detailed instructions on how to use the [gfw-api-python-client](https://github.com/GlobalFishingWatch/gfw-api-python-client) to access information about vessels through the Global Fishing Watch [Vessels API](https://globalfishingwatch.org/our-apis/documentation#vessels-api)." ] }, { From e5dc35f1d7eb8010f4c3774a587ab22013dcced0 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 13 Jan 2026 07:26:05 +0300 Subject: [PATCH 20/22] docs(fourwings): replace generic data caveats with dataset-specific caveats This: - replace generic data caveats with AIS apparent fishing effort data caveats - replace generic data caveats with AIS vessel presence data caveats - replace generic data caveats with SAR vessel detections data caveats --- docs/source/usage-guides/4wings-api.md | 2 +- notebooks/usage-guides/4wings-api.ipynb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/usage-guides/4wings-api.md b/docs/source/usage-guides/4wings-api.md index d1a8c08..19ff85b 100644 --- a/docs/source/usage-guides/4wings-api.md +++ b/docs/source/usage-guides/4wings-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 the [4Wings API](https://globalfishingwatch.org/our-apis/documentation#map-visualization-4wings-api), which is designed for generating reports and statistics on activities within specified regions. This API is particularly useful for creating data visualizations related to fishing effort and other vessel activities. Here is a [Jupyter Notebook](https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/notebooks/usage-guides/4wings-api.ipynb) version of this guide with more usage examples. -> **Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [AIS Apparent Fishing Effort Data Caveats](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort), [AIS Vessel Presence Data Caveats](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats), [SAR Vessel Detections Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats), 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 diff --git a/notebooks/usage-guides/4wings-api.ipynb b/notebooks/usage-guides/4wings-api.ipynb index 203ffac..b523b61 100644 --- a/notebooks/usage-guides/4wings-api.ipynb +++ b/notebooks/usage-guides/4wings-api.ipynb @@ -36,7 +36,7 @@ "id": "3d31e934-e291-453d-aad9-6e0e61d1318e", "metadata": {}, "source": [ - "**Note:** See the [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [Data Caveats](https://globalfishingwatch.org/our-apis/documentation#data-caveat), 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 [Datasets](https://globalfishingwatch.org/our-apis/documentation#api-dataset), [AIS Apparent Fishing Effort Data Caveats](https://globalfishingwatch.org/our-apis/documentation#apparent-fishing-effort), [AIS Vessel Presence Data Caveats](https://globalfishingwatch.org/our-apis/documentation#ais-vessel-presence-caveats), [SAR Vessel Detections Data Caveats](https://globalfishingwatch.org/our-apis/documentation#sar-vessel-detections-data-caveats), 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." ] }, { From 4bfba1e336ed3ae4544a0c7698a71ef1fd5c036d Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 13 Jan 2026 07:31:02 +0300 Subject: [PATCH 21/22] docs(readme): add workflow guides links to usage and documentation section --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ebc8848..c9bee5e 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ gfw_client = gfw.Client( ) ``` -For step-by-step instructions and examples, see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) and [Usage Guides](https://globalfishingwatch.github.io/gfw-api-python-client/usage-guides/index.html) in the documentation. +For step-by-step instructions and examples, see the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html), [Usage Guides](https://globalfishingwatch.github.io/gfw-api-python-client/usage-guides/index.html), and [Workflow Guides](https://globalfishingwatch.github.io/gfw-api-python-client/workflow-guides/index.html) in the documentation. ## Documentation @@ -82,7 +82,7 @@ The full project documentation is available at [globalfishingwatch.github.io/gfw To get started with the basics, head over to the [Getting Started](https://globalfishingwatch.github.io/gfw-api-python-client/getting-started.html) guide. -For detailed instructions and examples on interacting with the various APIs offered by Global Fishing Watch, explore the [Usage Guides](https://globalfishingwatch.github.io/gfw-api-python-client/usage-guides/index.html) section. +For detailed instructions and examples on interacting with the various APIs offered by Global Fishing Watch, explore the [Usage Guides](https://globalfishingwatch.github.io/gfw-api-python-client/usage-guides/index.html), and [Workflow Guides](https://globalfishingwatch.github.io/gfw-api-python-client/workflow-guides/index.html) sections. For a complete reference of all available classes, methods, and modules, see the [API Reference](https://globalfishingwatch.github.io/gfw-api-python-client/apidocs/index.html) section. From 723d311aa4d5de883e8b236a6e75f8320e73ddc8 Mon Sep 17 00:00:00 2001 From: lykmapipo Date: Tue, 13 Jan 2026 12:39:37 +0300 Subject: [PATCH 22/22] chore(release): bump to v1.4.0 --- CHANGELOG.md | 16 ++ CITATION.cff | 6 +- INSTALLATION.md | 2 +- .../gfwapiclient/gfwapiclient.__version__.rst | 2 +- .../gfwapiclient.client.client.rst | 13 ++ ...ces.bulk_downloads.base.models.request.rst | 172 ++++++++++++++ ...es.bulk_downloads.base.models.response.rst | 215 ++++++++++++++++++ ...t.resources.bulk_downloads.base.models.rst | 17 ++ ...piclient.resources.bulk_downloads.base.rst | 16 ++ ...ources.bulk_downloads.create.endpoints.rst | 52 +++++ ...s.bulk_downloads.create.models.request.rst | 104 +++++++++ ....bulk_downloads.create.models.response.rst | 80 +++++++ ...resources.bulk_downloads.create.models.rst | 17 ++ ...client.resources.bulk_downloads.create.rst | 25 ++ ...ources.bulk_downloads.detail.endpoints.rst | 52 +++++ ....bulk_downloads.detail.models.response.rst | 80 +++++++ ...resources.bulk_downloads.detail.models.rst | 16 ++ ...client.resources.bulk_downloads.detail.rst | 25 ++ ...esources.bulk_downloads.file.endpoints.rst | 52 +++++ ...ces.bulk_downloads.file.models.request.rst | 69 ++++++ ...es.bulk_downloads.file.models.response.rst | 87 +++++++ ...t.resources.bulk_downloads.file.models.rst | 17 ++ ...piclient.resources.bulk_downloads.file.rst | 25 ++ ...esources.bulk_downloads.list.endpoints.rst | 57 +++++ ...ces.bulk_downloads.list.models.request.rst | 90 ++++++++ ...es.bulk_downloads.list.models.response.rst | 80 +++++++ ...t.resources.bulk_downloads.list.models.rst | 17 ++ ...piclient.resources.bulk_downloads.list.rst | 25 ++ ...sources.bulk_downloads.query.endpoints.rst | 71 ++++++ ...lk_downloads.query.models.base.request.rst | 97 ++++++++ ...k_downloads.query.models.base.response.rst | 98 ++++++++ ...urces.bulk_downloads.query.models.base.rst | 17 ++ ...els.fixed_infrastructure_data.response.rst | 149 ++++++++++++ ...query.models.fixed_infrastructure_data.rst | 16 ++ ....resources.bulk_downloads.query.models.rst | 17 ++ ...iclient.resources.bulk_downloads.query.rst | 25 ++ ...ent.resources.bulk_downloads.resources.rst | 102 +++++++++ .../gfwapiclient.resources.bulk_downloads.rst | 53 +++++ .../gfwapiclient/gfwapiclient.resources.rst | 3 +- docs/source/conf.py | 2 +- pyproject.toml | 7 +- src/gfwapiclient/__version__.py | 2 +- 42 files changed, 2077 insertions(+), 11 deletions(-) create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.request.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.endpoints.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.request.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.endpoints.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.endpoints.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.request.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.endpoints.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.request.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.endpoints.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.request.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.resources.rst create mode 100644 docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.rst diff --git a/CHANGELOG.md b/CHANGELOG.md index 588f9d1..b8222fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## v1.4.0 (2026-01-13) + +### Feat + +- **bulk-downloads**: implement bulk report query API endpoints and models +- **bulk-downloads**: implement bulk report API endpoints +- **bulk-downloads**: implement bulk report file API endpoints and models +- **bulk-downloads**: implement bulk report list API endpoints and models +- **bulk-downloads**: implement bulk report detail API endpoints and models +- **bulk-downloads**: implement bulk report create API endpoints and models +- **bulk-downloads**: add base request and response models for Bulk Download API + +### Fix + +- **bulk-downloads**: correct typehints in docstrings + ## v1.3.0 (2025-09-17) ### Feat diff --git a/CITATION.cff b/CITATION.cff index a7d16d5..294d9af 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,4 +1,4 @@ -cff-version: 1.3.0 +cff-version: 1.2.0 title: "GlobalFishingWatch/gfw-api-python-client: Global Fishing Watch APIs Python Client" message: "If you use this software, please cite it using the metadata below." authors: @@ -6,13 +6,13 @@ authors: website: "https://globalfishingwatch.org/" email: "apis@globalfishingwatch.org" abstract: "Python package for accessing data from Global Fishing Watch APIs." -version: "1.3.0" +version: "1.4.0" doi: 10.5281/zenodo.15617432 license: "Apache-2.0" license-url: "https://github.com/GlobalFishingWatch/gfw-api-python-client/blob/develop/LICENSE" repository-code: "https://github.com/GlobalFishingWatch/gfw-api-python-client" url: "https://github.com/GlobalFishingWatch/gfw-api-python-client" -date-released: "2025-09-17" +date-released: "2026-01-13" keywords: - "global fishing watch" - "gfw" diff --git a/INSTALLATION.md b/INSTALLATION.md index 5217519..c02060e 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -127,7 +127,7 @@ print(gfw.__version__) If the installation was successful, you should see the installed version number, for example: ``` -3.0.0 +1.4.0 ``` You can also try a basic import to ensure the package is accessible: diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.__version__.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.__version__.rst index 7c24a73..6a2aa72 100644 --- a/docs/source/apidocs/gfwapiclient/gfwapiclient.__version__.rst +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.__version__.rst @@ -25,6 +25,6 @@ API .. py:data:: __version__ :canonical: gfwapiclient.__version__.__version__ - :value: '1.3.0' + :value: '1.4.0' .. autodoc2-docstring:: gfwapiclient.__version__.__version__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.client.client.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.client.client.rst index 03d326a..a24a01a 100644 --- a/docs/source/apidocs/gfwapiclient/gfwapiclient.client.client.rst +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.client.client.rst @@ -94,6 +94,13 @@ API .. autodoc2-docstring:: gfwapiclient.client.client.Client._datasets + .. py:attribute:: _bulk_downloads + :canonical: gfwapiclient.client.client.Client._bulk_downloads + :type: gfwapiclient.resources.BulkDownloadResource + :value: None + + .. autodoc2-docstring:: gfwapiclient.client.client.Client._bulk_downloads + .. py:attribute:: _references :canonical: gfwapiclient.client.client.Client._references :type: gfwapiclient.resources.ReferenceResource @@ -131,6 +138,12 @@ API .. autodoc2-docstring:: gfwapiclient.client.client.Client.datasets + .. py:property:: bulk_downloads + :canonical: gfwapiclient.client.client.Client.bulk_downloads + :type: gfwapiclient.resources.BulkDownloadResource + + .. autodoc2-docstring:: gfwapiclient.client.client.Client.bulk_downloads + .. py:property:: references :canonical: gfwapiclient.client.client.Client.references :type: gfwapiclient.resources.ReferenceResource diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.request.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.request.rst new file mode 100644 index 0000000..5e1e560 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.request.rst @@ -0,0 +1,172 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.base.models.request` +=================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.base.models.request + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportDataset ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset + :summary: + * - :py:obj:`BulkReportFormat ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat + :summary: + * - :py:obj:`BulkReportGeometry ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry + :summary: + * - :py:obj:`BulkReportRegion ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion + :summary: + * - :py:obj:`BulkReportFileType ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.__all__ + :value: ['BulkReportDataset', 'BulkReportFileType', 'BulkReportFormat', 'BulkReportGeometry', 'BulkReportReg... + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.__all__ + +.. py:class:: BulkReportDataset() + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset + + Bases: :py:obj:`str`, :py:obj:`enum.Enum` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset.__init__ + + .. py:attribute:: FIXED_INFRASTRUCTURE_DATA_LATEST + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset.FIXED_INFRASTRUCTURE_DATA_LATEST + :value: 'public-fixed-infrastructure-data:latest' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset.FIXED_INFRASTRUCTURE_DATA_LATEST + +.. py:class:: BulkReportFormat() + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat + + Bases: :py:obj:`str`, :py:obj:`enum.Enum` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat.__init__ + + .. py:attribute:: CSV + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat.CSV + :value: 'CSV' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat.CSV + + .. py:attribute:: JSON + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat.JSON + :value: 'JSON' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat.JSON + +.. py:class:: BulkReportGeometry(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry + + Bases: :py:obj:`gfwapiclient.base.models.BaseModel` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry.__init__ + + .. py:attribute:: type + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry.type + :type: str + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry.type + + .. py:attribute:: coordinates + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry.coordinates + :type: typing.Any + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry.coordinates + +.. py:class:: BulkReportRegion(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion + + Bases: :py:obj:`gfwapiclient.base.models.BaseModel` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion.__init__ + + .. py:attribute:: dataset + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion.dataset + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion.dataset + + .. py:attribute:: id + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion.id + :type: typing.Optional[typing.Union[str, int]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion.id + +.. py:class:: BulkReportFileType() + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType + + Bases: :py:obj:`str`, :py:obj:`enum.Enum` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.__init__ + + .. py:attribute:: DATA + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.DATA + :value: 'DATA' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.DATA + + .. py:attribute:: README + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.README + :value: 'README' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.README + + .. py:attribute:: GEOM + :canonical: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.GEOM + :value: 'GEOM' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType.GEOM diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.response.rst new file mode 100644 index 0000000..effcd0c --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.response.rst @@ -0,0 +1,215 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.base.models.response` +==================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.base.models.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportStatus ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus + :summary: + * - :py:obj:`BulkReportGeography ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography + :summary: + * - :py:obj:`BulkReportItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.__all__ + :value: ['BulkReportItem'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.__all__ + +.. py:class:: BulkReportStatus() + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus + + Bases: :py:obj:`str`, :py:obj:`enum.Enum` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.__init__ + + .. py:attribute:: PENDING + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.PENDING + :value: 'pending' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.PENDING + + .. py:attribute:: PROCESSING + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.PROCESSING + :value: 'processing' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.PROCESSING + + .. py:attribute:: DONE + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.DONE + :value: 'done' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.DONE + + .. py:attribute:: FAILED + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.FAILED + :value: 'failed' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus.FAILED + +.. py:class:: BulkReportGeography(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography + + Bases: :py:obj:`gfwapiclient.base.models.BaseModel` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.__init__ + + .. py:attribute:: type + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.type + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.type + + .. py:attribute:: dataset + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.dataset + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.dataset + + .. py:attribute:: id + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.id + :type: typing.Optional[typing.Union[str, int]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography.id + +.. py:class:: BulkReportItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem + + Bases: :py:obj:`gfwapiclient.http.models.ResultItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.__init__ + + .. py:attribute:: id + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.id + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.id + + .. py:attribute:: name + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.name + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.name + + .. py:attribute:: file_path + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.file_path + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.file_path + + .. py:attribute:: format + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.format + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.format + + .. py:attribute:: filters + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.filters + :type: typing.Optional[typing.List[str]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.filters + + .. py:attribute:: geom + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.geom + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportGeography] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.geom + + .. py:attribute:: status + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.status + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.status + + .. py:attribute:: owner_id + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.owner_id + :type: typing.Optional[typing.Union[str, int]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.owner_id + + .. py:attribute:: owner_type + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.owner_type + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.owner_type + + .. py:attribute:: created_at + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.created_at + :type: typing.Optional[datetime.datetime] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.created_at + + .. py:attribute:: updated_at + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.updated_at + :type: typing.Optional[datetime.datetime] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.updated_at + + .. py:attribute:: file_size + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.file_size + :type: typing.Optional[float] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.file_size + + .. py:method:: empty_datetime_str_to_none(value: typing.Any) -> typing.Optional[typing.Any] + :canonical: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.empty_datetime_str_to_none + :classmethod: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem.empty_datetime_str_to_none diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.rst new file mode 100644 index 0000000..afcd13a --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.models.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.base.models` +=========================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.base.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base.models + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.base.models.request + gfwapiclient.resources.bulk_downloads.base.models.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.rst new file mode 100644 index 0000000..db404ab --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.base.rst @@ -0,0 +1,16 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.base` +==================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.base + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.base + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.base.models diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.endpoints.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.endpoints.rst new file mode 100644 index 0000000..706ac88 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.endpoints.rst @@ -0,0 +1,52 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.create.endpoints` +================================================================ + +.. py:module:: gfwapiclient.resources.bulk_downloads.create.endpoints + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportCreateEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints.BulkReportCreateEndPoint + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.create.endpoints.__all__ + :value: ['BulkReportCreateEndPoint'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints.__all__ + +.. py:class:: BulkReportCreateEndPoint(*, request_body: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.create.endpoints.BulkReportCreateEndPoint + + Bases: :py:obj:`gfwapiclient.http.endpoints.PostEndPoint`\ [\ :py:obj:`gfwapiclient.http.models.RequestParams`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints.BulkReportCreateEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.endpoints.BulkReportCreateEndPoint.__init__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.request.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.request.rst new file mode 100644 index 0000000..d1be76b --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.request.rst @@ -0,0 +1,104 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.create.models.request` +===================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.create.models.request + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportCreateBody ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.__all__ + :summary: + * - :py:obj:`BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.__all__ + :value: ['BulkReportCreateBody'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.__all__ + +.. py:data:: BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE + :type: typing.Final[str] + :value: 'Create bulk report request body validation failed.' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BULK_REPORT_CREATE_BODY_VALIDATION_ERROR_MESSAGE + +.. py:class:: BulkReportCreateBody(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody + + Bases: :py:obj:`gfwapiclient.http.models.RequestBody` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.__init__ + + .. py:attribute:: name + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.name + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.name + + .. py:attribute:: dataset + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.dataset + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.dataset + + .. py:attribute:: geojson + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.geojson + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.geojson + + .. py:attribute:: format + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.format + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.format + + .. py:attribute:: region + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.region + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.region + + .. py:attribute:: filters + :canonical: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.filters + :type: typing.Optional[typing.List[str]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody.filters diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.response.rst new file mode 100644 index 0000000..87543a9 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.response.rst @@ -0,0 +1,80 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.create.models.response` +====================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.create.models.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportCreateItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem + :summary: + * - :py:obj:`BulkReportCreateResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.create.models.response.__all__ + :value: ['BulkReportCreateItem', 'BulkReportCreateResult'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.__all__ + +.. py:class:: BulkReportCreateItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem.__init__ + +.. py:class:: BulkReportCreateResult(data: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem) + :canonical: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult + + Bases: :py:obj:`gfwapiclient.http.models.Result`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult._data + :type: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateItem + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult._data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.rst new file mode 100644 index 0000000..e5611bc --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.models.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.create.models` +============================================================= + +.. py:module:: gfwapiclient.resources.bulk_downloads.create.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create.models + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.create.models.request + gfwapiclient.resources.bulk_downloads.create.models.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.rst new file mode 100644 index 0000000..2208e32 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.create.rst @@ -0,0 +1,25 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.create` +====================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.create + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.create + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.create.models + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.create.endpoints diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.endpoints.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.endpoints.rst new file mode 100644 index 0000000..1c640b7 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.endpoints.rst @@ -0,0 +1,52 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.detail.endpoints` +================================================================ + +.. py:module:: gfwapiclient.resources.bulk_downloads.detail.endpoints + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportDetailEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints.BulkReportDetailEndPoint + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.detail.endpoints.__all__ + :value: ['BulkReportDetailEndPoint'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints.__all__ + +.. py:class:: BulkReportDetailEndPoint(*, bulk_report_id: str, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.detail.endpoints.BulkReportDetailEndPoint + + Bases: :py:obj:`gfwapiclient.http.endpoints.GetEndPoint`\ [\ :py:obj:`gfwapiclient.http.models.RequestParams`\ , :py:obj:`gfwapiclient.http.models.RequestBody`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints.BulkReportDetailEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.endpoints.BulkReportDetailEndPoint.__init__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.response.rst new file mode 100644 index 0000000..c997a5a --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.response.rst @@ -0,0 +1,80 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.detail.models.response` +====================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.detail.models.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportDetailItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem + :summary: + * - :py:obj:`BulkReportDetailResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.detail.models.response.__all__ + :value: ['BulkReportDetailItem', 'BulkReportDetailResult'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.__all__ + +.. py:class:: BulkReportDetailItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem.__init__ + +.. py:class:: BulkReportDetailResult(data: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem) + :canonical: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult + + Bases: :py:obj:`gfwapiclient.http.models.Result`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult._data + :type: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailItem + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult._data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.rst new file mode 100644 index 0000000..33a4c1d --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.models.rst @@ -0,0 +1,16 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.detail.models` +============================================================= + +.. py:module:: gfwapiclient.resources.bulk_downloads.detail.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail.models + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.detail.models.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.rst new file mode 100644 index 0000000..bd82483 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.detail.rst @@ -0,0 +1,25 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.detail` +====================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.detail + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.detail + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.detail.models + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.detail.endpoints diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.endpoints.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.endpoints.rst new file mode 100644 index 0000000..ddd8b1d --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.endpoints.rst @@ -0,0 +1,52 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.file.endpoints` +============================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.file.endpoints + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportFileEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints.BulkReportFileEndPoint + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.file.endpoints.__all__ + :value: ['BulkReportFileEndPoint'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints.__all__ + +.. py:class:: BulkReportFileEndPoint(*, bulk_report_id: str, request_params: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.file.endpoints.BulkReportFileEndPoint + + Bases: :py:obj:`gfwapiclient.http.endpoints.GetEndPoint`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams`\ , :py:obj:`gfwapiclient.http.models.RequestBody`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints.BulkReportFileEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.endpoints.BulkReportFileEndPoint.__init__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.request.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.request.rst new file mode 100644 index 0000000..648642b --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.request.rst @@ -0,0 +1,69 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.file.models.request` +=================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.file.models.request + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportFileParams ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.__all__ + :summary: + * - :py:obj:`BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.file.models.request.__all__ + :value: ['BulkReportFileParams'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.__all__ + +.. py:data:: BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE + :canonical: gfwapiclient.resources.bulk_downloads.file.models.request.BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE + :type: typing.Final[str] + :value: 'Get bulk report file download URL request parameters validation failed.' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BULK_REPORT_FILE_PARAMS_VALIDATION_ERROR_MESSAGE + +.. py:class:: BulkReportFileParams(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams + + Bases: :py:obj:`gfwapiclient.http.models.RequestParams` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams.__init__ + + .. py:attribute:: file + :canonical: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams.file + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams.file diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.response.rst new file mode 100644 index 0000000..cd6e1fd --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.response.rst @@ -0,0 +1,87 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.file.models.response` +==================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.file.models.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportFileItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem + :summary: + * - :py:obj:`BulkReportFileResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.__all__ + :value: ['BulkReportFileItem', 'BulkReportFileResult'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.__all__ + +.. py:class:: BulkReportFileItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem + + Bases: :py:obj:`gfwapiclient.http.models.ResultItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem.__init__ + + .. py:attribute:: url + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem.url + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem.url + +.. py:class:: BulkReportFileResult(data: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem) + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult + + Bases: :py:obj:`gfwapiclient.http.models.Result`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult._data + :type: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileItem + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult._data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.rst new file mode 100644 index 0000000..04de6be --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.models.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.file.models` +=========================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.file.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file.models + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.file.models.request + gfwapiclient.resources.bulk_downloads.file.models.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.rst new file mode 100644 index 0000000..1d99c4c --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.file.rst @@ -0,0 +1,25 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.file` +==================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.file + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.file + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.file.models + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.file.endpoints diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.endpoints.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.endpoints.rst new file mode 100644 index 0000000..725ab77 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.endpoints.rst @@ -0,0 +1,57 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.list.endpoints` +============================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.list.endpoints + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportListEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.list.endpoints.__all__ + :value: ['BulkReportListEndPoint'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.__all__ + +.. py:class:: BulkReportListEndPoint(*, request_params: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint + + Bases: :py:obj:`gfwapiclient.http.endpoints.GetEndPoint`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams`\ , :py:obj:`gfwapiclient.http.models.RequestBody`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint.__init__ + + .. py:method:: _transform_response_data(*, body: typing.Union[typing.List[typing.Dict[str, typing.Any]], typing.Dict[str, typing.Any]]) -> typing.Union[typing.List[typing.Dict[str, typing.Any]], typing.Dict[str, typing.Any]] + :canonical: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint._transform_response_data + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.endpoints.BulkReportListEndPoint._transform_response_data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.request.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.request.rst new file mode 100644 index 0000000..d40233d --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.request.rst @@ -0,0 +1,90 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.list.models.request` +=================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.list.models.request + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportListParams ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.__all__ + :summary: + * - :py:obj:`BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.__all__ + :value: ['BulkReportListParams'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.__all__ + +.. py:data:: BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE + :type: typing.Final[str] + :value: 'Get bulk reports request parameters validation failed.' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BULK_REPORT_LIST_PARAMS_VALIDATION_ERROR_MESSAGE + +.. py:class:: BulkReportListParams(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams + + Bases: :py:obj:`gfwapiclient.http.models.RequestParams` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.__init__ + + .. py:attribute:: limit + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.limit + :type: typing.Optional[int] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.limit + + .. py:attribute:: offset + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.offset + :type: typing.Optional[int] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.offset + + .. py:attribute:: sort + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.sort + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.sort + + .. py:attribute:: status + :canonical: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.status + :type: typing.Optional[gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams.status diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.response.rst new file mode 100644 index 0000000..861f7f9 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.response.rst @@ -0,0 +1,80 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.list.models.response` +==================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.list.models.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportListItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem + :summary: + * - :py:obj:`BulkReportListResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.list.models.response.__all__ + :value: ['BulkReportListItem', 'BulkReportListResult'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.__all__ + +.. py:class:: BulkReportListItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem.__init__ + +.. py:class:: BulkReportListResult(data: typing.List[gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem]) + :canonical: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult + + Bases: :py:obj:`gfwapiclient.http.models.Result`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult._data + :type: typing.List[gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult._data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.rst new file mode 100644 index 0000000..0a0edb1 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.models.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.list.models` +=========================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.list.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list.models + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.list.models.request + gfwapiclient.resources.bulk_downloads.list.models.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.rst new file mode 100644 index 0000000..0060d40 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.list.rst @@ -0,0 +1,25 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.list` +==================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.list + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.list + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.list.models + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.list.endpoints diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.endpoints.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.endpoints.rst new file mode 100644 index 0000000..1cb5e00 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.endpoints.rst @@ -0,0 +1,71 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.endpoints` +=============================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.endpoints + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportQueryEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint + :summary: + * - :py:obj:`BulkFixedInfrastructureDataQueryEndPoint ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkFixedInfrastructureDataQueryEndPoint + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.query.endpoints.__all__ + :value: ['BulkFixedInfrastructureDataQueryEndPoint', 'BulkReportQueryEndPoint'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.__all__ + +.. py:class:: BulkReportQueryEndPoint(*, bulk_report_id: str, request_params: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams, result_item_class: typing.Type[gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT], result_class: typing.Type[gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryResultT], http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint + + Bases: :py:obj:`gfwapiclient.http.endpoints.GetEndPoint`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams`\ , :py:obj:`gfwapiclient.http.models.RequestBody`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryResultT`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint.__init__ + + .. py:method:: _transform_response_data(*, body: typing.Union[typing.List[typing.Dict[str, typing.Any]], typing.Dict[str, typing.Any]]) -> typing.Union[typing.List[typing.Dict[str, typing.Any]], typing.Dict[str, typing.Any]] + :canonical: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint._transform_response_data + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint._transform_response_data + +.. py:class:: BulkFixedInfrastructureDataQueryEndPoint(*, bulk_report_id: str, request_params: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkFixedInfrastructureDataQueryEndPoint + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.query.endpoints.BulkReportQueryEndPoint`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem`\ , :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkFixedInfrastructureDataQueryEndPoint + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.endpoints.BulkFixedInfrastructureDataQueryEndPoint.__init__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.request.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.request.rst new file mode 100644 index 0000000..760bc3d --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.request.rst @@ -0,0 +1,97 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models.base.request` +========================================================================= + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models.base.request + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportQueryParams ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.__all__ + :summary: + * - :py:obj:`BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.__all__ + :value: ['BulkReportQueryParams'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.__all__ + +.. py:data:: BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE + :type: typing.Final[str] + :value: 'Query bulk report request parameters validation failed.' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BULK_REPORT_QUERY_PARAMS_VALIDATION_ERROR_MESSAGE + +.. py:class:: BulkReportQueryParams(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams + + Bases: :py:obj:`gfwapiclient.http.models.RequestParams` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.__init__ + + .. py:attribute:: indexed_fields + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.indexed_fields + :type: typing.ClassVar[typing.Optional[typing.List[str]]] + :value: ['includes'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.indexed_fields + + .. py:attribute:: limit + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.limit + :type: typing.Optional[int] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.limit + + .. py:attribute:: offset + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.offset + :type: typing.Optional[int] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.offset + + .. py:attribute:: sort + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.sort + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.sort + + .. py:attribute:: includes + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.includes + :type: typing.Optional[typing.List[str]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams.includes diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.response.rst new file mode 100644 index 0000000..d1651a0 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.response.rst @@ -0,0 +1,98 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models.base.response` +========================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models.base.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkReportQueryItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryItem + :summary: + * - :py:obj:`BulkReportQueryResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.__all__ + :summary: + * - :py:obj:`_BulkReportQueryItemT ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT + :summary: + * - :py:obj:`_BulkReportQueryResultT ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryResultT + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response.__all__ + :value: ['BulkReportQueryItem', 'BulkReportQueryResult', '_BulkReportQueryItemT', '_BulkReportQueryResultT'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.__all__ + +.. py:class:: BulkReportQueryItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryItem + + Bases: :py:obj:`gfwapiclient.http.models.ResultItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryItem.__init__ + +.. py:data:: _BulkReportQueryItemT + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT + :value: 'TypeVar(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT + +.. py:class:: BulkReportQueryResult(data: typing.List[gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT]) + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult + + Bases: :py:obj:`gfwapiclient.http.models.Result`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult._data + :type: typing.List[gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryItemT] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult._data + +.. py:data:: _BulkReportQueryResultT + :canonical: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryResultT + :value: 'TypeVar(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base.response._BulkReportQueryResultT diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.rst new file mode 100644 index 0000000..75b82ce --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.base.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models.base` +================================================================= + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models.base + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.base + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.query.models.base.request + gfwapiclient.resources.bulk_downloads.query.models.base.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.rst new file mode 100644 index 0000000..760e679 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.rst @@ -0,0 +1,149 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response` +=============================================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkFixedInfrastructureDataQueryItem ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem + :summary: + * - :py:obj:`BulkFixedInfrastructureDataQueryResult ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.__all__ + :value: ['BulkFixedInfrastructureDataQueryItem', 'BulkFixedInfrastructureDataQueryResult'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.__all__ + +.. py:class:: BulkFixedInfrastructureDataQueryItem(/, **data: typing.Any) + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryItem` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.__init__ + + .. py:attribute:: detection_id + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.detection_id + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.detection_id + + .. py:attribute:: detection_date + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.detection_date + :type: typing.Optional[datetime.datetime] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.detection_date + + .. py:attribute:: structure_id + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_id + :type: typing.Optional[typing.Union[str, int]] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_id + + .. py:attribute:: lat + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.lat + :type: typing.Optional[float] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.lat + + .. py:attribute:: lon + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.lon + :type: typing.Optional[float] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.lon + + .. py:attribute:: structure_start_date + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_start_date + :type: typing.Optional[datetime.datetime] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_start_date + + .. py:attribute:: structure_end_date + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_end_date + :type: typing.Optional[datetime.datetime] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.structure_end_date + + .. py:attribute:: label + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.label + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.label + + .. py:attribute:: label_confidence + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.label_confidence + :type: typing.Optional[str] + :value: 'Field(...)' + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.label_confidence + + .. py:method:: empty_datetime_str_to_none(value: typing.Any) -> typing.Optional[typing.Any] + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.empty_datetime_str_to_none + :classmethod: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem.empty_datetime_str_to_none + +.. py:class:: BulkFixedInfrastructureDataQueryResult(data: typing.List[gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem]) + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult + + Bases: :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.base.response.BulkReportQueryResult`\ [\ :py:obj:`gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem`\ ] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult.__init__ + + .. py:attribute:: _result_item_class + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult._result_item_class + :type: typing.Type[gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult._result_item_class + + .. py:attribute:: _data + :canonical: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult._data + :type: typing.List[gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryItem] + :value: None + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult._data diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.rst new file mode 100644 index 0000000..ea1ce2c --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.rst @@ -0,0 +1,16 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data` +====================================================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data + :allowtitles: + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.rst new file mode 100644 index 0000000..a5e7a8d --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.models.rst @@ -0,0 +1,17 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query.models` +============================================================ + +.. py:module:: gfwapiclient.resources.bulk_downloads.query.models + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query.models + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data + gfwapiclient.resources.bulk_downloads.query.models.base diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.rst new file mode 100644 index 0000000..6c7b7ac --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.query.rst @@ -0,0 +1,25 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.query` +===================================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads.query + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.query + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.query.models + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.query.endpoints diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.resources.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.resources.rst new file mode 100644 index 0000000..ed98f47 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.resources.rst @@ -0,0 +1,102 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads.resources` +========================================================= + +.. py:module:: gfwapiclient.resources.bulk_downloads.resources + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources + :allowtitles: + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`BulkDownloadResource ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource + :summary: + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.resources.__all__ + :value: ['BulkDownloadResource'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.__all__ + +.. py:class:: BulkDownloadResource(*, http_client: gfwapiclient.http.client.HTTPClient) + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource + + Bases: :py:obj:`gfwapiclient.http.resources.BaseResource` + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource + + .. rubric:: Initialization + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.__init__ + + .. py:method:: create_bulk_report(*, name: str, dataset: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset, str]] = None, geojson: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry, typing.Dict[str, typing.Any]]] = None, format: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat, str]] = None, region: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion, typing.Dict[str, typing.Any]]] = None, filters: typing.Optional[typing.List[str]] = None, **kwargs: typing.Dict[str, typing.Any]) -> gfwapiclient.resources.bulk_downloads.create.models.response.BulkReportCreateResult + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.create_bulk_report + :async: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.create_bulk_report + + .. py:method:: get_bulk_report_by_id(*, id: str, **kwargs: typing.Dict[str, typing.Any]) -> gfwapiclient.resources.bulk_downloads.detail.models.response.BulkReportDetailResult + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_bulk_report_by_id + :async: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_bulk_report_by_id + + .. py:method:: get_all_bulk_reports(*, limit: typing.Optional[int] = None, offset: typing.Optional[int] = None, sort: typing.Optional[str] = None, status: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus, str]] = None, **kwargs: typing.Dict[str, typing.Any]) -> gfwapiclient.resources.bulk_downloads.list.models.response.BulkReportListResult + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_all_bulk_reports + :async: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_all_bulk_reports + + .. py:method:: get_bulk_report_file_download_url(*, id: str, file: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType, str]] = None, **kwargs: typing.Dict[str, typing.Any]) -> gfwapiclient.resources.bulk_downloads.file.models.response.BulkReportFileResult + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_bulk_report_file_download_url + :async: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.get_bulk_report_file_download_url + + .. py:method:: query_bulk_fixed_infrastructure_data_report(*, id: str, limit: typing.Optional[int] = None, offset: typing.Optional[int] = None, sort: typing.Optional[str] = None, includes: typing.Optional[typing.List[str]] = None, **kwargs: typing.Dict[str, typing.Any]) -> gfwapiclient.resources.bulk_downloads.query.models.fixed_infrastructure_data.response.BulkFixedInfrastructureDataQueryResult + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.query_bulk_fixed_infrastructure_data_report + :async: + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource.query_bulk_fixed_infrastructure_data_report + + .. py:method:: _prepare_create_bulk_report_request_body(*, name: str, dataset: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportDataset, str]] = None, geojson: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportGeometry, typing.Dict[str, typing.Any]]] = None, format: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFormat, str]] = None, region: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportRegion, typing.Dict[str, typing.Any]]] = None, filters: typing.Optional[typing.List[str]] = None) -> gfwapiclient.resources.bulk_downloads.create.models.request.BulkReportCreateBody + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_create_bulk_report_request_body + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_create_bulk_report_request_body + + .. py:method:: _prepare_get_all_bulk_report_params(*, limit: typing.Optional[int] = None, offset: typing.Optional[int] = None, sort: typing.Optional[str] = None, status: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.response.BulkReportStatus, str]] = None) -> gfwapiclient.resources.bulk_downloads.list.models.request.BulkReportListParams + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_get_all_bulk_report_params + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_get_all_bulk_report_params + + .. py:method:: _prepare_get_bulk_report_file_download_url_params(*, file: typing.Optional[typing.Union[gfwapiclient.resources.bulk_downloads.base.models.request.BulkReportFileType, str]] = None) -> gfwapiclient.resources.bulk_downloads.file.models.request.BulkReportFileParams + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_get_bulk_report_file_download_url_params + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_get_bulk_report_file_download_url_params + + .. py:method:: _prepare_query_bulk_report_params(*, limit: typing.Optional[int] = None, offset: typing.Optional[int] = None, sort: typing.Optional[str] = None, includes: typing.Optional[typing.List[str]] = None) -> gfwapiclient.resources.bulk_downloads.query.models.base.request.BulkReportQueryParams + :canonical: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_query_bulk_report_params + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.resources.BulkDownloadResource._prepare_query_bulk_report_params diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.rst new file mode 100644 index 0000000..6362ca5 --- /dev/null +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.bulk_downloads.rst @@ -0,0 +1,53 @@ +:py:mod:`gfwapiclient.resources.bulk_downloads` +=============================================== + +.. py:module:: gfwapiclient.resources.bulk_downloads + +.. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads + :allowtitles: + +Subpackages +----------- + +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gfwapiclient.resources.bulk_downloads.file + gfwapiclient.resources.bulk_downloads.detail + gfwapiclient.resources.bulk_downloads.list + gfwapiclient.resources.bulk_downloads.query + gfwapiclient.resources.bulk_downloads.create + gfwapiclient.resources.bulk_downloads.base + +Submodules +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + gfwapiclient.resources.bulk_downloads.resources + +Package Contents +---------------- + +Data +~~~~ + +.. list-table:: + :class: autosummary longtable + :align: left + + * - :py:obj:`__all__ ` + - .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.__all__ + :summary: + +API +~~~ + +.. py:data:: __all__ + :canonical: gfwapiclient.resources.bulk_downloads.__all__ + :value: ['BulkDownloadResource'] + + .. autodoc2-docstring:: gfwapiclient.resources.bulk_downloads.__all__ diff --git a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.rst b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.rst index f5a4f27..0d4b71e 100644 --- a/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.rst +++ b/docs/source/apidocs/gfwapiclient/gfwapiclient.resources.rst @@ -16,6 +16,7 @@ Subpackages gfwapiclient.resources.insights gfwapiclient.resources.vessels gfwapiclient.resources.references + gfwapiclient.resources.bulk_downloads gfwapiclient.resources.datasets gfwapiclient.resources.events gfwapiclient.resources.fourwings @@ -39,6 +40,6 @@ API .. py:data:: __all__ :canonical: gfwapiclient.resources.__all__ - :value: ['DatasetResource', 'EventResource', 'FourWingsResource', 'InsightResource', 'ReferenceResource', 'V... + :value: ['BulkDownloadResource', 'DatasetResource', 'EventResource', 'FourWingsResource', 'InsightResource',... .. autodoc2-docstring:: gfwapiclient.resources.__all__ diff --git a/docs/source/conf.py b/docs/source/conf.py index 452f9e5..bff4053 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ project = "Global Fishing Watch API Client" copyright = "2025, Global Fishing Watch" author = "Global Fishing Watch" -release = "1.0.1" +release = "1.4.0" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index ffaaa5b..ffb229a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" # Project metadata. [project] name = "gfw-api-python-client" -version = "1.3.0" +version = "1.4.0" description = "Python package for accessing data from Global Fishing Watch APIs." readme = "README.md" requires-python = ">=3.11" @@ -237,10 +237,11 @@ exclude_lines = [ [tool.commitizen] name = "cz_conventional_commits" -version = "1.3.0" +version = "1.4.0" version_files = [ "pyproject.toml:version", - "src/gfwapiclient/__version__.py", + "src/gfwapiclient/__version__.py:__version__", + "docs/source/conf.py:release", "CITATION.cff:version", ] version_provider = "commitizen" diff --git a/src/gfwapiclient/__version__.py b/src/gfwapiclient/__version__.py index 1848333..65a6f0b 100644 --- a/src/gfwapiclient/__version__.py +++ b/src/gfwapiclient/__version__.py @@ -1,3 +1,3 @@ """Global Fishing Watch (GFW) API Python Client - Version and Metadata.""" -__version__ = "1.3.0" +__version__ = "1.4.0"