> For the complete documentation index, see [llms.txt](https://on-premises.docs.hyper3d.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://on-premises.docs.hyper3d.ai/task/query-task-status.md).

# Query Task Status

{% hint style="info" %}
The status channel is based on Socket.IO instead of standard WebSocket.
{% endhint %}

### Workflow

1. **Initialization**: Establish a WebSocket connection to the server using the `base_url` and `subscription_key`.
2. **Request Handling**:
   * On a successful connection, initiate status queries with the specified job with its `uuid`.
3. **Status Monitoring**:
   * Periodically send status queries to the server, we recommend submitting queries at 2-second intervals.
   * Listen for responses from the server and update the job status accordingly.
   * If the job is completed successfully, perform necessary cleanup actions such as closing the connection.

## API Endpoint

<mark style="color:green;">`Socket`</mark> `/api/scheduler_socket`

**Queries**

| Name         | Value             |
| ------------ | ----------------- |
| subscription | `subscripton_key` |

**Sending a Query**

To query the status of a job, send a message to the scheduler socket endpoint with the job's UUID:

```javascript
// Establish connection with the scheduler socket
const socket = io('/api/scheduler_socket?subscription={subscripton_key}');

// Send a query for the job status
socket.emit('query', '{job_uuid}');
```

**Receiving a Response**

The server responds with the status of the job, including details such as the job's UUID, status, and any relevant metrics.

```javascript
socket.on('message', (data) => {
  console.log('Received response:', data);
  /*
    Output will be:
    {
      "taskUuid": "{job_uuid}",
      "jobStatus": "Succeeded", // Succeeded, Running, Failed
      "jobMetricPayload": {
        "status": "Done",
        "error": "None",
        "message": "Process Done",
        "percentage": 100
      }
    }
  */
});
```

While the specific implementation can vary, the core functionality typically involves:

* A WebSocket client that handles the lifecycle of the connection and communication.
* Event handlers that react to changes in the connection status and incoming messages.
* A mechanism to periodically send requests to the server to check the status of the job.

### Examples

{% tabs %}
{% tab title="Python" %}

```python
import socketio
import time

class JobStatusChecker:
    def __init__(self, base_url, subscription_key, uuid):
        self.base_url = base_url
        self.subscription_key = subscription_key
        self.uuid = uuid
        self.sio = socketio.Client(logger=True, engineio_logger=True)

        @self.sio.event
        def connect():
            print("Connected to the server.")
            self.send_query() 
            threading.Thread(target=self.send_periodic_queries).start() 

        @self.sio.event
        def disconnect():
            print("Disconnected from server.")

        @self.sio.on('message', namespace='*')
        def message(*args, **kwargs):
            if len(args) > 2:
                data = args[2]
                if data.get('jobStatus') == 'Succeeded':
                    print("Job Succeeded! Please find the SDF image in history")
                    self.sio.disconnect()
            else:
                print("Received event with insufficient arguments.")

    def send_query(self):
        self.sio.emit('query', self.uuid, namespace='/api/scheduler_socket')

    def send_periodic_queries(self):
        while True:
            time.sleep(3)
            self.send_query()

    def start(self):
        self.sio.connect(f"{self.base_url}/scheduler_socket?subscription={self.subscription_key}", 
                         namespaces=['/api/scheduler_socket'], transports='websocket')
        self.sio.wait()
        
# Check progress
progress_checker = JobStatusChecker(BASE_URL, 'subscription_key', 'task_uuid')
progress_checker.start()
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

const BaseURI = "https://hyperhuman.deemos.com/api"

type TaskStatus string

const (
	Created       TaskStatus = "Created"
	Waiting       TaskStatus = "Waiting"
	Canceled      TaskStatus = "Canceled"
	NeedSelection TaskStatus = "NeedSelection"
	Generating    TaskStatus = "Generating"
	Done          TaskStatus = "Done"
	Failed        TaskStatus = "Failed"
)

type CheckProgressResponse struct {
	Stage      TaskStatus `json:"stage"`
	Message    *string    `json:"message,omitempty"`
	Percentage *float32   `json:"percentage,omitempty"`
	WaitingNum *int       `json:"waiting_num,omitempty"`
	Candidates []string   `json:"candidates,omitempty"`
	OnProgress []string   `json:"on_progress,omitempty"`
}

func CheckProgress(token string, uuid string) (*CheckProgressResponse, error) {
	req, err := http.NewRequest("POST", fmt.Sprintf("%s/task/check_progress/%s", BaseURI, uuid), nil)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Authorization", "Bearer "+token)
	req.Header.Set("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var responseData CheckProgressResponse
	err = json.NewDecoder(resp.Body).Decode(&responseData)
	if err != nil {
		return nil, err
	}

	return &responseData, nil
}

func main() {
	// Replace with your actual API key
	token := "your api key"
	// Replace with the task uuid
	resp, _ := CheckProgress(token, "task uuid")
	fmt.Println(resp)
}

```

{% endtab %}
{% endtabs %}
