Skip to content

Commit a05ae6c

Browse files
committed
Re-order cli methods
1 parent 7794c24 commit a05ae6c

1 file changed

Lines changed: 69 additions & 70 deletions

File tree

src/blueapi/cli/cli.py

Lines changed: 69 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@
4242
from .scratch import setup_scratch
4343
from .updates import CliEventRenderer
4444

45+
P = ParamSpec("P")
46+
T = TypeVar("T")
47+
48+
49+
def check_connection(func: Callable[P, T]) -> Callable[P, T]:
50+
@wraps(func)
51+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
52+
try:
53+
return func(*args, **kwargs)
54+
except ConnectionError as ce:
55+
raise ClickException(
56+
"Failed to establish connection to blueapi server."
57+
) from ce
58+
except BlueskyRemoteControlError as e:
59+
if str(e) == "<Response [401]>":
60+
raise ClickException(
61+
"Access denied. Please check your login status and try again."
62+
) from e
63+
else:
64+
raise e
65+
66+
return wrapper
67+
4568

4669
def _load_config(ctx: click.Context, config: Path | None | tuple[Path, ...]) -> None:
4770
config_loader = ConfigLoader(ApplicationConfig)
@@ -156,6 +179,52 @@ def start_application(ctx: click.Context, config: Path | None | tuple[Path, ...]
156179
start(loaded_config)
157180

158181

182+
@main.command(name="login")
183+
@click.pass_obj
184+
@check_connection
185+
def login(obj: dict) -> None:
186+
"""
187+
Authenticate with the blueapi using the OIDC (OpenID Connect) flow.
188+
"""
189+
config: ApplicationConfig = obj["config"]
190+
try:
191+
auth: SessionManager = SessionManager.from_cache(config.auth_token_path)
192+
access_token = auth.get_valid_access_token()
193+
assert access_token
194+
print("Logged in")
195+
except Exception:
196+
client = BlueapiClient.from_config(config)
197+
oidc_config = client.get_oidc_config()
198+
if oidc_config is None:
199+
print("Server is not configured to use authentication!")
200+
return
201+
auth = SessionManager(
202+
oidc_config, cache_manager=SessionCacheManager(config.auth_token_path)
203+
)
204+
auth.start_device_flow()
205+
206+
207+
@main.command(name="logout")
208+
@click.pass_obj
209+
def logout(obj: dict) -> None:
210+
"""
211+
Logs out from the OIDC provider and removes the cached access token.
212+
"""
213+
config: ApplicationConfig = obj["config"]
214+
try:
215+
auth: SessionManager = SessionManager.from_cache(config.auth_token_path)
216+
auth.logout()
217+
except FileNotFoundError:
218+
print("Logged out")
219+
except ValueError as e:
220+
logging.debug("Invalid login token: %s", e)
221+
raise ClickException(
222+
"Login token is not valid - remove before trying again"
223+
) from e
224+
except Exception as e:
225+
raise ClickException(f"Error logging out: {e}") from e
226+
227+
159228
@main.group()
160229
@click.option(
161230
"-o",
@@ -197,30 +266,6 @@ def controller(
197266
ctx.obj["client"] = BlueapiClient.from_config(config)
198267

199268

200-
P = ParamSpec("P")
201-
T = TypeVar("T")
202-
203-
204-
def check_connection(func: Callable[P, T]) -> Callable[P, T]:
205-
@wraps(func)
206-
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
207-
try:
208-
return func(*args, **kwargs)
209-
except ConnectionError as ce:
210-
raise ClickException(
211-
"Failed to establish connection to blueapi server."
212-
) from ce
213-
except BlueskyRemoteControlError as e:
214-
if str(e) == "<Response [401]>":
215-
raise ClickException(
216-
"Access denied. Please check your login status and try again."
217-
) from e
218-
else:
219-
raise e
220-
221-
return wrapper
222-
223-
224269
@controller.command(name="plans")
225270
@click.pass_obj
226271
@check_connection
@@ -476,49 +521,3 @@ def get_python_env(obj: dict, name: str, source: SourceInfo) -> None:
476521
"""
477522
client: BlueapiClient = obj["client"]
478523
obj["fmt"].display(client.get_python_env(name=name, source=source))
479-
480-
481-
@main.command(name="login")
482-
@click.pass_obj
483-
@check_connection
484-
def login(obj: dict) -> None:
485-
"""
486-
Authenticate with the blueapi using the OIDC (OpenID Connect) flow.
487-
"""
488-
config: ApplicationConfig = obj["config"]
489-
try:
490-
auth: SessionManager = SessionManager.from_cache(config.auth_token_path)
491-
access_token = auth.get_valid_access_token()
492-
assert access_token
493-
print("Logged in")
494-
except Exception:
495-
client = BlueapiClient.from_config(config)
496-
oidc_config = client.get_oidc_config()
497-
if oidc_config is None:
498-
print("Server is not configured to use authentication!")
499-
return
500-
auth = SessionManager(
501-
oidc_config, cache_manager=SessionCacheManager(config.auth_token_path)
502-
)
503-
auth.start_device_flow()
504-
505-
506-
@main.command(name="logout")
507-
@click.pass_obj
508-
def logout(obj: dict) -> None:
509-
"""
510-
Logs out from the OIDC provider and removes the cached access token.
511-
"""
512-
config: ApplicationConfig = obj["config"]
513-
try:
514-
auth: SessionManager = SessionManager.from_cache(config.auth_token_path)
515-
auth.logout()
516-
except FileNotFoundError:
517-
print("Logged out")
518-
except ValueError as e:
519-
logging.debug("Invalid login token: %s", e)
520-
raise ClickException(
521-
"Login token is not valid - remove before trying again"
522-
) from e
523-
except Exception as e:
524-
raise ClickException(f"Error logging out: {e}") from e

0 commit comments

Comments
 (0)