Nice to have modularization, not-blocking for 3.3.0 release.
Dependency
Background
The Go SDK has two independent implementations of the same Python-parity rule that an environment variable named AIRFLOW_VAR_<UPPER(key)> short-circuits GetVariable and is returned in preference to the supervisor-stored value (matching airflow.models.variable.Variable.get).
The HTTP-backed client uses an unexported helper:
// go-sdk/sdk/client.go
func variableFromEnv(key string) (string, bool) {
return os.LookupEnv(VariableEnvPrefix + strings.ToUpper(key))
}
func (*client) GetVariable(ctx context.Context, key string) (string, error) {
// TODO: Let the lookup priority be configurable like it is in Python SDK
if env, ok := variableFromEnv(key); ok {
return env, nil
}
...
}
The coordinator-mode client inlines the same logic and carries a TODO calling out the duplication:
// go-sdk/pkg/execution/client.go
func (c *CoordinatorClient) GetVariable(ctx context.Context, key string) (string, error) {
// TODO: this duplicates variableFromEnv in sdk/client.go. The env-first
// precedence is part of the SDK contract, so both clients should share a
// single helper (e.g. an exported sdk.VariableFromEnv) instead of two
// independent copies that can drift.
if env, ok := os.LookupEnv(sdk.VariableEnvPrefix + strings.ToUpper(key)); ok {
return env, nil
}
...
}
The env-first lookup order is part of the public Go SDK contract; two independently maintained copies can silently drift, particularly if the lookup precedence is made configurable later (as the HTTP-side TODO notes).
What needs to happen
- Promote
variableFromEnv to an exported helper on the sdk package — e.g. sdk.VariableFromEnv(key string) (string, bool) — so the env-override logic has a single canonical implementation.
- Update
go-sdk/sdk/client.go to call the exported helper.
- Update
go-sdk/pkg/execution/client.go CoordinatorClient.GetVariable to call the same exported helper and drop the inlined os.LookupEnv block.
- Remove the duplication TODO in
pkg/execution/client.go.
Acceptance criteria
- Only one implementation of the
AIRFLOW_VAR_* env-override lookup exists in the Go SDK source tree.
- Both
sdk.client and execution.CoordinatorClient call the shared helper.
- Existing tests (
TestCoordinatorClientGetVariableEnvOverride and any HTTP-side equivalent) continue to pass without modification, or are updated to exercise the shared helper directly if duplication of the test coverage no longer makes sense.
Context
Nice to have modularization, not-blocking for 3.3.0 release.
Dependency
main.Background
The Go SDK has two independent implementations of the same Python-parity rule that an environment variable named
AIRFLOW_VAR_<UPPER(key)>short-circuitsGetVariableand is returned in preference to the supervisor-stored value (matchingairflow.models.variable.Variable.get).The HTTP-backed client uses an unexported helper:
The coordinator-mode client inlines the same logic and carries a TODO calling out the duplication:
The env-first lookup order is part of the public Go SDK contract; two independently maintained copies can silently drift, particularly if the lookup precedence is made configurable later (as the HTTP-side TODO notes).
What needs to happen
variableFromEnvto an exported helper on thesdkpackage — e.g.sdk.VariableFromEnv(key string) (string, bool)— so the env-override logic has a single canonical implementation.go-sdk/sdk/client.goto call the exported helper.go-sdk/pkg/execution/client.goCoordinatorClient.GetVariableto call the same exported helper and drop the inlinedos.LookupEnvblock.pkg/execution/client.go.Acceptance criteria
AIRFLOW_VAR_*env-override lookup exists in the Go SDK source tree.sdk.clientandexecution.CoordinatorClientcall the shared helper.TestCoordinatorClientGetVariableEnvOverrideand any HTTP-side equivalent) continue to pass without modification, or are updated to exercise the shared helper directly if duplication of the test coverage no longer makes sense.Context
go-sdk/sdk/client.go(variableFromEnv).go-sdk/pkg/execution/client.goCoordinatorClient.GetVariable.