TangoGQL Ariadne Implementation¶
The current implementation of TangoGQL, using Ariadne, integrates with Starlette for serving GraphQL queries and WebSocket subscriptions, providing modern and efficient queryable access to a Tango Control System. This documentation outlines the server setup, key routes, middleware configuration, and resolver functionality.
Server Setup¶
The production server is set up using Ariadne’s ASGI GraphQL handler integrated into a Starlette application. The handler manages both HTTP routes and WebSocket connections to serve GraphQL queries and subscriptions.
The key components include:
GraphQL Handler: This is responsible for processing incoming GraphQL queries and mutations.
Context: A custom get_context_value function is used to inject request-specific data into the resolver context.
Routes: The server supports HTTP requests via /db and WebSocket subscriptions via /socket.
Middleware: CORS middleware is added to handle cross-origin requests, allowing interactions from any origin.
Middleware¶
The CORS (Cross-Origin Resource Sharing) middleware is configured to:
Allow requests from any origin (allow_origins=[“*”]).
Allow credentials, methods, and headers to ensure full access from external clients.
GraphQL Resolvers¶
The implementation includes several key resolver functions that handle mutations for interacting with Tango devices. These are built using Ariadne’s ObjectType and decorated with authorization checks.
Mutations: The core mutations allow modification of Tango device properties and attributes, as well as execution of device commands.
putDeviceProperty: Allows the setting of device properties using the async TangoDB.
deleteDeviceProperty: Deletes properties from a Tango device.
setAttributeValue: Updates a Tango device’s attribute with a new value and returns the previous value for reference.
executeCommand: Executes a Tango device command, optionally with arguments.
Each mutation is wrapped with an authorization check using the @check_auth decorator to verify if the client has the required credentials and group memberships before proceeding with the operation.
Error Handling¶
Each resolver is designed to handle common errors, such as:
tango.DevFailed exceptions when device operations fail.
TypeError exceptions when the input argument types are invalid.
Error messages are logged for debugging purposes, and a standard response structure is returned to the client indicating the success or failure of the operation.
Authentication and Authorization¶
The authentication mechanism relies on JWT (JSON Web Tokens) stored in client cookies. These tokens are verified on each request to ensure that the user is logged in and belongs to the required groups.
Auth Claims: The authentication information is extracted from the taranta_jwt cookie and verified using the application’s secret key.
Authorization Checks: The check_auth decorator enforces that only authorized users (those belonging to the necessary groups) can perform certain operations. This can be disabled globally by setting the NO_AUTH environment variable, allowing all requests to bypass authentication.
Custom GraphQL errors are defined for handling authentication and authorization issues:
AuthenticationError: Raised when the user is not logged in.
AuthorizationError: Raised when the user does not belong to the required groups to execute a specific operation.
Summary of Key Functionalities:¶
GraphQL Queries: Serve queries and mutations through HTTP and WebSocket routes using Ariadne’s GraphQL handler.
Mutations: Support for key operations such as setting device properties, writing attributes, and executing commands on Tango devices.
Authorization: JWT-based authentication with group membership enforcement to control access to resolvers.
Error Handling: Robust logging and exception management for Tango device operations and input validation.