Configuration API
Read and change Vis settings from your own program. The program changes the same settings as the Settings views, for the gateway, a project, a group or one session.
The examples use the Python SDK. To see the same steps as HTTP API requests, select HTTP at the top of the page.
When to use
- A setup script must turn on features for a new project. Change one setting for that project.
- Several settings must change together or not at all. Change many settings in one batch with a revision check.
- You must know which value applies to a session, and why. Read settings with a context session.
- You edited an extension and the gateway must load the new code. Reload extensions.
To learn the settings and the configuration files, read Configuration.
Before you start
Python
Connect a GatewayClient as in Connect to a gateway and run a
task. The examples are calls on that client.
HTTP
Define the vis_api function from Authenticate requests. The
examples use it.
Operations
Python
GatewayClient has one method for each settings route.
| Task | Method |
|---|---|
| Read the settings of a target | get_settings(query=...) |
| Read one setting | get_setting(id, query=...) |
| Change one setting | post_settings(body=...) |
| Change many settings at once | patch_settings(body=...) |
| Reload extensions | post_extensions_reload(body=...) |
HTTP
| Task | Method and path |
|---|---|
| Read the settings of a target | GET /v1/settings |
| Read one setting | GET /v1/settings/{id} |
| Change one setting | POST /v1/settings |
| Change many settings at once | PATCH /v1/settings |
| Reload extensions | POST /v1/extensions/reload |
How settings requests work
Python
The methods send and receive the JSON of the HTTP routes. You give a body or a query as a Python
dict. To read the scopes, the catalog fields and the status codes, select HTTP at the top of
the page. A failed request raises GatewayError with that status.
HTTP
Your program reads and changes the same settings as the Settings views. The Python SDK sends the same JSON and gets the same answers.
A request names its target with scope and target_id. The scope is global, project, group
or session. Without a scope, a request uses the global settings, never the session that you see.
A scope other than global needs a target_id.
The catalog of a target has its revision and its groups. Each group has toggles, the setting
rows. A row has scopes, scope, source and is_override. A boolean row has enabled, and
other rows have value. The revision is a hash of the saved values of the target.
A row can have children: the rows that belong under it, in display order. A child row has
parent with the id of its parent row. Rows nest at any depth. For example, the Council room
rows are children of the council row. When you read or write one setting, its row has no
children. Keep the cached children when you replace a row.
Add context_session_id to a read to mark the rows that a more specific scope decides for that
session. Such a row has overridden_by with the deciding scope and its enabled or value. An
unknown session, or a session outside the target, marks no rows. Vis does not refuse a write to a
marked row, because the global value still applies to other projects. Clients lock the row only for
the open session.
An extension group in the catalog has extension with name, origin and status. The origin
is built_in, global or project, and the status is loaded, stale or failed. A global
or project extension also has path. A stale or failed extension has error. A failed
extension that never loaded has a group with no rows.
| Status | Meaning |
|---|---|
400 |
A value, a scope or a batch is not valid. A batch error names the setting id. Access errors also list field_errors. |
404 |
The target, the context session or the setting ID does not exist. |
409 |
The revision of a batch is stale. Read the catalog again. |
Read settings
Python
catalog = client.get_settings(query={"scope": "session", "target_id": session_id})
def show(rows, depth=0):
for row in rows:
value = row.get("enabled", row.get("value"))
print(" " * depth + row["id"], value, row["source"])
show(row.get("children", []), depth + 1)
for group in catalog["groups"]:
show(group["toggles"])
print(client.get_setting("agent_name")["value"])
get_session(session_id) also returns the resolved agent_name of a session.
HTTP
vis_api "$VIS_GATEWAY_URL/v1/settings?scope=session&target_id=$SESSION_ID"
vis_api "$VIS_GATEWAY_URL/v1/settings/agent_name"
GET /v1/sessions/{sid} also returns the resolved agent_name of a session.
Change one setting
Python
client.post_settings(body={"id": "agent_name", "action": "value", "value": "Ada"})
client.post_settings(
body={"scope": "session", "target_id": session_id, "id": "refusal_fallback", "action": "toggle"}
)
The action is value, toggle, cycle or inherit. A value action needs value, also when
the value is False. inherit removes one key at this scope, not a parent map. The answer is the
changed row.
HTTP
vis_api -X POST "$VIS_GATEWAY_URL/v1/settings" -H 'content-type: application/json' \
--data '{"id": "agent_name", "action": "value", "value": "Ada"}'
The action is value, toggle, cycle or inherit. A value action needs value, also when
the value is false. inherit removes one key at this scope, not a parent map. The answer is the
changed row.
Change many settings
Python
catalog = client.get_settings(query={"scope": "session", "target_id": session_id})
client.patch_settings(
body={
"scope": "session",
"target_id": session_id,
"revision": catalog["revision"],
"changes": [
{"id": "refusal_fallback", "action": "value", "value": False},
{"id": "provider_fallback", "action": "inherit"},
],
}
)
HTTP
Save the batch as changes.json, with the revision from your last read:
{
"scope": "session",
"target_id": "<session-id>",
"revision": "<revision from GET>",
"changes": [
{"id": "refusal_fallback", "action": "value", "value": false},
{"id": "provider_fallback", "action": "inherit"}
]
}
vis_api -X PATCH "$VIS_GATEWAY_URL/v1/settings" -H 'content-type: application/json' \
--data @changes.json
A batch has 1 to 256 changes for one target. Each change has a unique id and the action value or
inherit. Vis applies the whole batch or none of it. Optional channel and context_session_id
work as in a read. The answer is the full catalog with its new revision.
Reload extensions
Python
result = client.post_extensions_reload(body={"scope": "project", "target_id": project_id})
for scope in result["scopes"]:
print(scope["scope"], scope["dirs"], scope["loaded"], scope["failed"], scope["extensions"])
HTTP
vis_api -X POST "$VIS_GATEWAY_URL/v1/extensions/reload" -H 'content-type: application/json' \
--data '{"scope": "global"}'
Vis runs the extension files of the target again. A global target reloads machine extensions only. Reading the catalog never runs extension code.
The answer has the totals loaded and failed. Its scopes list has one entry for each scanned
scope. An entry has scope (global or project), the scanned dirs, and loaded and failed
for that scope. Its extensions list names the loaded extensions. A scope with no loaded or failed
extensions found nothing in its directories.
See also
- Configuration — every setting, configuration file and scope.
- Python SDK — install the SDK, connect a client and handle gateway errors.
- HTTP API — authentication, the OpenAPI document and gateway errors.
