airbyte-agent-linear 0.19.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_agent_linear/__init__.py +43 -0
- airbyte_agent_linear/_vendored/__init__.py +1 -0
- airbyte_agent_linear/_vendored/connector_sdk/__init__.py +82 -0
- airbyte_agent_linear/_vendored/connector_sdk/auth_strategies.py +1123 -0
- airbyte_agent_linear/_vendored/connector_sdk/auth_template.py +135 -0
- airbyte_agent_linear/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
- airbyte_agent_linear/_vendored/connector_sdk/cloud_utils/client.py +213 -0
- airbyte_agent_linear/_vendored/connector_sdk/connector_model_loader.py +957 -0
- airbyte_agent_linear/_vendored/connector_sdk/constants.py +78 -0
- airbyte_agent_linear/_vendored/connector_sdk/exceptions.py +23 -0
- airbyte_agent_linear/_vendored/connector_sdk/executor/__init__.py +31 -0
- airbyte_agent_linear/_vendored/connector_sdk/executor/hosted_executor.py +197 -0
- airbyte_agent_linear/_vendored/connector_sdk/executor/local_executor.py +1504 -0
- airbyte_agent_linear/_vendored/connector_sdk/executor/models.py +190 -0
- airbyte_agent_linear/_vendored/connector_sdk/extensions.py +655 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/__init__.py +37 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/config.py +98 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/exceptions.py +119 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/protocols.py +114 -0
- airbyte_agent_linear/_vendored/connector_sdk/http/response.py +102 -0
- airbyte_agent_linear/_vendored/connector_sdk/http_client.py +679 -0
- airbyte_agent_linear/_vendored/connector_sdk/logging/__init__.py +11 -0
- airbyte_agent_linear/_vendored/connector_sdk/logging/logger.py +264 -0
- airbyte_agent_linear/_vendored/connector_sdk/logging/types.py +92 -0
- airbyte_agent_linear/_vendored/connector_sdk/observability/__init__.py +11 -0
- airbyte_agent_linear/_vendored/connector_sdk/observability/models.py +19 -0
- airbyte_agent_linear/_vendored/connector_sdk/observability/redactor.py +81 -0
- airbyte_agent_linear/_vendored/connector_sdk/observability/session.py +94 -0
- airbyte_agent_linear/_vendored/connector_sdk/performance/__init__.py +6 -0
- airbyte_agent_linear/_vendored/connector_sdk/performance/instrumentation.py +57 -0
- airbyte_agent_linear/_vendored/connector_sdk/performance/metrics.py +93 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/__init__.py +75 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/base.py +161 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/components.py +238 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/connector.py +131 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/extensions.py +109 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/operations.py +146 -0
- airbyte_agent_linear/_vendored/connector_sdk/schema/security.py +213 -0
- airbyte_agent_linear/_vendored/connector_sdk/secrets.py +182 -0
- airbyte_agent_linear/_vendored/connector_sdk/telemetry/__init__.py +10 -0
- airbyte_agent_linear/_vendored/connector_sdk/telemetry/config.py +32 -0
- airbyte_agent_linear/_vendored/connector_sdk/telemetry/events.py +58 -0
- airbyte_agent_linear/_vendored/connector_sdk/telemetry/tracker.py +151 -0
- airbyte_agent_linear/_vendored/connector_sdk/types.py +241 -0
- airbyte_agent_linear/_vendored/connector_sdk/utils.py +60 -0
- airbyte_agent_linear/_vendored/connector_sdk/validation.py +822 -0
- airbyte_agent_linear/connector.py +460 -0
- airbyte_agent_linear/connector_model.py +780 -0
- airbyte_agent_linear/models.py +221 -0
- airbyte_agent_linear/types.py +44 -0
- airbyte_agent_linear-0.19.18.dist-info/METADATA +101 -0
- airbyte_agent_linear-0.19.18.dist-info/RECORD +55 -0
- airbyte_agent_linear-0.19.18.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"""
|
|
2
|
+
linear connector.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, overload
|
|
8
|
+
try:
|
|
9
|
+
from typing import Literal
|
|
10
|
+
except ImportError:
|
|
11
|
+
from typing_extensions import Literal
|
|
12
|
+
|
|
13
|
+
from .connector_model import LinearConnectorModel
|
|
14
|
+
|
|
15
|
+
from .types import (
|
|
16
|
+
IssuesGetParams,
|
|
17
|
+
IssuesListParams,
|
|
18
|
+
ProjectsGetParams,
|
|
19
|
+
ProjectsListParams,
|
|
20
|
+
TeamsGetParams,
|
|
21
|
+
TeamsListParams,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from .models import LinearAuthConfig
|
|
26
|
+
# Import response models and envelope models at runtime
|
|
27
|
+
from .models import (
|
|
28
|
+
LinearExecuteResult,
|
|
29
|
+
LinearExecuteResultWithMeta,
|
|
30
|
+
IssueResponse,
|
|
31
|
+
IssuesListResponse,
|
|
32
|
+
ProjectResponse,
|
|
33
|
+
ProjectsListResponse,
|
|
34
|
+
TeamResponse,
|
|
35
|
+
TeamsListResponse,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class LinearConnector:
|
|
40
|
+
"""
|
|
41
|
+
Type-safe Linear API connector.
|
|
42
|
+
|
|
43
|
+
Auto-generated from OpenAPI specification with full type safety.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
connector_name = "linear"
|
|
47
|
+
connector_version = "0.1.1"
|
|
48
|
+
vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
|
|
49
|
+
|
|
50
|
+
# Map of (entity, action) -> has_extractors for envelope wrapping decision
|
|
51
|
+
_EXTRACTOR_MAP = {
|
|
52
|
+
("issues", "list"): False,
|
|
53
|
+
("issues", "get"): False,
|
|
54
|
+
("projects", "list"): False,
|
|
55
|
+
("projects", "get"): False,
|
|
56
|
+
("teams", "list"): False,
|
|
57
|
+
("teams", "get"): False,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Map of (entity, action) -> {python_param_name: api_param_name}
|
|
61
|
+
# Used to convert snake_case TypedDict keys to API parameter names in execute()
|
|
62
|
+
_PARAM_MAP = {
|
|
63
|
+
('issues', 'list'): {'first': 'first', 'after': 'after'},
|
|
64
|
+
('issues', 'get'): {'id': 'id'},
|
|
65
|
+
('projects', 'list'): {'first': 'first', 'after': 'after'},
|
|
66
|
+
('projects', 'get'): {'id': 'id'},
|
|
67
|
+
('teams', 'list'): {'first': 'first', 'after': 'after'},
|
|
68
|
+
('teams', 'get'): {'id': 'id'},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
auth_config: LinearAuthConfig | None = None,
|
|
74
|
+
external_user_id: str | None = None,
|
|
75
|
+
airbyte_client_id: str | None = None,
|
|
76
|
+
airbyte_client_secret: str | None = None,
|
|
77
|
+
on_token_refresh: Any | None = None ):
|
|
78
|
+
"""
|
|
79
|
+
Initialize a new linear connector instance.
|
|
80
|
+
|
|
81
|
+
Supports both local and hosted execution modes:
|
|
82
|
+
- Local mode: Provide `auth_config` for direct API calls
|
|
83
|
+
- Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
auth_config: Typed authentication configuration (required for local mode)
|
|
87
|
+
external_user_id: External user ID (required for hosted mode)
|
|
88
|
+
airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
|
|
89
|
+
airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
|
|
90
|
+
on_token_refresh: Optional callback for OAuth2 token refresh persistence.
|
|
91
|
+
Called with new_tokens dict when tokens are refreshed. Can be sync or async.
|
|
92
|
+
Example: lambda tokens: save_to_database(tokens)
|
|
93
|
+
Examples:
|
|
94
|
+
# Local mode (direct API calls)
|
|
95
|
+
connector = LinearConnector(auth_config=LinearAuthConfig(api_key="..."))
|
|
96
|
+
# Hosted mode (executed on Airbyte cloud)
|
|
97
|
+
connector = LinearConnector(
|
|
98
|
+
external_user_id="user-123",
|
|
99
|
+
airbyte_client_id="client_abc123",
|
|
100
|
+
airbyte_client_secret="secret_xyz789"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# Local mode with OAuth2 token refresh callback
|
|
104
|
+
def save_tokens(new_tokens: dict) -> None:
|
|
105
|
+
# Persist updated tokens to your storage (file, database, etc.)
|
|
106
|
+
with open("tokens.json", "w") as f:
|
|
107
|
+
json.dump(new_tokens, f)
|
|
108
|
+
|
|
109
|
+
connector = LinearConnector(
|
|
110
|
+
auth_config=LinearAuthConfig(access_token="...", refresh_token="..."),
|
|
111
|
+
on_token_refresh=save_tokens
|
|
112
|
+
)
|
|
113
|
+
"""
|
|
114
|
+
# Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
|
|
115
|
+
if external_user_id and airbyte_client_id and airbyte_client_secret:
|
|
116
|
+
from ._vendored.connector_sdk.executor import HostedExecutor
|
|
117
|
+
self._executor = HostedExecutor(
|
|
118
|
+
external_user_id=external_user_id,
|
|
119
|
+
airbyte_client_id=airbyte_client_id,
|
|
120
|
+
airbyte_client_secret=airbyte_client_secret,
|
|
121
|
+
connector_definition_id=str(LinearConnectorModel.id),
|
|
122
|
+
)
|
|
123
|
+
else:
|
|
124
|
+
# Local mode: auth_config required
|
|
125
|
+
if not auth_config:
|
|
126
|
+
raise ValueError(
|
|
127
|
+
"Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
|
|
128
|
+
"or auth_config for local mode"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
from ._vendored.connector_sdk.executor import LocalExecutor
|
|
132
|
+
|
|
133
|
+
# Build config_values dict from server variables
|
|
134
|
+
config_values = None
|
|
135
|
+
|
|
136
|
+
self._executor = LocalExecutor(
|
|
137
|
+
model=LinearConnectorModel,
|
|
138
|
+
auth_config=auth_config.model_dump() if auth_config else None,
|
|
139
|
+
config_values=config_values,
|
|
140
|
+
on_token_refresh=on_token_refresh
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Update base_url with server variables if provided
|
|
144
|
+
|
|
145
|
+
# Initialize entity query objects
|
|
146
|
+
self.issues = IssuesQuery(self)
|
|
147
|
+
self.projects = ProjectsQuery(self)
|
|
148
|
+
self.teams = TeamsQuery(self)
|
|
149
|
+
|
|
150
|
+
# ===== TYPED EXECUTE METHOD (Recommended Interface) =====
|
|
151
|
+
|
|
152
|
+
@overload
|
|
153
|
+
async def execute(
|
|
154
|
+
self,
|
|
155
|
+
entity: Literal["issues"],
|
|
156
|
+
action: Literal["list"],
|
|
157
|
+
params: "IssuesListParams"
|
|
158
|
+
) -> "IssuesListResponse": ...
|
|
159
|
+
|
|
160
|
+
@overload
|
|
161
|
+
async def execute(
|
|
162
|
+
self,
|
|
163
|
+
entity: Literal["issues"],
|
|
164
|
+
action: Literal["get"],
|
|
165
|
+
params: "IssuesGetParams"
|
|
166
|
+
) -> "IssueResponse": ...
|
|
167
|
+
|
|
168
|
+
@overload
|
|
169
|
+
async def execute(
|
|
170
|
+
self,
|
|
171
|
+
entity: Literal["projects"],
|
|
172
|
+
action: Literal["list"],
|
|
173
|
+
params: "ProjectsListParams"
|
|
174
|
+
) -> "ProjectsListResponse": ...
|
|
175
|
+
|
|
176
|
+
@overload
|
|
177
|
+
async def execute(
|
|
178
|
+
self,
|
|
179
|
+
entity: Literal["projects"],
|
|
180
|
+
action: Literal["get"],
|
|
181
|
+
params: "ProjectsGetParams"
|
|
182
|
+
) -> "ProjectResponse": ...
|
|
183
|
+
|
|
184
|
+
@overload
|
|
185
|
+
async def execute(
|
|
186
|
+
self,
|
|
187
|
+
entity: Literal["teams"],
|
|
188
|
+
action: Literal["list"],
|
|
189
|
+
params: "TeamsListParams"
|
|
190
|
+
) -> "TeamsListResponse": ...
|
|
191
|
+
|
|
192
|
+
@overload
|
|
193
|
+
async def execute(
|
|
194
|
+
self,
|
|
195
|
+
entity: Literal["teams"],
|
|
196
|
+
action: Literal["get"],
|
|
197
|
+
params: "TeamsGetParams"
|
|
198
|
+
) -> "TeamResponse": ...
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@overload
|
|
202
|
+
async def execute(
|
|
203
|
+
self,
|
|
204
|
+
entity: str,
|
|
205
|
+
action: str,
|
|
206
|
+
params: dict[str, Any]
|
|
207
|
+
) -> LinearExecuteResult[Any] | LinearExecuteResultWithMeta[Any, Any] | Any: ...
|
|
208
|
+
|
|
209
|
+
async def execute(
|
|
210
|
+
self,
|
|
211
|
+
entity: str,
|
|
212
|
+
action: str,
|
|
213
|
+
params: dict[str, Any] | None = None
|
|
214
|
+
) -> Any:
|
|
215
|
+
"""
|
|
216
|
+
Execute an entity operation with full type safety.
|
|
217
|
+
|
|
218
|
+
This is the recommended interface for blessed connectors as it:
|
|
219
|
+
- Uses the same signature as non-blessed connectors
|
|
220
|
+
- Provides full IDE autocomplete for entity/action/params
|
|
221
|
+
- Makes migration from generic to blessed connectors seamless
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
entity: Entity name (e.g., "customers")
|
|
225
|
+
action: Operation action (e.g., "create", "get", "list")
|
|
226
|
+
params: Operation parameters (typed based on entity+action)
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Typed response based on the operation
|
|
230
|
+
|
|
231
|
+
Example:
|
|
232
|
+
customer = await connector.execute(
|
|
233
|
+
entity="customers",
|
|
234
|
+
action="get",
|
|
235
|
+
params={"id": "cus_123"}
|
|
236
|
+
)
|
|
237
|
+
"""
|
|
238
|
+
from ._vendored.connector_sdk.executor import ExecutionConfig
|
|
239
|
+
|
|
240
|
+
# Remap parameter names from snake_case (TypedDict keys) to API parameter names
|
|
241
|
+
if params:
|
|
242
|
+
param_map = self._PARAM_MAP.get((entity, action), {})
|
|
243
|
+
if param_map:
|
|
244
|
+
params = {param_map.get(k, k): v for k, v in params.items()}
|
|
245
|
+
|
|
246
|
+
# Use ExecutionConfig for both local and hosted executors
|
|
247
|
+
config = ExecutionConfig(
|
|
248
|
+
entity=entity,
|
|
249
|
+
action=action,
|
|
250
|
+
params=params
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
result = await self._executor.execute(config)
|
|
254
|
+
|
|
255
|
+
if not result.success:
|
|
256
|
+
raise RuntimeError(f"Execution failed: {result.error}")
|
|
257
|
+
|
|
258
|
+
# Check if this operation has extractors configured
|
|
259
|
+
has_extractors = self._EXTRACTOR_MAP.get((entity, action), False)
|
|
260
|
+
|
|
261
|
+
if has_extractors:
|
|
262
|
+
# With extractors - return Pydantic envelope with data and meta
|
|
263
|
+
if result.meta is not None:
|
|
264
|
+
return LinearExecuteResultWithMeta[Any, Any](
|
|
265
|
+
data=result.data,
|
|
266
|
+
meta=result.meta
|
|
267
|
+
)
|
|
268
|
+
else:
|
|
269
|
+
return LinearExecuteResult[Any](data=result.data)
|
|
270
|
+
else:
|
|
271
|
+
# No extractors - return raw response data
|
|
272
|
+
return result.data
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
class IssuesQuery:
|
|
277
|
+
"""
|
|
278
|
+
Query class for Issues entity operations.
|
|
279
|
+
"""
|
|
280
|
+
|
|
281
|
+
def __init__(self, connector: LinearConnector):
|
|
282
|
+
"""Initialize query with connector reference."""
|
|
283
|
+
self._connector = connector
|
|
284
|
+
|
|
285
|
+
async def list(
|
|
286
|
+
self,
|
|
287
|
+
first: int | None = None,
|
|
288
|
+
after: str | None = None,
|
|
289
|
+
**kwargs
|
|
290
|
+
) -> IssuesListResponse:
|
|
291
|
+
"""
|
|
292
|
+
Returns a paginated list of issues via GraphQL with pagination support
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
first: Number of items to return (max 250)
|
|
296
|
+
after: Cursor to start after (for pagination)
|
|
297
|
+
**kwargs: Additional parameters
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
IssuesListResponse
|
|
301
|
+
"""
|
|
302
|
+
params = {k: v for k, v in {
|
|
303
|
+
"first": first,
|
|
304
|
+
"after": after,
|
|
305
|
+
**kwargs
|
|
306
|
+
}.items() if v is not None}
|
|
307
|
+
|
|
308
|
+
result = await self._connector.execute("issues", "list", params)
|
|
309
|
+
return result
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
async def get(
|
|
314
|
+
self,
|
|
315
|
+
id: str | None = None,
|
|
316
|
+
**kwargs
|
|
317
|
+
) -> IssueResponse:
|
|
318
|
+
"""
|
|
319
|
+
Get a single issue by ID via GraphQL
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
id: Issue ID
|
|
323
|
+
**kwargs: Additional parameters
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
IssueResponse
|
|
327
|
+
"""
|
|
328
|
+
params = {k: v for k, v in {
|
|
329
|
+
"id": id,
|
|
330
|
+
**kwargs
|
|
331
|
+
}.items() if v is not None}
|
|
332
|
+
|
|
333
|
+
result = await self._connector.execute("issues", "get", params)
|
|
334
|
+
return result
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class ProjectsQuery:
|
|
339
|
+
"""
|
|
340
|
+
Query class for Projects entity operations.
|
|
341
|
+
"""
|
|
342
|
+
|
|
343
|
+
def __init__(self, connector: LinearConnector):
|
|
344
|
+
"""Initialize query with connector reference."""
|
|
345
|
+
self._connector = connector
|
|
346
|
+
|
|
347
|
+
async def list(
|
|
348
|
+
self,
|
|
349
|
+
first: int | None = None,
|
|
350
|
+
after: str | None = None,
|
|
351
|
+
**kwargs
|
|
352
|
+
) -> ProjectsListResponse:
|
|
353
|
+
"""
|
|
354
|
+
Returns a paginated list of projects via GraphQL with pagination support
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
first: Number of items to return (max 250)
|
|
358
|
+
after: Cursor to start after (for pagination)
|
|
359
|
+
**kwargs: Additional parameters
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
ProjectsListResponse
|
|
363
|
+
"""
|
|
364
|
+
params = {k: v for k, v in {
|
|
365
|
+
"first": first,
|
|
366
|
+
"after": after,
|
|
367
|
+
**kwargs
|
|
368
|
+
}.items() if v is not None}
|
|
369
|
+
|
|
370
|
+
result = await self._connector.execute("projects", "list", params)
|
|
371
|
+
return result
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
async def get(
|
|
376
|
+
self,
|
|
377
|
+
id: str | None = None,
|
|
378
|
+
**kwargs
|
|
379
|
+
) -> ProjectResponse:
|
|
380
|
+
"""
|
|
381
|
+
Get a single project by ID via GraphQL
|
|
382
|
+
|
|
383
|
+
Args:
|
|
384
|
+
id: Project ID
|
|
385
|
+
**kwargs: Additional parameters
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
ProjectResponse
|
|
389
|
+
"""
|
|
390
|
+
params = {k: v for k, v in {
|
|
391
|
+
"id": id,
|
|
392
|
+
**kwargs
|
|
393
|
+
}.items() if v is not None}
|
|
394
|
+
|
|
395
|
+
result = await self._connector.execute("projects", "get", params)
|
|
396
|
+
return result
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
class TeamsQuery:
|
|
401
|
+
"""
|
|
402
|
+
Query class for Teams entity operations.
|
|
403
|
+
"""
|
|
404
|
+
|
|
405
|
+
def __init__(self, connector: LinearConnector):
|
|
406
|
+
"""Initialize query with connector reference."""
|
|
407
|
+
self._connector = connector
|
|
408
|
+
|
|
409
|
+
async def list(
|
|
410
|
+
self,
|
|
411
|
+
first: int | None = None,
|
|
412
|
+
after: str | None = None,
|
|
413
|
+
**kwargs
|
|
414
|
+
) -> TeamsListResponse:
|
|
415
|
+
"""
|
|
416
|
+
Returns a list of teams via GraphQL with pagination support
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
first: Number of items to return (max 250)
|
|
420
|
+
after: Cursor to start after (for pagination)
|
|
421
|
+
**kwargs: Additional parameters
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
TeamsListResponse
|
|
425
|
+
"""
|
|
426
|
+
params = {k: v for k, v in {
|
|
427
|
+
"first": first,
|
|
428
|
+
"after": after,
|
|
429
|
+
**kwargs
|
|
430
|
+
}.items() if v is not None}
|
|
431
|
+
|
|
432
|
+
result = await self._connector.execute("teams", "list", params)
|
|
433
|
+
return result
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
async def get(
|
|
438
|
+
self,
|
|
439
|
+
id: str | None = None,
|
|
440
|
+
**kwargs
|
|
441
|
+
) -> TeamResponse:
|
|
442
|
+
"""
|
|
443
|
+
Get a single team by ID via GraphQL
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
id: Team ID
|
|
447
|
+
**kwargs: Additional parameters
|
|
448
|
+
|
|
449
|
+
Returns:
|
|
450
|
+
TeamResponse
|
|
451
|
+
"""
|
|
452
|
+
params = {k: v for k, v in {
|
|
453
|
+
"id": id,
|
|
454
|
+
**kwargs
|
|
455
|
+
}.items() if v is not None}
|
|
456
|
+
|
|
457
|
+
result = await self._connector.execute("teams", "get", params)
|
|
458
|
+
return result
|
|
459
|
+
|
|
460
|
+
|