fal 1.11.4__py3-none-any.whl → 1.12.0__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.
Potentially problematic release.
This version of fal might be problematic. Click here for more details.
- fal/_fal_version.py +2 -2
- fal/auth/__init__.py +13 -11
- fal/cli/auth.py +82 -23
- fal/cli/teams.py +4 -39
- fal/sdk.py +1 -1
- {fal-1.11.4.dist-info → fal-1.12.0.dist-info}/METADATA +1 -1
- {fal-1.11.4.dist-info → fal-1.12.0.dist-info}/RECORD +10 -10
- {fal-1.11.4.dist-info → fal-1.12.0.dist-info}/WHEEL +0 -0
- {fal-1.11.4.dist-info → fal-1.12.0.dist-info}/entry_points.txt +0 -0
- {fal-1.11.4.dist-info → fal-1.12.0.dist-info}/top_level.txt +0 -0
fal/_fal_version.py
CHANGED
fal/auth/__init__.py
CHANGED
|
@@ -142,25 +142,23 @@ def _fetch_teams(bearer_token: str) -> list[dict]:
|
|
|
142
142
|
)
|
|
143
143
|
try:
|
|
144
144
|
with urlopen(request) as response:
|
|
145
|
-
|
|
145
|
+
return json.load(response)
|
|
146
146
|
except HTTPError as exc:
|
|
147
147
|
raise FalServerlessException("Failed to fetch teams") from exc
|
|
148
148
|
|
|
149
|
-
return [team for team in teams if not team["is_personal"]]
|
|
150
|
-
|
|
151
149
|
|
|
152
150
|
@dataclass
|
|
153
151
|
class UserAccess:
|
|
154
152
|
_access_token: str | None = field(repr=False, default=None)
|
|
155
153
|
_user_info: dict | None = field(repr=False, default=None)
|
|
156
154
|
_exc: Exception | None = field(repr=False, default=None)
|
|
157
|
-
|
|
155
|
+
_accounts: list[dict] | None = field(repr=False, default=None)
|
|
158
156
|
|
|
159
157
|
def invalidate(self) -> None:
|
|
160
158
|
self._access_token = None
|
|
161
159
|
self._user_info = None
|
|
162
160
|
self._exc = None
|
|
163
|
-
self.
|
|
161
|
+
self._accounts = None
|
|
164
162
|
|
|
165
163
|
@property
|
|
166
164
|
def info(self) -> dict:
|
|
@@ -191,13 +189,17 @@ class UserAccess:
|
|
|
191
189
|
return "Bearer " + self.access_token
|
|
192
190
|
|
|
193
191
|
@property
|
|
194
|
-
def
|
|
195
|
-
if self.
|
|
196
|
-
self.
|
|
197
|
-
|
|
192
|
+
def accounts(self) -> list[dict]:
|
|
193
|
+
if self._accounts is None:
|
|
194
|
+
self._accounts = _fetch_teams(self.bearer_token)
|
|
195
|
+
self._accounts = sorted(
|
|
196
|
+
self._accounts, key=lambda x: (not x["is_personal"], x["nickname"])
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
return self._accounts
|
|
198
200
|
|
|
199
|
-
def
|
|
200
|
-
for t in self.
|
|
201
|
+
def get_account(self, team: str) -> dict:
|
|
202
|
+
for t in self.accounts:
|
|
201
203
|
if t["nickname"].lower() == team.lower():
|
|
202
204
|
return t
|
|
203
205
|
raise ValueError(f"Team {team} not found")
|
fal/cli/auth.py
CHANGED
|
@@ -2,30 +2,14 @@ from fal.auth import USER, login, logout
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def _login(args):
|
|
5
|
-
from rich.prompt import Prompt
|
|
6
|
-
|
|
7
5
|
from fal.config import Config
|
|
8
6
|
|
|
9
7
|
login()
|
|
10
|
-
|
|
11
|
-
if not teams:
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
team = Prompt.ask(
|
|
15
|
-
"\nPlease choose a team account to use or leave blank to "
|
|
16
|
-
"use your personal account:",
|
|
17
|
-
choices=teams,
|
|
18
|
-
default=None,
|
|
19
|
-
)
|
|
8
|
+
|
|
20
9
|
with Config().edit() as config:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"You can change this later with [bold]fal team set[/]."
|
|
25
|
-
)
|
|
26
|
-
config.set("team", team)
|
|
27
|
-
else:
|
|
28
|
-
config.unset("team")
|
|
10
|
+
config.unset("team")
|
|
11
|
+
|
|
12
|
+
_set_account(args)
|
|
29
13
|
|
|
30
14
|
|
|
31
15
|
def _logout(args):
|
|
@@ -36,10 +20,85 @@ def _logout(args):
|
|
|
36
20
|
config.unset("team")
|
|
37
21
|
|
|
38
22
|
|
|
23
|
+
def _list_accounts(args):
|
|
24
|
+
from rich.style import Style
|
|
25
|
+
from rich.table import Table
|
|
26
|
+
|
|
27
|
+
from fal.config import Config
|
|
28
|
+
|
|
29
|
+
config = Config()
|
|
30
|
+
current_account = config.get("team") or USER.info["nickname"]
|
|
31
|
+
|
|
32
|
+
table = Table(border_style=Style(frame=False), show_header=False)
|
|
33
|
+
table.add_column("#")
|
|
34
|
+
table.add_column("Nickname")
|
|
35
|
+
table.add_column("Type")
|
|
36
|
+
|
|
37
|
+
for idx, account in enumerate(USER.accounts):
|
|
38
|
+
selected = account["nickname"] == current_account
|
|
39
|
+
color = "bold yellow" if selected else None
|
|
40
|
+
|
|
41
|
+
table.add_row(
|
|
42
|
+
f"* {idx + 1}" if selected else f" {idx + 1}",
|
|
43
|
+
account["nickname"],
|
|
44
|
+
"Personal" if account["is_personal"] else "Team",
|
|
45
|
+
style=color,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
args.console.print(table)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _set_account(args):
|
|
52
|
+
from rich.prompt import Prompt
|
|
53
|
+
|
|
54
|
+
from fal.config import Config
|
|
55
|
+
|
|
56
|
+
if hasattr(args, "account") and args.account:
|
|
57
|
+
if args.account.isdigit():
|
|
58
|
+
acc_index = int(args.account) - 1
|
|
59
|
+
account = USER.accounts[acc_index]
|
|
60
|
+
else:
|
|
61
|
+
account = USER.get_account(args.account)
|
|
62
|
+
else:
|
|
63
|
+
_list_accounts(args)
|
|
64
|
+
indices = list(map(str, range(1, len(USER.accounts) + 1)))
|
|
65
|
+
team_names = [account["nickname"] for account in USER.accounts]
|
|
66
|
+
acc_choice = Prompt.ask(
|
|
67
|
+
"Select an account by number",
|
|
68
|
+
choices=indices + team_names,
|
|
69
|
+
show_choices=False,
|
|
70
|
+
)
|
|
71
|
+
if acc_choice in indices:
|
|
72
|
+
acc_index = int(acc_choice) - 1
|
|
73
|
+
account = USER.accounts[acc_index]
|
|
74
|
+
else:
|
|
75
|
+
account = USER.get_account(acc_choice)
|
|
76
|
+
|
|
77
|
+
if account["is_personal"]:
|
|
78
|
+
args.console.print(f"Using personal account {account['nickname']}")
|
|
79
|
+
else:
|
|
80
|
+
args.console.print(f"Using team account {account['nickname']}")
|
|
81
|
+
|
|
82
|
+
with Config().edit() as config:
|
|
83
|
+
config.set("team", account["nickname"])
|
|
84
|
+
|
|
85
|
+
|
|
39
86
|
def _whoami(args):
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
87
|
+
from fal.config import Config
|
|
88
|
+
|
|
89
|
+
config = Config()
|
|
90
|
+
|
|
91
|
+
team = config.get("team")
|
|
92
|
+
if team:
|
|
93
|
+
account = USER.get_account(team)
|
|
94
|
+
else:
|
|
95
|
+
account = USER.get_account(USER.info["nickname"])
|
|
96
|
+
|
|
97
|
+
nickname = account["nickname"]
|
|
98
|
+
full_name = account["full_name"]
|
|
99
|
+
user_id = account["user_id"]
|
|
100
|
+
|
|
101
|
+
args.console.print(f"Hello, {full_name}: {nickname!r} - {user_id!r}")
|
|
43
102
|
|
|
44
103
|
|
|
45
104
|
def add_parser(main_subparsers, parents):
|
fal/cli/teams.py
CHANGED
|
@@ -1,39 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
from rich.table import Table
|
|
3
|
-
|
|
4
|
-
from fal.auth import USER
|
|
5
|
-
from fal.config import Config
|
|
6
|
-
|
|
7
|
-
table = Table()
|
|
8
|
-
table.add_column("Default")
|
|
9
|
-
table.add_column("Team")
|
|
10
|
-
table.add_column("Full Name")
|
|
11
|
-
table.add_column("ID")
|
|
12
|
-
|
|
13
|
-
default_team = Config().get("team")
|
|
14
|
-
|
|
15
|
-
for team in USER.teams:
|
|
16
|
-
default = default_team and default_team.lower() == team["nickname"].lower()
|
|
17
|
-
table.add_row(
|
|
18
|
-
"*" if default else "", team["nickname"], team["full_name"], team["user_id"]
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
args.console.print(table)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def _set(args):
|
|
25
|
-
from fal.config import Config
|
|
26
|
-
from fal.sdk import USER
|
|
27
|
-
|
|
28
|
-
team = args.team.lower()
|
|
29
|
-
for team_info in USER.teams:
|
|
30
|
-
if team_info["nickname"].lower() == team:
|
|
31
|
-
break
|
|
32
|
-
else:
|
|
33
|
-
raise ValueError(f"Team {args.team} not found")
|
|
34
|
-
|
|
35
|
-
with Config().edit() as config:
|
|
36
|
-
config.set("team", team)
|
|
1
|
+
from fal.cli.auth import _list_accounts, _set_account
|
|
37
2
|
|
|
38
3
|
|
|
39
4
|
def _unset(args):
|
|
@@ -67,7 +32,7 @@ def add_parser(main_subparsers, parents):
|
|
|
67
32
|
help=list_help,
|
|
68
33
|
parents=parents,
|
|
69
34
|
)
|
|
70
|
-
list_parser.set_defaults(func=
|
|
35
|
+
list_parser.set_defaults(func=_list_accounts)
|
|
71
36
|
|
|
72
37
|
set_help = "Set the current team."
|
|
73
38
|
set_parser = subparsers.add_parser(
|
|
@@ -76,8 +41,8 @@ def add_parser(main_subparsers, parents):
|
|
|
76
41
|
help=set_help,
|
|
77
42
|
parents=parents,
|
|
78
43
|
)
|
|
79
|
-
set_parser.add_argument("
|
|
80
|
-
set_parser.set_defaults(func=
|
|
44
|
+
set_parser.add_argument("account", help="The team to set.")
|
|
45
|
+
set_parser.set_defaults(func=_set_account)
|
|
81
46
|
|
|
82
47
|
unset_help = "Unset the current team."
|
|
83
48
|
unset_parser = subparsers.add_parser(
|
fal/sdk.py
CHANGED
|
@@ -183,7 +183,7 @@ def get_default_credentials(team: str | None = None) -> Credentials:
|
|
|
183
183
|
else:
|
|
184
184
|
config = Config()
|
|
185
185
|
team = team or config.get("team")
|
|
186
|
-
team_id = USER.
|
|
186
|
+
team_id = USER.get_account(team)["user_id"] if team else None
|
|
187
187
|
return AuthenticatedCredentials(team_id=team_id)
|
|
188
188
|
|
|
189
189
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
fal/__init__.py,sha256=wXs1G0gSc7ZK60-bHe-B2m0l_sA6TrFk4BxY0tMoLe8,784
|
|
2
2
|
fal/__main__.py,sha256=4JMK66Wj4uLZTKbF-sT3LAxOsr6buig77PmOkJCRRxw,83
|
|
3
|
-
fal/_fal_version.py,sha256=
|
|
3
|
+
fal/_fal_version.py,sha256=X7AXkrxMLYa0fUCdwZA2oOfiFkQJiuenTXzRghkc4eU,513
|
|
4
4
|
fal/_serialization.py,sha256=rD2YiSa8iuzCaZohZwN_MPEB-PpSKbWRDeaIDpTEjyY,7653
|
|
5
5
|
fal/_version.py,sha256=EBGqrknaf1WygENX-H4fBefLvHryvJBBGtVJetaB0NY,266
|
|
6
6
|
fal/api.py,sha256=aoA0-7JsO6dWhudzmDOidbPwxnJmIJaQWhGV1kqLCbw,44814
|
|
@@ -12,18 +12,18 @@ fal/files.py,sha256=QgfYfMKmNobMPufrAP_ga1FKcIAlSbw18Iar1-0qepo,2650
|
|
|
12
12
|
fal/flags.py,sha256=oWN_eidSUOcE9wdPK_77si3A1fpgOC0UEERPsvNLIMc,842
|
|
13
13
|
fal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
fal/rest_client.py,sha256=kGBGmuyHfX1lR910EoKCYPjsyU8MdXawT_cW2q8Sajc,568
|
|
15
|
-
fal/sdk.py,sha256=
|
|
15
|
+
fal/sdk.py,sha256=lS-nVp35qwlovQWhmkhWhBmTMCG-ntMekdrIIgzK-2A,25423
|
|
16
16
|
fal/sync.py,sha256=ZuIJA2-hTPNANG9B_NNJZUsO68EIdTH0dc9MzeVE2VU,4340
|
|
17
17
|
fal/utils.py,sha256=9q_QrQBlQN3nZYA1kEGRfhJWi4RjnO4H1uQswfaei9w,2146
|
|
18
18
|
fal/workflows.py,sha256=Zl4f6Bs085hY40zmqScxDUyCu7zXkukDbW02iYOLTTI,14805
|
|
19
|
-
fal/auth/__init__.py,sha256=
|
|
19
|
+
fal/auth/__init__.py,sha256=WSDXxkrshGyOvfN6WomHGKrflbmJvPiDUSQRsp4mqsI,5932
|
|
20
20
|
fal/auth/auth0.py,sha256=_OhfrqF41odNebFTr8SvUm-d9REVG6wfQBHhPIQxsZU,5468
|
|
21
21
|
fal/auth/local.py,sha256=sndkM6vKpeVny6NHTacVlTbiIFqaksOmw0Viqs_RN1U,1790
|
|
22
22
|
fal/cli/__init__.py,sha256=padK4o0BFqq61kxAA1qQ0jYr2SuhA2mf90B3AaRkmJA,37
|
|
23
23
|
fal/cli/_utils.py,sha256=pHmKzpUWc2n4yPv4R0Y6DuZC5j-rVKU8oqdQDVW_-Lo,1591
|
|
24
24
|
fal/cli/api.py,sha256=-rl50A00CxqVZtDh0iZmpCHMFY0jZySaumbPCe3MSoQ,2090
|
|
25
25
|
fal/cli/apps.py,sha256=vKeTUw_uUxz5M9hlP0jcJ23qjR0GTz7ifeS4HBjKECo,10101
|
|
26
|
-
fal/cli/auth.py,sha256=
|
|
26
|
+
fal/cli/auth.py,sha256=iHXxreitWubR7meV7DEbSP8djvdb6QxMw6nHZFv9udw,3779
|
|
27
27
|
fal/cli/cli_nested_json.py,sha256=veSZU8_bYV3Iu1PAoxt-4BMBraNIqgH5nughbs2UKvE,13539
|
|
28
28
|
fal/cli/create.py,sha256=a8WDq-nJLFTeoIXqpb5cr7GR7YR9ZZrQCawNm34KXXE,627
|
|
29
29
|
fal/cli/debug.py,sha256=u_urnyFzSlNnrq93zz_GXE9FX4VyVxDoamJJyrZpFI0,1312
|
|
@@ -36,7 +36,7 @@ fal/cli/profile.py,sha256=vWngqkX7UizQIUQOpXauFz1UGJwDeh38Si6wXcIj3Eo,3396
|
|
|
36
36
|
fal/cli/run.py,sha256=nAC12Qss4Fg1XmV0qOS9RdGNLYcdoHeRgQMvbTN4P9I,1202
|
|
37
37
|
fal/cli/runners.py,sha256=z7WkZZC9rCW2mU5enowVQsxd1W18iBtLNOnPjrzhEf0,3491
|
|
38
38
|
fal/cli/secrets.py,sha256=QKSmazu-wiNF6fOpGL9v2TDYxAjX9KTi7ot7vnv6f5E,2474
|
|
39
|
-
fal/cli/teams.py,sha256=
|
|
39
|
+
fal/cli/teams.py,sha256=lIY4uT8TGjk9g0z2tY4cGDU8PGqowncEMKh9K_dJYUY,1314
|
|
40
40
|
fal/console/__init__.py,sha256=ernZ4bzvvliQh5SmrEqQ7lA5eVcbw6Ra2jalKtA7dxg,132
|
|
41
41
|
fal/console/icons.py,sha256=De9MfFaSkO2Lqfne13n3PrYfTXJVIzYZVqYn5BWsdrA,108
|
|
42
42
|
fal/console/ux.py,sha256=KMQs3UHQvVHDxDQQqlot-WskVKoMQXOE3jiVkkfmIMY,356
|
|
@@ -134,8 +134,8 @@ openapi_fal_rest/models/workflow_node_type.py,sha256=-FzyeY2bxcNmizKbJI8joG7byRi
|
|
|
134
134
|
openapi_fal_rest/models/workflow_schema.py,sha256=4K5gsv9u9pxx2ItkffoyHeNjBBYf6ur5bN4m_zePZNY,2019
|
|
135
135
|
openapi_fal_rest/models/workflow_schema_input.py,sha256=2OkOXWHTNsCXHWS6EGDFzcJKkW5FIap-2gfO233EvZQ,1191
|
|
136
136
|
openapi_fal_rest/models/workflow_schema_output.py,sha256=EblwSPAGfWfYVWw_WSSaBzQVju296is9o28rMBAd0mc,1196
|
|
137
|
-
fal-1.
|
|
138
|
-
fal-1.
|
|
139
|
-
fal-1.
|
|
140
|
-
fal-1.
|
|
141
|
-
fal-1.
|
|
137
|
+
fal-1.12.0.dist-info/METADATA,sha256=aOSYnbFBCtE2_UnXsu0QrBd5s8sHWJUoOh6FwxqhSTM,4062
|
|
138
|
+
fal-1.12.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
139
|
+
fal-1.12.0.dist-info/entry_points.txt,sha256=32zwTUC1U1E7nSTIGCoANQOQ3I7-qHG5wI6gsVz5pNU,37
|
|
140
|
+
fal-1.12.0.dist-info/top_level.txt,sha256=r257X1L57oJL8_lM0tRrfGuXFwm66i1huwQygbpLmHw,21
|
|
141
|
+
fal-1.12.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|