open-feature / python-sdk

Python SDK for OpenFeature
https://openfeature.dev
Apache License 2.0
48 stars 16 forks source link

[FEATURE] Implement transaction context #292

Open toddbaert opened 6 months ago

toddbaert commented 6 months ago

Requirements

We should implement transaction context propagation

What is transaction context?

From the spec: Transaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP). Transaction context can be set where specific data is available (e.g. an auth service or request handler) and by using the transaction context propagator it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread).

Transaction context has been added in the following PR: https://github.com/open-feature/spec/pull/227

Examples:

Implementation

The JS SDK implementation is implemented as a POC that is currently being hardened. https://github.com/open-feature/js-sdk/blob/main/packages/server/src/transaction-context/transaction-context.ts We'd need to define some interfaces to support the construction various context propagation mechanisms, for instance, one based on the flask context.

Usage

An example usage for the JS SDK implementation of the feature is the usage for propagating HTTP request information in the NestJS SDK. https://github.com/open-feature/js-sdk/blob/main/packages/nest/src/evaluation-context-interceptor.ts#L31

federicobond commented 5 months ago

We could prototype a propagator based on contextvars which are sort of threadlocals that also work well in async contexts. This would be framework-agnostic and should be compatible with both Django and Flask.

federicobond commented 5 months ago

Must the API be designed to lexically scope the transaction context, as in a context manager, so that it cleans up after itself? Or is it permissible to set the transaction evaluation context and return, leaving the cleanup for a separate method?

What happens if it's called nested? Does the nested context override the previous and then restores it on exit?