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/detail/__init__.py
Original file line number Diff line number Diff line change
@@ -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
"""
57 changes: 57 additions & 0 deletions src/gfwapiclient/resources/bulk_downloads/detail/endpoints.py
Original file line number Diff line number Diff line change
@@ -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,
)
Original file line number Diff line number Diff line change
@@ -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
"""
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/detail/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.detail`."""
1 change: 1 addition & 0 deletions tests/resources/bulk_downloads/detail/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for `gfwapiclient.resources.bulk_downloads.detail.models`."""
Original file line number Diff line number Diff line change
@@ -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
59 changes: 59 additions & 0 deletions tests/resources/bulk_downloads/detail/test_endpoints.py
Original file line number Diff line number Diff line change
@@ -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()