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
17 changes: 17 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/create/__init__.py
Original file line number Diff line number Diff line change
@@ -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
"""
58 changes: 58 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/create/endpoints.py
Original file line number Diff line number Diff line change
@@ -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,
)
Original file line number Diff line number Diff line change
@@ -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
"""
66 changes: 66 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/create/models/request.py
Original file line number Diff line number Diff line change
@@ -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")
Original file line number Diff line number Diff line change
@@ -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)
39 changes: 39 additions & 0 deletions tests/fixtures/bulk_downloads/bulk_report_create_request_body.json
Original file line number Diff line number Diff line change
@@ -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
]
]
]
}
}
16 changes: 16 additions & 0 deletions tests/resources/bulk_downloads/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/create/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.create`."""
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/create/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.create.models`."""
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
@@ -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
Loading