Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/__init__.py
Original file line number Diff line number Diff line change
@@ -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
"""
15 changes: 15 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/base/__init__.py
Original file line number Diff line number Diff line change
@@ -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
"""
16 changes: 16 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -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
"""
133 changes: 133 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/base/models/request.py
Original file line number Diff line number Diff line change
@@ -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"
171 changes: 171 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/base/models/response.py
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions tests/fixtures/bulk_downloads/bulk_report_item.json
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads`."""
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.base`."""
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.base.models`."""
Loading