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
15 changes: 8 additions & 7 deletions docs/upload.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,13 +349,14 @@ To force a fresh upload (ignoring any existing state), simply delete the state f

The SDK raises specific exceptions for common error cases:

| Exception | Cause |
|-----------|-------|
| `FileNotFoundError` | The specified file path does not exist |
| `ValidationError` | Invalid `DatasetSubmission` or required string inputs |
| `ValueError` | Missing or invalid required parameter |
| `PermissionError` | API key is invalid or lacks permissions |
| `RuntimeError` | Rate limit exceeded or upload failed |
| Exception | Cause |
|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `FileNotFoundError` | The specified file path does not exist |
| `ValidationError` | Invalid `DatasetSubmission` or required string inputs |
| `ValueError` | Missing or invalid required parameter |
| `AuthenticationError` | The API key is invalid, expired or revoked |
| `PermissionError` | When downloading: You have not agreed to the T&C of the dataset. When uploading: your organization is not approved to upload datasets, or the API key was created before the approval was granted |
| `RuntimeError` | Rate limit exceeded or upload failed |

## Using the DatasetSubmission Model

Expand Down
6 changes: 6 additions & 0 deletions src/datacollective/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
load_dataset,
save_dataset_to_disk,
)
from datacollective.errors import (
AuthenticationError,
RateLimitError,
)
from datacollective.models import (
DatasetDetails,
DatasetSubmission,
Expand Down Expand Up @@ -36,6 +40,8 @@
"License",
"Task",
"Visibility",
"AuthenticationError",
"RateLimitError",
"__version__",
]

Expand Down
18 changes: 15 additions & 3 deletions src/datacollective/api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def _send_api_request(

Raises:
FileNotFoundError: If the resource is not found (404).
AuthenticationError: If the API key is not accepted (401).
PermissionError: If access is denied (403).
RateLimitError: If rate limit is exceeded (429).
ValueError: If API key is missing when authentication is required.
Expand Down Expand Up @@ -95,12 +96,23 @@ def _send_api_request(
f"Resource not found: {method.upper()} {url}"
+ (f" — {detail}" if detail else "")
)
if resp.status_code == 401:
from datacollective.errors import AuthenticationError

detail = _extract_error_detail(resp)
raise AuthenticationError(
f"Authentication failed. The API key in `{ENV_API_KEY}` is invalid, expired or revoked."
" Create a new key on the MDC platform (https://mozilladatacollective.com/api-reference)."
+ (f"\n{detail}" if detail else "")
)
if resp.status_code == 403:
detail = _extract_error_detail(resp)
raise PermissionError(
f"Access denied. If the dataset is public, make sure you have read thoroughly and agreed"
" to the dataset's Terms & Conditions in its respective page on the MDC platform before downloading. \n"
f"{detail}"
"Access denied. When downloading, make sure you have read thoroughly and agreed to the dataset's"
" Terms & Conditions in its respective page on the MDC platform before downloading."
"When uploading, this means your organization is not approved to upload"
" datasets yet, or the API key was created before the approval was granted."
+ (f"\n{detail}" if detail else "")
)
if resp.status_code == 429:
from datacollective.errors import RateLimitError
Expand Down
4 changes: 4 additions & 0 deletions src/datacollective/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class MissingDependencyError(ImportError):
"""Raised when an optional dependency required for a feature is not installed."""


class AuthenticationError(RuntimeError):
"""Raised when the MDC API responds with HTTP 401."""


class RateLimitError(RuntimeError):
"""Raised when the MDC API responds with HTTP 429."""

Expand Down
Loading