Developer guide on how to set up Labelbox webhooks through Python SDK
from flask import Flask, request
import json
import hmac
import hashlib
# This can be any secret that matches your webhook config (we will set later)
secret = b"<replace with secret>"
# Example for server-side code to receive webhook events
app = Flask(**name**)
@app.route("/webhook-endpoint", methods=["POST"])
def print_webhook_info():
payload = request.data
computed_signature = hmac.new(secret, msg=payload,
digestmod=hashlib.sha1).hexdigest()
if request.headers["X-Hub-Signature"] != "sha1=" + computed_signature:
print(
"Error: computed_signature does not match signature provided in the headers"
)
return "Error", 500, 200
print("=========== New Webhook Delivery ============")
print("Delivery ID: %s" % request.headers["X-Labelbox-Id"])
print("Event: %s" % request.headers["X-Labelbox-Event"])
print("Payload: %s" %
json.dumps(json.loads(payload.decode("utf8")), indent=4))
return "Success"
thread = threading.Thread(target=lambda: run_simple("0.0.0.0", 3001, app))
thread.start()
from labelbox import Client, Webhook
public_url = "https://example.com/webhook-endpoint" # Your server's public url - where the messages will be sent to
secret = b"CHANGE-ME" # Use to verify Labelbox is sending the message
client = Client(api_key="<YOUR_API_KEY>")
project = client.get_project("<project_id>")
print([topic.value for topic in Webhook.Topic]) # See all available topics
secret = b"example_secret" # This can be any secret that matches your webhook config (we will set later)
webhook = Webhook.create(client,
topics=["LABEL_CREATED"],
url="public_url",
secret=secret.decode(),
project=project)
# Fetch all webhooks
org = client.get_organization()
webhooks = org.webhooks() #paginated
# Fetch project webhooks
project = client.get_project("<project_id>")
webhooks = project.webhooks() #paginated
webhook = next(webhooks)
status = webhook.status
server_url = webhook.url
topics = webhook.topics
project = webhook.project()
# url, topics, and status can all be updated
updated_url = f"{public_url}/webhook-endpoint"
webhook.update(url=updated_url, topics=[Topic.LABEL_DELETED], status=Webhook.Status.INACTIVE.value)
webhook.delete()
{'agreement': None,
'benchmarkAgreement': None,
'createdAt': '2023-02-13T18:22:46Z',
'dataRow': {'createdAt': '2023-01-25T17:54:20Z',
'deletedAt': None,
'externalId': 'multi_thread_update_4cfdcb29-be33-4e07-b586-849829385210',
'id': 'cldbyu7c7n4jp072scuqt66ll',
'labelCountInProject': 1,
'rowData': 'https://labelbox.s3-us-west-2.amazonaws.com/datasets/mapillary_traffic/images/F1xqHzDSi1qP3qSLBXVyJQ.jpg',
'updatedAt': '2023-01-25T20:42:57Z'},
'dataset': {'createdAt': '2023-01-25T17:53:58Z',
'deleted': False,
'description': '',
'id': 'cldbytq0w2uw8074hgl3hbxr2',
'name': 'Datarow Update Test - 5K',
'updatedAt': '2023-01-25T17:54:21Z'},
'deleted': False,
'id': 'cle357uex0g5307z996y28ic0',
'label': '{"objects":[{"featureId":"cle357vrp00013b6jsi6dfei0","schemaId":"cldan3u0701sc07yi6xyw6up6","color":"#ff0000","title":"bounding_box","value":"bounding_box","bbox":{"top":453,"left":951,"height":670,"width":952},"instanceURI":"https://api.labelbox.com/masks/feature/cle357vrp00013b6jsi6dfei0"}],"classifications":[],"relationships":[]}',
'project': {'createdAt': '2023-02-13T18:20:52Z',
'deleted': False,
'description': '',
'id': 'cle355i370h86070hf1v7ata1',
'name': 'Webhooks',
'updatedAt': '2023-02-13T18:22:17Z'},
'secondsToLabel': 0,
'skipped': False,
'updatedAt': '2023-02-13T18:22:46Z',
'user': {'email': '[email protected]',
'id': 'clbpgxfaehww6076tedo5ejwx'}}
{
"data_row": {
"id": "clvmpaetz76ct0706730rfcq9",
"external_id": null,
"global_key": "TEST-ID-157128604429964085398241585654637789196d",
"row_data": "https://storage.googleapis.com/labelbox-datasets/People_Clothing_Segmentation/jpeg_images/IMAGES/img_0001.jpeg",
"metadata_fields": [],
"details": {
"dataset_id": "clvmpa9et010j0750rlgs8qdi",
"created_at": "2024-04-30T18:07:10.82Z",
"updated_at": "2024-04-30T18:07:14.199Z",
"created_by": null
}
},
"projects": {
"clvo7ajpc014907zxagiw9hry": {
"project_name": "test_lambda",
"labels": [
{
"label_kind": "Default",
"id": "clvo7b6h501ic07fdbg62c32w",
"label_details": {
"created_at": "2024-05-06T17:18:48Z",
"updated_at": "2024-05-06T17:18:48Z",
"created_by": "[email protected]"
},
"performance_details": {
"seconds_to_create": 5759.536,
"seconds_to_review": 0,
"skipped": false,
"benchmark_reference_label": null,
"benchmark_score": null,
"consensus_score": null
},
"annotations": {
"classifications": [],
"objects": [
{
"bbox": {
"height": 359,
"left": 24,
"top": 85,
"width": 480
},
"color": "#1976d2",
"feature_id": "clvv876mw00023b6qr6mk2o4s",
"instance_uri": "https://api.labelbox.com/masks/feature/clvv876mw00023b6qr6mk2o4s",
"schema_id": "clvcnmppk0aq507z11haa4x66",
"title": "person",
"value": "person"
}
],
"relationships": []
}
}
],
"project_details": {
"ontology_id": "clvcnmpor0aq207z14jesh8w7",
"batch_id": "11EF07D4F9E60FC08820734F207E70B1",
"priority": 5,
"consensus_expected_label_count": {
"Int32": 1,
"Valid": true
}
}
}
},
"media_attributes": {
"asset_type": "image",
"content_length": 122898,
"exif_rotation": 1,
"height": 825,
"mime_type": "image/jpeg",
"sub_type": "jpeg",
"super_type": "image",
"width": 550
}
}