Coverage for src/bayernwerk_client/efix/cli.py: 87%

54 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-17 13:07 +0000

1"""`efix` subcommand: e-fix installer portal (bayernwerk.e-fix.info). 

2 

3 bayernwerk efix login 

4 bayernwerk efix installer 

5 bayernwerk -j efix antraege 

6 

7Run `bayernwerk efix login` once (reads MAP_EMAIL/MAP_PASSWORD from the 

8environment - e-fix uses the same credentials as the Mein.Auftragsportal, 

9or prompts interactively) to populate the local token cache. Later 

10commands reuse the cached token and transparently re-run the login when it 

11expires, provided MAP_EMAIL/MAP_PASSWORD are set in the environment; 

12otherwise they'll ask you to run `login` again. 

13 

14`-j`/`--json` is a top-level flag on `bayernwerk` itself (before `efix`), 

15not per-command - see `bayernwerk_client.cli`. 

16""" 

17 

18from __future__ import annotations 

19 

20import argparse 

21import getpass 

22import json 

23import os 

24from typing import Any 

25 

26from bayernwerk_client.efix.client import EFIX_TOKEN_PATH, EfixClient 

27from bayernwerk_client.exceptions import BayernwerkClientError 

28from bayernwerk_client.formatting import format_result 

29from bayernwerk_client.tokens import TokenSet, TokenStore 

30 

31 

32def _relogin_from_env(_old_tokens: TokenSet) -> TokenSet: 

33 from bayernwerk_client.efix.auth import login_interactive 

34 

35 email = os.environ.get("MAP_EMAIL") 

36 password = os.environ.get("MAP_PASSWORD") 

37 if not email or not password: 

38 raise BayernwerkClientError( 

39 "Access-Token abgelaufen und MAP_EMAIL/MAP_PASSWORD sind nicht gesetzt - " 

40 "bitte 'bayernwerk efix login' erneut ausfuehren." 

41 ) 

42 return login_interactive(email, password, headless=False) 

43 

44 

45def _make_client() -> EfixClient: 

46 return EfixClient.from_token_store(TokenStore(EFIX_TOKEN_PATH), on_token_expired=_relogin_from_env) 

47 

48 

49def _output(data: Any, *, as_json: bool) -> None: 

50 if as_json: 

51 print(json.dumps(data, ensure_ascii=False, indent=2)) 

52 else: 

53 print(format_result(data)) 

54 

55 

56def cmd_login(args: argparse.Namespace) -> None: 

57 from bayernwerk_client.efix.auth import login_interactive 

58 

59 email = os.environ.get("MAP_EMAIL") or input("E-Mail: ") 

60 password = os.environ.get("MAP_PASSWORD") or getpass.getpass("Passwort: ") 

61 tokens = login_interactive(email, password, headless=args.headless) 

62 TokenStore(EFIX_TOKEN_PATH).save(tokens) 

63 print("Login erfolgreich, Token gespeichert.") 

64 

65 

66def cmd_installer(args: argparse.Namespace) -> None: 

67 with _make_client() as client: 

68 _output(client.get_installer(), as_json=args.json) 

69 

70 

71def cmd_antraege(args: argparse.Namespace) -> None: 

72 with _make_client() as client: 

73 _output(client.list_installer_antraege(), as_json=args.json) 

74 

75 

76def cmd_status(args: argparse.Namespace) -> None: 

77 with _make_client() as client: 

78 _output(client.get_user_status(), as_json=args.json) 

79 

80 

81def cmd_events(args: argparse.Namespace) -> None: 

82 with _make_client() as client: 

83 _output(client.list_my_registered_events(), as_json=args.json) 

84 

85 

86def register(subparsers: argparse._SubParsersAction) -> None: 

87 """Add the `efix` subcommand (and its own sub-subcommands) to `subparsers`.""" 

88 efix_parser = subparsers.add_parser("efix", help="e-fix Installateur-Portal (bayernwerk.e-fix.info)") 

89 efix_sub = efix_parser.add_subparsers(dest="efix_command", required=True) 

90 

91 def add(name: str, *, help: str) -> argparse.ArgumentParser: 

92 return efix_sub.add_parser(name, help=help, description=help) 

93 

94 p = add("login", help="Einmalig einloggen und Token cachen") 

95 p.add_argument("--headless", action="store_true", help="Browser beim Login nicht anzeigen (Standard: sichtbar)") 

96 p.set_defaults(func=cmd_login) 

97 

98 add("installer", help="Eigene Installateur-Stammdaten anzeigen").set_defaults(func=cmd_installer) 

99 add("antraege", help="Eigene Anträge auflisten").set_defaults(func=cmd_antraege) 

100 add("status", help="Account-Status (Rolle, Benachrichtigungen, ...) anzeigen").set_defaults(func=cmd_status) 

101 add("events", help="Registrierte Veranstaltungen auflisten").set_defaults(func=cmd_events)