cylc-uiserver icon indicating copy to clipboard operation
cylc-uiserver copied to clipboard

Make API info available - CLI via Hub/proxy and/or UIS

Open dwsutherland opened this issue 2 years ago • 7 comments

These changes partially address https://github.com/cylc/cylc-flow/issues/5235 Sibling to https://github.com/cylc/cylc-flow/pull/5267

On spawning the UI Server (Jupyter server), the hub negotiates an API token and puts it as JUPYTERHUB_API_TOKEN, along with other variables, into the the environment. If not hub spawned the UI Server will generate one itself.

Using the server app's information (self.serverapp.server_info()) and overwriting it with HUB info, we can make this available by writing it to a (user read-only) file:

$ pwd
/home/sutherlander/.cylc/uiserver
$ ls -larth api_info.json 
-rw------- 1 sutherlander sutherlander 288 Nov 22 11:25 api_info.json
$ cat api_info.json
{"url": "http://127.0.0.1:39409/user/sutherlander/", "hostname": "127.0.0.1", "port": 39409, "sock": "", "secure": false, "base_url": "/user/sutherlander/", "token": "2f2abf2e4bcd43589711c1554ce2cc7e", "root_dir": "/home/sutherlander", "password": false, "pid": 6610, "version": "1.21.0"}

(this token changes on each UIS spawn)

This can be used to access the UIS via the UIS url (as above) but also via the hub proxy (http://localhost:8000/user/sutherlander/).. And copied (manually only?) to machines on the network for API access there.

Tasks:

  • [x] - Write API info, including hub token if available, to a user read-only file.
  • [ ] - Clean up file on UI Server shutdown (use absence as indicator that UIS isn't running?).
    • [x] Hubless clean-up.
    • [ ] Hub stopped server clean-up (https://github.com/cylc/cylc-uiserver/issues/392)
  • [ ] - Find out hub proxy URL (if available), and use that instead or in addition to UIS URL.

Sample:

#!/usr/bin/env python3

import json
import requests

from cylc.uiserver.app import API_INFO_FILE

f = open(API_INFO_FILE, "r")
api_info = json.loads(f.read())
f.close()

query = '''
query {
  workflows {
    id
    stateTotals
  }
}
'''

r = requests.post(api_info["url"] + 'cylc/graphql',
    headers={
        'Authorization': f'token {api_info["token"]}',
    },
    json={'query': query}
)


r.raise_for_status()
data = r.json()

print(json.dumps(data, indent=4))

$ ./uis_api.py
{
    "data": {
        "workflows": [
            {
                "id": "~sutherlander/linear/run1",
                "stateTotals": {
                    "waiting": 2,
                    "expired": 0,
                    "preparing": 0,
                    "submit-failed": 1,
                    "submitted": 0,
                    "running": 0,
                    "failed": 0,
                    "succeeded": 0
                }
            }
        ]
    }
}

Requirements check-list

  • [x] I have read CONTRIBUTING.md and added my name as a Code Contributor.

  • [x] Contains logically grouped changes (else tidy your branch by rebase).

  • [x] Does not contain off-topic changes (use other PRs for other changes).

  • [ ] Appropriate tests are included (test for token use should be included).

  • [ ] Already covered by existing tests (file is written on UIS start).

  • [ ] Appropriate change log entry included.

  • [ ] I have opened a documentation PR at cylc/cylc-doc/pull/XXXX.

dwsutherland avatar Nov 22 '22 00:11 dwsutherland