Skip to content

Commit fc4edc9

Browse files
committed
Add team_id to variable APIs
1 parent e95748a commit fc4edc9

File tree

9 files changed

+149
-9
lines changed

9 files changed

+149
-9
lines changed

airflow-core/src/airflow/api_fastapi/core_api/datamodels/variables.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import json
2121
from collections.abc import Iterable
22+
from uuid import UUID
2223

2324
from pydantic import Field, JsonValue, model_validator
2425

@@ -35,6 +36,7 @@ class VariableResponse(BaseModel):
3536
val: str = Field(alias="value")
3637
description: str | None
3738
is_encrypted: bool
39+
team_id: UUID | None
3840

3941
@model_validator(mode="after")
4042
def redact_val(self) -> Self:
@@ -57,6 +59,7 @@ class VariableBody(StrictBaseModel):
5759
key: str = Field(max_length=ID_LEN)
5860
value: JsonValue = Field(serialization_alias="val")
5961
description: str | None = Field(default=None)
62+
team_id: UUID | None = Field(default=None)
6063

6164

6265
class VariableCollectionResponse(BaseModel):

airflow-core/src/airflow/api_fastapi/core_api/openapi/v2-rest-api-generated.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13034,6 +13034,12 @@ components:
1303413034
- type: string
1303513035
- type: 'null'
1303613036
title: Description
13037+
team_id:
13038+
anyOf:
13039+
- type: string
13040+
format: uuid
13041+
- type: 'null'
13042+
title: Team Id
1303713043
additionalProperties: false
1303813044
type: object
1303913045
required:
@@ -13073,12 +13079,19 @@ components:
1307313079
is_encrypted:
1307413080
type: boolean
1307513081
title: Is Encrypted
13082+
team_id:
13083+
anyOf:
13084+
- type: string
13085+
format: uuid
13086+
- type: 'null'
13087+
title: Team Id
1307613088
type: object
1307713089
required:
1307813090
- key
1307913091
- value
1308013092
- description
1308113093
- is_encrypted
13094+
- team_id
1308213095
title: VariableResponse
1308313096
description: Variable serializer for responses.
1308413097
VersionInfo:

airflow-core/src/airflow/models/variable.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from sqlalchemy_utils import UUIDType
3131

