Skip to main content

Official Python SDK for Frekil API

Project description

Frekil SDK

The official Python SDK for the Frekil API.

Installation

pip install frekil

Usage

Authentication

To use the SDK, you'll need an API key from your Frekil account:

from frekil import FrekilClient

# Initialize the client with your API key
client = FrekilClient(api_key="your-api-key")

# Optionally specify a custom base URL (e.g., for development)
client = FrekilClient(
    api_key="your-api-key",
    base_url="https://dev.notatehq.com/api/sdk"
)

Working with Projects

List Projects

Get all projects the authenticated user has access to:

# Get all projects
projects = client.projects.list()

# Example response:
# [
#     {
#         "id": "uuid",
#         "name": "Project Name",
#         "description": "Project Description",
#         "role": "ADMIN",  # User's role in the project
#         "created_at": "2024-03-21T10:00:00Z",
#         "updated_at": "2024-03-21T10:00:00Z",
#         "is_ct_scan": true,
#         "tags": ["tag1", "tag2"]
#     },
#     ...
# ]

Get Project Membership

Get membership details for a specific project including user roles and status:

# Get project membership
project_id = "project-uuid"
memberships = client.projects.get_membership(project_id)

# Example response:
# [
#     {
#         "user_id": "uuid",
#         "email": "user@example.com",
#         "name": "User Name",  # Full name or email if name not set
#         "role": "ADMIN",      # User's role in the project
#         "percentage": 100,    # User's allocation percentage
#         "is_active": true,    # Whether the user is active
#         "is_project_admin": true,  # Whether user is project admin
#         "created_at": "2024-03-21T10:00:00Z",
#         "updated_at": "2024-03-21T10:00:00Z"
#     },
#     ...
# ]

Get Project Images

Get all images in a project:

# Get project images
project_id = "project-uuid"
images = client.projects.get_images(project_id)

# Example response:
# [
#     {
#         "id": "images/image1.dcm",  # Full image key
#         "filename": "image1.dcm",   # Just the filename
#         "created_at": "2024-03-21T10:00:00Z",
#         "updated_at": "2024-03-21T10:00:00Z"
#     },
#     ...
# ]

Get Project Allocations

Get all allocations in a project, including user roles for both annotators and reviewers:

# Get project allocations
project_id = "project-uuid"
allocations = client.projects.get_allocations(project_id)

# Example response:
# [
#     {
#         "allocation_id": "uuid",
#         "image_id": "images/image1.dcm",  # Full image key
#         "image_filename": "image1.dcm",   # Just the filename
#         "annotator_email": "annotator@example.com",  # May be null
#         "reviewer_email": "reviewer@example.com",    # May be null
#         "status": "PENDING",  # One of: PENDING, PENDING_REVIEW, APPROVED, REJECTED
#         "created_at": "2024-03-21T10:00:00Z",
#         "is_ground_truth": false
#     },
#     ...
# ]

Working with Allocations

The SDK provides a dedicated allocations API for managing image allocations with more granular control.

Create Allocation

Create a single allocation:

# Create a new allocation
allocation = client.allocations.create(
    project_id="project-uuid",
    image_key="images/image1.dcm",
    annotator="annotator@example.com",
    reviewer="reviewer@example.com",
    is_ground_truth=False
)

Get Allocation

Get details of a specific allocation:

# Get allocation details
allocation = client.allocations.get(
    project_id="project-uuid",
    allocation_id="allocation-uuid"
)

List Allocations with Filtering

List allocations with optional filtering:

# List allocations with filters
allocations = client.allocations.list(
    project_id="project-uuid",
    image_key="images/image1.dcm",  # Optional: filter by image
    annotator="annotator@example.com",  # Optional: filter by annotator
    reviewer="reviewer@example.com",  # Optional: filter by reviewer
    status="PENDING"  # Optional: filter by status
)

Update Allocation

Update an existing allocation:

# Update an allocation
updated = client.allocations.update(
    project_id="project-uuid",
    allocation_id="allocation-uuid",
    annotator="new_annotator@example.com",  # Optional: new annotator
    reviewer="new_reviewer@example.com",    # Optional: new reviewer
    is_ground_truth=True,                   # Optional: new ground truth status
    override_existing_work=False            # Whether to override existing work
)

Delete Allocation

Delete an allocation:

# Delete an allocation
client.allocations.delete(
    project_id="project-uuid",
    allocation_id="allocation-uuid",
    override_existing_work=False  # Whether to override existing work
)

Bulk Create Allocations

