Create a job
post
https://api.playment.io
/v1/projects/:project_id/jobs
A JOB
{
"reference_id":"001",
"data":{
"video_data": {
"frames": [
{
"frame_id": "frame001",
"src": "https://dummyimage.com/600x400/000/fff.jpg&text=Dummy+Image+1"
},
{
"frame_id": "frame002",
"src": "https://dummyimage.com/600x400/000/fff.jpg&text=Dummy+Image+2"
},
{
"frame_id": "frame003",
"src": "https://dummyimage.com/600x400/000/fff.jpg&text=Dummy+Image+3"
},
{
"frame_id": "frame004",
"src": "https://dummyimage.com/600x400/000/fff.jpg&text=Dummy+Image+4"
},
{
"frame_id": "frame005",
"src": "https://dummyimage.com/600x400/000/fff.jpg&text=Dummy+Image+5"
}
]
}
},
"work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
Python
import requests
import json
"""
Details for creating JOBS,
project_id ->> ID of project in which the job will be created
x_api_key ->> API key for authentication
workflow_id ->> The workflow in which the job will be created
batch_id ->> The batch in which job will be created
"""
# Additional helper function to create a batch
def create_batch(BATCH_NAME):
base_url = f"https://api.playment.io/v1/projects/{PROJECT_ID}/batch"
DATA = {"name":BATCH_NAME}
response = requests.post(base_url, headers={'x-api-key': CLIENT_KEY}, json=DATA)
response_data = response.json()
if response.status_code >= 500:
raise Exception(f"Something went wrong at Playment's end {response.status_code}")
if 400 <= response.status_code < 500:
raise Exception(f"{response_data['error']['message']} {response.status_code}")
print(response_data)
return response_data
#method that can be used to call the job creation api
def create_job(project_id, data, x_api_key):
base_url = "https://api.playment.io/v1/projects/{}/jobs".format(project_id)
headers = {'x-api-key': x_api_key}
response = requests.post(base_url, headers=headers, json=data)
print(response.json())
if response.status_code >= 500:
raise Exception(response.text)
if 400 <= response.status_code < 500:
raise Exception(response.text)
return response.json()
if __name__ == "__main__":
#list of frames in a single job
frames = ["https://example.com/image_url_1","https://example.com/image_url_2","https://example.com/image_url_3"]
#reference_id should be unique for each job
reference_id= "job1"
project_id = ''
x_api_key = ''
workflow_id = ''
batch_id = ''
video_data = {'frames' : []}
i=0
for frame_url in frames:
i=i+1
frame_id = "frame"+str(i)
frame_obj = {'src':frame_url,'frame_id':frame_id}
video_data['frames'].append(frame_obj)
job_data = {
'reference_id':reference_id,
'work_flow_id':workflow_id,
'data':{'video_data':video_data},
'batch_id' : batch_id
}
response = create_job(project_id=project_id, data=job_data, x_api_key= x_api_key)
print(response)
If you have data which has been labeled previously by an ML model or by human labelers, you can create jobs with such labels already created. To do this, you need to send the annotation data in the
data.maker_response
key in the payload. The annotation data needs to be in Playment's annotation format.Here's an example
{
"reference_id":"001",
"data":{
"video_data": {
"frames": [...]
},
"maker_response" : {
"video2d": {
"data": {
"annotations": []
}
}
}
},
"work_flow_id":"2aae1234-acac-1234-eeff-12a22a237bbc"
}
The
data.maker_response.video_2d.data.annotations
list contains objects, where each object is a tracker. A tracker tracks an object across frames. The frames
key in the tracker object maps each annotation object in the tracker to the frame_id
it belongs to. {
"_id": "",
"type": "rectangle", // rectangle/polygon/line/cuboid/landmark
"label": "Cat",
"frames" : {
"frame001" : {<annotation_object>}
}
}
You can check the structure for various
annotation_object
below:Rectangles
Polygon
Line
Cuboid
Landmark
{
"_id": "0e6d895e-2484-439a-b62b-d8a0afb3d190",
"label": "".
"attributes": {
"pose": {
"value": "standing"
},
"breed": {
"value": "Persian"
}
}
"coordinates": [
{"x": 0.00398, "y": 0.00558},
{"x": 0.05404, "y": 0.00558},
{"x": 0.05404, "y": 0.09096},
{"x": 0.00398, "y": 0.09096}
]
}
{
"_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
"label": "face_mask",
"attributes": {
"covers_nose": {
"value": "Yes"
},
}
"points": {
"p1": {"x": 0.286774, "y": 0.892502},
"p2": {"x": 0.385849, "y": 0.576888},
"p3": {"x": 0.426721, "y": 0.469081},
"p4": {"x": 0.288623, "y": 0.253878},
"p5": {"x": 0.148623, "y": 0.353878}
},
"edges": {
"e1": ["p1", "p2"],
"e2": ["p2", "p3"],
"e3": ["p3", "p4"],
"e4": ["p4", "p4"],
"e5": ["p5", "p1"]
}
}
{
"_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
"label": "lane_divider",
"attributes": {
"raised": {
"value": "Yes"
},
}
"points": {
"p1": {"x": 0.286774, "y": 0.892502},
"p2": {"x": 0.285849, "y": 0.876888},
"p3": {"x": 0.286774, "y": 0.869081},
"p4": {"x": 0.288623, "y": 0.853878}
}
}
{
"_id": "8f8897ad-e07b-4e55-9dbe-61f6b9df85c5",
"label": "Car",
"attributes" : {
"faces_visible": {
"value": ["right","back"]
}
},
"points": {
"p1": {"x": 0.17,"y": 0.58},
"p2": {"x": 0.26,"y": 0.58},
"p3": {"x": 0.26,"y": 0.49},
"p4": {"x": 0.17,"y": 0.49},
"p5": {"x": 0.24,"y": 0.51},
"p6": {"x": 0.35,"y": 0.52},
"p7": {"x": 0.35,"y": 0.36},
"p8": {"x": 0.25,"y": 0.37}
},
"front": {
"coordinates": ["p1","p2","p3","p4"]
},
"side": {
"coordinates": ["p2","p3","p5","p6"]
},
"back": {
"coordinates": ["p7","p8","p5","p6"]
}
}
{
"_id": "e7e3353f-2ffe-432a-a14f-9cb9a6f4b735",
"label": "nose",
"attributes": {
"visible": {
"value": "Partially"
},
}
"points": {
"p1": { "x": 0.17, "y": 0.58, "label": 1 },
"p2": { "x": 0.26, "y": 0.63, "label": 2 },
"p3": { "x": 0.27, "y": 0.63, "label": 3 },
"p4": { "x": 0.29, "y": 0.59, "label": 4 },
"p5": { "x": 0.25, "y": 0.46, "label": 5 },
"p6": { "x": 0.22, "y": 0.42, "label": 6 }
}
}
Last modified 1yr ago