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 generate_key(load_if_exists=True) to reuse the Stage 3 key context.
×N
run_query()
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
generate_key(load_if_exists=True). That loads the secret key already on your machine. It does not generate a new key or re-register the evaluation key if those artifacts already exist. 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") query_client = QueryClient(token) # load the key generated in Key generation sk = query_client.generate_key(load_if_exists=True)
Load the token with
studio.tokens.load using the same model_name you saved. generate_key(load_if_exists=True) returns the secret key your queries need.Run a query
One call encrypts your input, runs it on the worker, and decrypts the result for you. Your plaintext never leaves your machine.
query.pyPYTHON
# run as many times as you need while the worker is up res = query_client.run_query(sk, pt) y_pred = res.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.