So the Websocket API endpoint on SCALE through 24.10 is ws://host/websocket (or wss://). In 25.04, it changes to /api/current, but /websocket still works (at least as of RC1). How long will /websocket continue to work?
The context is, naturally, that I have a script that uses the API, and I’d like it to work across as many releases of SCALE as possible. I could make the user specify the API endpoint via a config file, but that seems kind of user-hostile. Is there a way I can determine which API endpoint to use programmatically? Better yet, to do it when the script is running on a different system from the NAS?
I think probably the simplest solution for API consumers is the following: for 25.04.0 we’re adding a api/versions path so you can do something like this:
This will allow versioning scripts based on which API version is available. If you get a 404 on that path then /websocket (you know you’re dealing with an older TrueNAS version).
Well, good news: the /api/versions path does now give a response in the 4/6 nightly. And requests to that path on 25.04-RC1 without the HTTP → HTTPS redirect enabled give 404. Bad news: any version with that redirect enabled responds with a 302 redirect to /ui, which in turn gives 200–so just testing for a 200 status code clearly isn’t going to do the trick.
I guess the fallback course of action is to test whether the result can be parsed, and if so, the system’s running 25.04+. If not, it’s an earlier version.
edit: with assistance from ChatGPT, this seems to do the trick, with or without a http->https redirect, on 25.04-Nightly and other versions:
# Determine API path
valid_versions = []
invalid_response = False
try:
response = requests.get(f"http://{CONNECT_HOST}/api/versions", timeout=10)
response.raise_for_status()
data = response.json()
if isinstance(data, list) and all(isinstance(v, str) and v.startswith("v") for v in data):
valid_versions = data
logger.debug(f"✅ Valid versions received: {valid_versions}")
else:
invalid_response = True
logger.debug(f"⚠️ Unexpected response structure: {data}")
except Exception as e:
invalid_response = True
logger.debug(f"❌ Failed to retrieve or parse the response: {e}")
if invalid_response==True:
API_PATH="/websocket"
logger.debug(f"API path is {API_PATH}")
else:
API_PATH="/api/current"
logger.debug(f"API path is {API_PATH}")