Run queries
Your pipeline is deployed, and keys are already generated. Now you run encrypted queries against it. Start a worker, load the existing key, send as many queries as you need, then stop the worker. The worker only ever receives ciphertext, so your input and result stay private.
Start, load key, query, stop
Querying is a loop with a clear start and end. You turn a worker on, load the key you generated in Key generation, run queries while it is up, and turn it off when you are done.
Start worker
Turn the worker on when you are ready.
credits beginLoad existing key
Call keys.ensure() to reuse the local key and load the registered EVK on the worker.
×N
query.encrypted()
Send a query, get a result. Repeat as many times as you want.
while worker is upStop worker
Turn it off when your work is done.
credits stopYou pay for the worker's runtime, not per query
Start the worker
A worker runs the body of your pipeline. Start it with the
model_id from deploy. It uses credits from this moment until you stop it, so start it when you are ready to query.query.pyPYTHON
# credits begin here with studio.workers.running(model_id, stop_on_exit=True): # load key and run queries inside this block ...
Load the existing key
Create a query client with the access token from Key generation, then call
client.keys.ensure(). It reuses the key artifacts already on your machine; it does not generate or upload a second evaluation key. After the worker starts, it loads the evaluation key already registered for this model. You installed the query client with Lattica Studio at setup. In a researcher setup, that is the same environment you deployed from.query.pyPYTHON
from lattica_query import QueryClient token = studio.tokens.load("MY_MNIST_MODEL") with QueryClient(token) as client: # reuse local key artifacts; the worker loads the registered EVK key = client.keys.ensure()
Load the token with
studio.tokens.load using the same model_name you saved. keys.ensure() returns the local key your queries need. If the worker has just started, the client also makes sure the registered evaluation key is ready on its GPU.Run a query
client.query.encrypted(...) encrypts your input, runs it on the worker, and decrypts the result for you. The complete snippet keeps key loading and encrypted inference inside the worker session. Your plaintext never leaves your machine.query.pyPYTHON
from lattica_query import QueryClient token = studio.tokens.load("MY_MNIST_MODEL") with studio.workers.running(model_id, stop_on_exit=True): with QueryClient(token) as client: key = client.keys.ensure() # run as many times as you need while the worker is up result = client.query.encrypted(x, key=key) y_pred = result.argmax(dim=-1)
Inside that one call, three things happen:
Encrypt
Your input is encrypted on your machine. It is packed into slots first, and the last block is filled with zeros.
ciphertext
Run on worker
the worker computes on ciphertext
ciphertext
Decrypt
the result is decrypted, just for you
Run it again with a different input as often as you like. The worker stays up between queries, so each one is a single call.
Stop the worker
When you are done, stop the worker. Credits stop the moment it goes down. If you used
studio.workers.running(..., stop_on_exit=True), the worker stops when the block exits.query.pyPYTHON
# credits stop when the context exits (stop_on_exit=True) studio.workers.stop(model_id=model_id)
Leave the worker running only while you need it. Billing is by runtime, so a worker left up keeps using credits even when idle. Start it for a session of queries, then stop it.
The full flow
That completes the path: from a plaintext input to an encrypted answer and back, after deploy and key generation.
Build → Deploy → Key generation → Query
Next
See it all together
End-to-End Example
One runnable walkthrough that threads build, deploy, key generation, and query in a single script.