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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# eve-api

[![CI](https://github.com/FrontierDevelopmentLab/eve-api/actions/workflows/main.yml/badge.svg)](https://github.com/FrontierDevelopmentLab/eve-api/actions/workflows/main.yml)
[![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/FrontierDevelopmentLab/eve-api)
[![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)

Minimal authenticated HTTP client for the EVE (Earth Virtual Expert) API.

Provides login, automatic JWT token refresh, and generic HTTP methods that return plain dicts. No domain-specific wrappers or Pydantic models.
Expand Down
2 changes: 1 addition & 1 deletion src/eve_api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ def _handle_error(response: httpx.Response) -> None:
message = response.text or f"HTTP {status}"

if status == HTTPStatus.NOT_FOUND:
raise NotFoundError("resource", "unknown")
raise NotFoundError(message)
if status == HTTPStatus.FORBIDDEN:
raise ForbiddenError(message)
if status == HTTPStatus.BAD_REQUEST:
Expand Down
15 changes: 10 additions & 5 deletions src/eve_api/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,22 @@ def __init__(
class NotFoundError(APIError):
"""Raised when a requested resource is not found (404)."""

def __init__(self, resource: str, resource_id: str) -> None:
def __init__(
self,
message: str = "Resource not found",
details: dict[str, Any] | None = None,
) -> None:
"""Initialise the not found error.

Args:
resource: Type of resource (e.g., 'conversation', 'document').
resource_id: ID of the resource that was not found.
message: Human-readable error message (typically the server's
``detail`` field).
details: Additional error details from the response body.
"""
super().__init__(
f"{resource.title()} not found: {resource_id}",
message,
status_code=HTTPStatus.NOT_FOUND,
details={"resource": resource, "id": resource_id},
details=details,
)


Expand Down
2 changes: 1 addition & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ async def test_404_raises_not_found(mock_api, authenticated_client: EVEClient):
)
)

with pytest.raises(NotFoundError) as exc_info:
with pytest.raises(NotFoundError, match="Not found") as exc_info:
await authenticated_client.get("/conversations/missing")

assert exc_info.value.status_code == HTTPStatus.NOT_FOUND
Expand Down
Loading