Is the Nx Cloud up? Visit our Status Page for the current health and performance of the Nx Cloud.

Status Page

How to control layouts vi'a API?

Answered

Comments

10 comments

  • Andrey Terentyev
    • Network Optix team

    Hello,

    Please, provide OS version. VMS build number, url of the request you're trying.

    0
  • Andrey Terentyev
    • Network Optix team

    As the error string states, the user you're invoking the API with has no sufficient permissions. 

    0
  • Mariusz

    I'm using an administrator (owner) account. I am logged in to this account.

    0
  • Mariusz

    I found information: "All owner-level API requests in the /rest section of the API documentation require session authentication with a fresh bearer token to enforce password checks before executing API requests."

    So, how should look a code to for example add new layout?

    0
  • Andrey Terentyev
    • Network Optix team

    Mariusz,

    Please, see our code example on github

    https://github.com/networkoptix/nx_open_integrations/blob/master/python/examples/authentication/local_bearer.py

    1. You get a bearer token via /rest/v1/login/sessions

    2. With the token got, you invoke POST /rest/v2/layouts with http authorization header for creating a layout

    "Authorization": "Bearer <here goes the token you got>"

    0
  • Mariusz

    This is python script written based on the github example you gave me (with changed password):

    import requests
    import urllib3

    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def create_bearer_token(url, username, password):
        token_endpoint = f"{url}/rest/v1/login/sessions"
        auth_payload = {
            'username': username,
            'password': password,
            'setCookie': False
        }
        response = requests.post(token_endpoint, json=auth_payload, verify=False)
        
        if response.status_code == requests.codes.ok:
            bearer_token = response.json().get('token')
            return bearer_token
        else:
            print(f"Error obtaining Bearer Token: {response.status_code}")
            return None

    def post_layout(url, bearer_token, layout_data):
        post_endpoint = f"{url}/rest/v2/layouts"
        headers = {"Authorization": f"Bearer {bearer_token}"}
        response = requests.post(post_endpoint, json=layout_data, headers=headers, verify=False)

        if response.status_code == requests.codes.ok:
            print("POST request successful")
        else:
            print(f"POST request error: {response.status_code}\n{response.text}")

    if __name__ == '__main__':
        USERNAME = 'admin'
        PASSWORD = 'myPassword123!'
        LOCAL_URL = 'https://localhost:7001'

        layout_data = {
          "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "name": "Layout",
          "cellAspectRatio": 0,
          "cellSpacing": 0,
          "items": [
            {
              "flags": 0,
              "left": 0,
              "top": 0,
              "right": 1,
              "bottom": 1,
              "rotation": 0,
              "resourceId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
              "resourcePath": "",
              "zoomLeft": 0,
              "zoomTop": 0,
              "zoomRight": 0,
              "zoomBottom": 0,
              "zoomTargetId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
              "contrastParams": {
                "enabled": True,
                "blackLevel": 0,
                "whiteLevel": 0,
                "gamma": 0
              },
              "dewarpingParams": {
                "enabled": True,
                "xAngle": 0,
                "yAngle": 0,
                "fov": 0,
                "panoFactor": 0
              },
              "displayInfo": True,
              "controlPtz": True,
              "displayAnalyticsObjects": True,
              "displayRoi": True
            }
          ],
          "locked": True,
          "fixedWidth": 1,
          "fixedHeight": 1,
          "logicalId": 0,
          "backgroundImageFilename": "",
          "backgroundWidth": 0,
          "backgroundHeight": 0,
          "backgroundOpacity": 0
        }

        bearer_token = create_bearer_token(LOCAL_URL, USERNAME, PASSWORD)

        if bearer_token:
            post_layout(LOCAL_URL, bearer_token, layout_data)

    And the response is:
    Error POST: 403
    {"error":"4","errorId":"forbidden","errorString":"User 99cbc715-539b-4bfe-856f-799b45b69b1e is not permitted to create new resource"}

    What am I doing wrong?

    0
  • Andrey Terentyev
    • Network Optix team

    Helllo,

    1. Please provide the information asked for.

    https://support.networkoptix.com/hc/en-us/community/posts/19474586032151/comments/19476379744151

    2. Make sure the `admin` user has digest auth scheme disabled.

    3. Here is layout_data your script worked with in my lab. See the Schema tab in the API endpoint documentation for required parameters.

    layout_data = {
    "name":"Layout2",
    "items":[
    {
    "flags":0,
    "left":0,
    "top":0,
    "right":1,
    "bottom":1,
    "rotation":0,
    "resourceId":"e3e9a385-7fe0-3ba5-5482-a86cde7faf48",
    }
    ],
    "fixedWidth":1,
    "fixedHeight":1
    }

     

    0
  • Mariusz

    You're right. It works:

    import requests
    import urllib3

    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    def create_bearer_token(url, username, password):
        token_endpoint = f"{url}/rest/v1/login/sessions"
        auth_payload = {
            'username': username,
            'password': password,
            'setCookie': False
        }
        response = requests.post(token_endpoint, json=auth_payload, verify=False)
        if response.status_code == requests.codes.ok:
            bearer_token = response.json().get('token')
            return bearer_token
        else:
            print(f"Error while obtaining Bearer Token: {response.status_code}")
            return None

    def post_layout(url, bearer_token, layout_data):
        post_endpoint = f"{url}/rest/v2/layouts"
        headers = {"Authorization": f"Bearer {bearer_token}"}
        response = requests.post(post_endpoint, json=layout_data, headers=headers, verify=False)
        if response.status_code == requests.codes.ok:
            print("POST request successful")
            delete_method_header = {"Authorization": f"Bearer {bearer_token}"}
            requests.delete(f"{url}/rest/v1/login/sessions/{bearer_token}", headers=delete_method_header, verify=False)
            print("Token deleted, session ended.")
        else:
            print(f"POST request error: {response.status_code}\n{response.text}")

    if __name__ == '__main__':
        USERNAME = 'admin'
        PASSWORD = 'myPassword123!'
        LOCAL_URL = 'https://localhost:7001'

        layout_data = {
            "name": "Layout created from Python script",
            "items": [
                {
                    "flags": 0,
                    "left": 0,
                    "top": 0,
                    "right": 1,
                    "bottom": 1,
                    "rotation": 0,
                    "resourceId": "8353216e-92fd-11ee-b9d1-0242ac120002", # camera's ID
                }
            ],
            "fixedWidth": 1,
            "fixedHeight": 1
        }

        bearer_token = create_bearer_token(LOCAL_URL, USERNAME, PASSWORD)

        if bearer_token:
            post_layout(LOCAL_URL, bearer_token, layout_data)

    0
  • Mariusz

    I'm testing it on WAVE Cilent version 5.1.0.37133.

    I can create a new empty layout, a new layout with a camera, remove all cameras in the layout to display one camera (replace item layout).
    I need to learn one more thing. I would like to display two cameras: CAM1 and CAM2, and then replace the CAM2 camera with e.g. CAM3, as a result of which CAM1 and CAM3 should be displayed.
    Is it possible to do this with Modify Layout Item?

    0
  • Andrey Terentyev
    • Network Optix team

    Hi,

    Is it possible to do this with Modify Layout Item?

    Yes, that's possible. The layout id indicated in the URL /rest/v2/layouts/{id}

    in the `items` place items with "resourceId" corresponding to CAM1 and CAM3.

    0

Please sign in to leave a comment.