You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
encrypt returns a list of dicts, one per model, with a str EQL payload for each sealed field and the plaintext echoed for each Passthrough field; Ignore fields are absent. psycopg inserts the str with a plain %s into a public.eql_v4_text_eq column; no cast. The dicts are built in Rust from the engine's output tree; plaintext does not pass through a Python dict on the way in.
One engine client per process behind OnceLock with a multi-thread tokio runtime, AutoStrategy and the http feature; the default keyset loads when the client is first built. The GIL is released around the engine call. Request batching is the engine's: ceil(values / 500) requests per call.
Live test infrastructure arrives here: a Postgres container with the EQL v4 bundle, a pytest marker that skips without credentials, and the CI live job in tests-python.yml behind require-cs-secrets with its BINDING_EXEMPT_JOBS entry.
Acceptance criteria
The snippet above inserts a row that SELECT email FROM users returns as a non-null eql_v4_text_eq value.
encrypt([]) returns [] with no request.
A value whose Python type is not the field's exact type raises InvalidValueError with VALUE_WRONG_TYPE before any request (bool for an int field included).
1001 one-field models make exactly three ZeroKMS requests (observed through the engine's request counter or a recording transport).
Two Cipher instances in one process share the engine client (observed through a process-wide counter the engine crate exposes for tests).
The live CI job runs on PRs from the repo, skips on forks, and the ffi-binding-step-order test accepts it.
A README stub in the Python workspace shows the DDL for the column and this snippet.
Activity
Cipher(cls)checks #1388decryptrows back into models #1390queryan equality term #1391