Create multiple allocations in a single request:

# Bulk create allocations
allocations = [
    {
        "image_key": "images/image1.dcm",
        "annotator": "annotator1@example.com",
        "reviewer": "reviewer1@example.com",
        "is_ground_truth": False
    },
    {
        "image_key": "images/image2.dcm",
        "annotator": "annotator2@example.com",
        "reviewer": "reviewer2@example.com"
    }
]

result = client.allocations.bulk_create(
    project_id="project-uuid",
    allocations=allocations,
    override_existing_work=False
)

Bulk Update Reviewers

Update reviewers for multiple allocations:

# Bulk update reviewers
updates = [
    {
        "image_key": "images/image1.dcm",
        "annotator": "annotator1@example.com",
        "new_reviewer": "new_reviewer1@example.com"
    },
    {
        "image_key": "images/image2.dcm",
        "annotator": "annotator2@example.com",
        "new_reviewer": "new_reviewer2@example.com"
    }
]

result = client.allocations.bulk_update_reviewers(
    project_id="project-uuid",
    updates=updates,
    override_existing_work=False
)

# Example response:
# {
#     "status": "success",
#     "results": {
#         "updated": [
#             {
#                 "allocation_id": "uuid",
#                 "image_key": "images/image1.dcm",
#                 "annotator": "annotator1@example.com",
#                 "old_reviewer": "old_reviewer1@example.com",
#                 "new_reviewer": "new_reviewer1@example.com",
#                 "status": "updated"
#             }
#         ],
#         "skipped": [
#             {
#                 "image_key": "images/image2.dcm",
#                 "annotator": "annotator2@example.com",
#                 "reason": "Existing review found",
#                 "can_override": true
#             }
#         ],
#         "failed": [
#             {
#                 "image_key": "images/image3.dcm",
#                 "annotator": "annotator3@example.com",
#                 "reason": "Invalid reviewer role",
#                 "details": "User is not a project reviewer"
#             }
#         ]
#     },
#     "summary": {
#         "total_updates": 3,
#         "successfully_updated": 1,
#         "skipped": 1,
#         "failed": 1
#     }
# }

Bulk Update by Filter

Update multiple allocations based on filter criteria:

# Bulk update by filter
filter_criteria = {
    "image_keys": ["images/image1.dcm", "images/image2.dcm"],
    "annotators": ["annotator1@example.com"],
    "reviewers": ["old_reviewer@example.com"],
    "status": "PENDING"
}

update_data = {
    "reviewer": "new_reviewer@example.com",
    "is_ground_truth": True
}

result = client.allocations.bulk_update_by_filter(
    project_id="project-uuid",
    filter_criteria=filter_criteria,
    update_data=update_data,
    override_existing_work=False
)

Error Handling

The SDK uses custom exception classes to handle API errors:

from frekil.exceptions import FrekilAPIError, FrekilClientError

try:
    projects = client.projects.list()
except FrekilClientError as e:
    # Handle client errors (e.g., authentication issues, invalid parameters)
    print(f"Client error: {e} (Status: {e.status_code})")
    print(f"Error details: {e.error_details}")
except FrekilAPIError as e:
    # Handle API errors (e.g., server issues)
    print(f"API error: {e} (Status: {e.status_code})")
    print(f"Error details: {e.error_details}")

Development

Setup

# Clone the repository
git clone https://github.com/notatehq/frekil-python-sdk.git
cd frekil-python-sdk

# Install dependencies
pip install -e ".[dev]"

Testing

pytest

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

frekil-0.1.9.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

frekil-0.1.9-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file frekil-0.1.9.tar.gz.

File metadata

  • Download URL: frekil-0.1.9.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.22

File hashes

Hashes for frekil-0.1.9.tar.gz
Algorithm Hash digest
SHA256 d1d912413bcc05d10c7f174ab388ed1e0d439fc751ad1734322154946ba7dcf7
MD5 17ed70aab3ae3c1b3ed7c119e8cb75b7
BLAKE2b-256 db882458c2aabb12dbf533b38277b479477336a94ebe7627444cb6b4d8a71551

See more details on using hashes here.

File details

Details for the file frekil-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: frekil-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.22

File hashes

Hashes for frekil-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 428b52dea81316c788dbdd7967608b7a7d8cd0f1bd6e486ee1a605e7d2dc2772
MD5 ff3ca7536db1965f0c2b2520306d680f
BLAKE2b-256 1a8103863ad0bfdc716f4faa96bad8cd2eec797d9ec500ceefafa1c8cf592055

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page