3232
from airflow._shared.secrets_masker import mask_secret
33-
from airflow.configuration import ensure_secrets_loaded
33+
from airflow.configuration import conf, ensure_secrets_loaded
3434
from airflow.models.base import ID_LEN, Base
3535
from airflow.models.crypto import get_fernet
3636
from airflow.models.team import Team
@@ -146,7 +146,7 @@ def get(
146146
# means SQLA etc is loaded, but we can't avoid that unless/until we add import shims as a big
147147
# back-compat layer
148148

149-
# If this is set it means are in some kind of execution context (Task, Dag Parse or Triggerer perhaps)
149+
# If this is set it means we are in some kind of execution context (Task, Dag Parse or Triggerer perhaps)
150150
# and should use the Task SDK API server path
151151
if hasattr(sys.modules.get("airflow.sdk.execution_time.task_runner"), "SUPERVISOR_COMMS"):
152152
warnings.warn(
@@ -186,6 +186,7 @@ def set(
186186
value: Any,
187187
description: str | None = None,
188188
serialize_json: bool = False,
189+
team_id: str | None = None,
189190
session: Session | None = None,
190191
) -> None:
191192
"""
@@ -197,13 +198,14 @@ def set(
197198
:param value: Value to set for the Variable
198199
:param description: Description of the Variable
199200
:param serialize_json: Serialize the value to a JSON string
201+
:param team_id: ID of the team associated to the variable (if any)
200202
:param session: optional session, use if provided or create a new one
201203
"""
202204
# TODO: This is not the best way of having compat, but it's "better than erroring" for now. This still
203205
# means SQLA etc is loaded, but we can't avoid that unless/until we add import shims as a big
204206
# back-compat layer
205207

206-
# If this is set it means are in some kind of execution context (Task, Dag Parse or Triggerer perhaps)
208+
# If this is set it means we are in some kind of execution context (Task, Dag Parse or Triggerer perhaps)
207209
# and should use the Task SDK API server path
208210
if hasattr(sys.modules.get("airflow.sdk.execution_time.task_runner"), "SUPERVISOR_COMMS"):
209211
warnings.warn(
@@ -222,6 +224,11 @@ def set(
222224
)
223225
return
224226

227+
if team_id and not conf.getboolean("core", "multi_team"):
228+
raise ValueError(
229+
"Multi-team mode is not configured in the Airflow environment. To assign a team to a variable, multi-mode must be enabled."
230+
)
231+
225232
# check if the secret exists in the custom secrets' backend.
226233
Variable.check_for_write_conflict(key=key)
227234
if serialize_json:
@@ -236,7 +243,7 @@ def set(
236243
ctx = create_session()
237244

238245
with ctx as session:
239-
new_variable = Variable(key=key, val=stored_value, description=description)
246+
new_variable = Variable(key=key, val=stored_value, description=description, team_id=team_id)
240247

241248
val = new_variable._val
242249
is_encrypted = new_variable.is_encrypted
@@ -255,6 +262,7 @@ def set(
255262
val=val,
256263
description=description,
257264
is_encrypted=is_encrypted,
265+
team_id=team_id,
258266
)
259267

260268
# Apply dialect-specific upsert
@@ -264,6 +272,7 @@ def set(
264272
val=val,
265273
description=description,
266274
is_encrypted=is_encrypted,
275+
team_id=team_id,
267276
)
268277
else:
269278
# PostgreSQL and SQLite: ON CONFLICT DO UPDATE
@@ -273,6 +282,7 @@ def set(
273282
val=val,
274283
description=description,
275284
is_encrypted=is_encrypted,
285+
team_id=team_id,
276286
),
277287
)
278288

airflow-core/src/airflow/ui/openapi-gen/requests/schemas.gen.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6505,6 +6505,18 @@ export const $VariableBody = {
65056505
}
65066506
],
65076507
title: 'Description'
6508+
},
6509+
team_id: {
6510+
anyOf: [
6511+
{
6512+
type: 'string',
6513+
format: 'uuid'
6514+
},
6515+
{
6516+
type: 'null'
6517+
}
6518+
],
6519+
title: 'Team Id'
65086520
}
65096521
},
65106522
additionalProperties: false,
@@ -6558,10 +6570,22 @@ export const $VariableResponse = {
65586570
is_encrypted: {
65596571
type: 'boolean',
65606572
title: 'Is Encrypted'
6573+
},
6574+
team_id: {
6575+
anyOf: [
6576+
{
6577+
type: 'string',
6578+
format: 'uuid'
6579+
},
6580+
{
6581+
type: 'null'
6582+
}
6583+
],
6584+
title: 'Team Id'
65616585
}
65626586
},
65636587
type: 'object',
6564-
required: ['key', 'value', 'description', 'is_encrypted'],
6588+
required: ['key', 'value', 'description', 'is_encrypted', 'team_id'],
65656589
title: 'VariableResponse',
65666590
description: 'Variable serializer for responses.'
65676591
} as const;

airflow-core/src/airflow/ui/openapi-gen/requests/types.gen.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,7 @@ export type VariableBody = {
15881588
key: string;
15891589
value: JsonValue;
15901590
description?: string | null;
1591+
team_id?: string | null;
15911592
};
15921593

15931594
/**
@@ -1606,6 +1607,7 @@ export type VariableResponse = {
16061607
value: string;
16071608
description: string | null;
16081609
is_encrypted: boolean;
1610+
team_id: string | null;
16091611
};
16101612

16111613
/**

0 commit comments

Comments
 (0)