audex 1.0.7a3__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.
Files changed (192) hide show
  1. audex/__init__.py +9 -0
  2. audex/__main__.py +7 -0
  3. audex/cli/__init__.py +189 -0
  4. audex/cli/apis/__init__.py +12 -0
  5. audex/cli/apis/init/__init__.py +34 -0
  6. audex/cli/apis/init/gencfg.py +130 -0
  7. audex/cli/apis/init/setup.py +330 -0
  8. audex/cli/apis/init/vprgroup.py +125 -0
  9. audex/cli/apis/serve.py +141 -0
  10. audex/cli/args.py +356 -0
  11. audex/cli/exceptions.py +44 -0
  12. audex/cli/helper/__init__.py +0 -0
  13. audex/cli/helper/ansi.py +193 -0
  14. audex/cli/helper/display.py +288 -0
  15. audex/config/__init__.py +64 -0
  16. audex/config/core/__init__.py +30 -0
  17. audex/config/core/app.py +29 -0
  18. audex/config/core/audio.py +45 -0
  19. audex/config/core/logging.py +163 -0
  20. audex/config/core/session.py +11 -0
  21. audex/config/helper/__init__.py +1 -0
  22. audex/config/helper/client/__init__.py +1 -0
  23. audex/config/helper/client/http.py +28 -0
  24. audex/config/helper/client/websocket.py +21 -0
  25. audex/config/helper/provider/__init__.py +1 -0
  26. audex/config/helper/provider/dashscope.py +13 -0
  27. audex/config/helper/provider/unisound.py +18 -0
  28. audex/config/helper/provider/xfyun.py +23 -0
  29. audex/config/infrastructure/__init__.py +31 -0
  30. audex/config/infrastructure/cache.py +51 -0
  31. audex/config/infrastructure/database.py +48 -0
  32. audex/config/infrastructure/recorder.py +32 -0
  33. audex/config/infrastructure/store.py +19 -0
  34. audex/config/provider/__init__.py +18 -0
  35. audex/config/provider/transcription.py +109 -0
  36. audex/config/provider/vpr.py +99 -0
  37. audex/container.py +40 -0
  38. audex/entity/__init__.py +468 -0
  39. audex/entity/doctor.py +109 -0
  40. audex/entity/doctor.pyi +51 -0
  41. audex/entity/fields.py +401 -0
  42. audex/entity/segment.py +115 -0
  43. audex/entity/segment.pyi +38 -0
  44. audex/entity/session.py +133 -0
  45. audex/entity/session.pyi +47 -0
  46. audex/entity/utterance.py +142 -0
  47. audex/entity/utterance.pyi +48 -0
  48. audex/entity/vp.py +68 -0
  49. audex/entity/vp.pyi +35 -0
  50. audex/exceptions.py +157 -0
  51. audex/filters/__init__.py +692 -0
  52. audex/filters/generated/__init__.py +21 -0
  53. audex/filters/generated/doctor.py +987 -0
  54. audex/filters/generated/segment.py +723 -0
  55. audex/filters/generated/session.py +978 -0
  56. audex/filters/generated/utterance.py +939 -0
  57. audex/filters/generated/vp.py +815 -0
  58. audex/helper/__init__.py +1 -0
  59. audex/helper/hash.py +33 -0
  60. audex/helper/mixin.py +65 -0
  61. audex/helper/net.py +19 -0
  62. audex/helper/settings/__init__.py +830 -0
  63. audex/helper/settings/fields.py +317 -0
  64. audex/helper/stream.py +153 -0
  65. audex/injectors/__init__.py +1 -0
  66. audex/injectors/config.py +12 -0
  67. audex/injectors/lifespan.py +7 -0
  68. audex/lib/__init__.py +1 -0
  69. audex/lib/cache/__init__.py +383 -0
  70. audex/lib/cache/inmemory.py +513 -0
  71. audex/lib/database/__init__.py +83 -0
  72. audex/lib/database/sqlite.py +406 -0
  73. audex/lib/exporter.py +189 -0
  74. audex/lib/injectors/__init__.py +1 -0
  75. audex/lib/injectors/cache.py +25 -0
  76. audex/lib/injectors/container.py +47 -0
  77. audex/lib/injectors/exporter.py +26 -0
  78. audex/lib/injectors/recorder.py +33 -0
  79. audex/lib/injectors/server.py +17 -0
  80. audex/lib/injectors/session.py +18 -0
  81. audex/lib/injectors/sqlite.py +24 -0
  82. audex/lib/injectors/store.py +13 -0
  83. audex/lib/injectors/transcription.py +42 -0
  84. audex/lib/injectors/usb.py +12 -0
  85. audex/lib/injectors/vpr.py +65 -0
  86. audex/lib/injectors/wifi.py +7 -0
  87. audex/lib/recorder.py +844 -0
  88. audex/lib/repos/__init__.py +149 -0
  89. audex/lib/repos/container.py +23 -0
  90. audex/lib/repos/database/__init__.py +1 -0
  91. audex/lib/repos/database/sqlite.py +672 -0
  92. audex/lib/repos/decorators.py +74 -0
  93. audex/lib/repos/doctor.py +286 -0
  94. audex/lib/repos/segment.py +302 -0
  95. audex/lib/repos/session.py +285 -0
  96. audex/lib/repos/tables/__init__.py +70 -0
  97. audex/lib/repos/tables/doctor.py +137 -0
  98. audex/lib/repos/tables/segment.py +113 -0
  99. audex/lib/repos/tables/session.py +140 -0
  100. audex/lib/repos/tables/utterance.py +131 -0
  101. audex/lib/repos/tables/vp.py +102 -0
  102. audex/lib/repos/utterance.py +288 -0
  103. audex/lib/repos/vp.py +286 -0
  104. audex/lib/restful.py +251 -0
  105. audex/lib/server/__init__.py +97 -0
  106. audex/lib/server/auth.py +98 -0
  107. audex/lib/server/handlers.py +248 -0
  108. audex/lib/server/templates/index.html.j2 +226 -0
  109. audex/lib/server/templates/login.html.j2 +111 -0
  110. audex/lib/server/templates/static/script.js +68 -0
  111. audex/lib/server/templates/static/style.css +579 -0
  112. audex/lib/server/types.py +123 -0
  113. audex/lib/session.py +503 -0
  114. audex/lib/store/__init__.py +238 -0
  115. audex/lib/store/localfile.py +411 -0
  116. audex/lib/transcription/__init__.py +33 -0
  117. audex/lib/transcription/dashscope.py +525 -0
  118. audex/lib/transcription/events.py +62 -0
  119. audex/lib/usb.py +554 -0
  120. audex/lib/vpr/__init__.py +38 -0
  121. audex/lib/vpr/unisound/__init__.py +185 -0
  122. audex/lib/vpr/unisound/types.py +469 -0
  123. audex/lib/vpr/xfyun/__init__.py +483 -0
  124. audex/lib/vpr/xfyun/types.py +679 -0
  125. audex/lib/websocket/__init__.py +8 -0
  126. audex/lib/websocket/connection.py +485 -0
  127. audex/lib/websocket/pool.py +991 -0
  128. audex/lib/wifi.py +1146 -0
  129. audex/lifespan.py +75 -0
  130. audex/service/__init__.py +27 -0
  131. audex/service/decorators.py +73 -0
  132. audex/service/doctor/__init__.py +652 -0
  133. audex/service/doctor/const.py +36 -0
  134. audex/service/doctor/exceptions.py +96 -0
  135. audex/service/doctor/types.py +54 -0
  136. audex/service/export/__init__.py +236 -0
  137. audex/service/export/const.py +17 -0
  138. audex/service/export/exceptions.py +34 -0
  139. audex/service/export/types.py +21 -0
  140. audex/service/injectors/__init__.py +1 -0
  141. audex/service/injectors/container.py +53 -0
  142. audex/service/injectors/doctor.py +34 -0
  143. audex/service/injectors/export.py +27 -0
  144. audex/service/injectors/session.py +49 -0
  145. audex/service/session/__init__.py +754 -0
  146. audex/service/session/const.py +34 -0
  147. audex/service/session/exceptions.py +67 -0
  148. audex/service/session/types.py +91 -0
  149. audex/types.py +39 -0
  150. audex/utils.py +287 -0
  151. audex/valueobj/__init__.py +81 -0
  152. audex/valueobj/common/__init__.py +1 -0
  153. audex/valueobj/common/auth.py +84 -0
  154. audex/valueobj/common/email.py +16 -0
  155. audex/valueobj/common/ops.py +22 -0
  156. audex/valueobj/common/phone.py +84 -0
  157. audex/valueobj/common/version.py +72 -0
  158. audex/valueobj/session.py +19 -0
  159. audex/valueobj/utterance.py +15 -0
  160. audex/view/__init__.py +51 -0
  161. audex/view/container.py +17 -0
  162. audex/view/decorators.py +303 -0
  163. audex/view/pages/__init__.py +1 -0
  164. audex/view/pages/dashboard/__init__.py +286 -0
  165. audex/view/pages/dashboard/wifi.py +407 -0
  166. audex/view/pages/login.py +110 -0
  167. audex/view/pages/recording.py +348 -0
  168. audex/view/pages/register.py +202 -0
  169. audex/view/pages/sessions/__init__.py +196 -0
  170. audex/view/pages/sessions/details.py +224 -0
  171. audex/view/pages/sessions/export.py +443 -0
  172. audex/view/pages/settings.py +374 -0
  173. audex/view/pages/voiceprint/__init__.py +1 -0
  174. audex/view/pages/voiceprint/enroll.py +195 -0
  175. audex/view/pages/voiceprint/update.py +195 -0
  176. audex/view/static/css/dashboard.css +452 -0
  177. audex/view/static/css/glass.css +22 -0
  178. audex/view/static/css/global.css +541 -0
  179. audex/view/static/css/login.css +386 -0
  180. audex/view/static/css/recording.css +439 -0
  181. audex/view/static/css/register.css +293 -0
  182. audex/view/static/css/sessions/styles.css +501 -0
  183. audex/view/static/css/settings.css +186 -0
  184. audex/view/static/css/voiceprint/enroll.css +43 -0
  185. audex/view/static/css/voiceprint/styles.css +209 -0
  186. audex/view/static/css/voiceprint/update.css +44 -0
  187. audex/view/static/images/logo.svg +95 -0
  188. audex/view/static/js/recording.js +42 -0
  189. audex-1.0.7a3.dist-info/METADATA +361 -0
  190. audex-1.0.7a3.dist-info/RECORD +192 -0
  191. audex-1.0.7a3.dist-info/WHEEL +4 -0
  192. audex-1.0.7a3.dist-info/entry_points.txt +3 -0
audex/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ __title__ = "Audex"
4
+ __prog__ = "audex"
5
+ __version__ = "1.0.7-a3"
6
+ __description__ = """
7
+ Audex is an intelligent medical transcription system designed specifically for clinical scenarios.
8
+ It uses Voice Print Recognition (VPR) and real-time speech-to-text technology to automatically distinguish between the doctor and the patient, producing structured medical documentation from their conversations.
9
+ """
audex/__main__.py ADDED
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+
5
+ from audex.cli import main
6
+
7
+ sys.exit(main())
audex/cli/__init__.py ADDED
@@ -0,0 +1,189 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import pathlib
5
+ import sys
6
+
7
+ import dotenv
8
+
9
+ from audex.cli.apis import register_apis
10
+ from audex.cli.args import parser_with_version
11
+ from audex.cli.exceptions import CLIError
12
+ from audex.cli.helper import display
13
+ from audex.config import Config
14
+ from audex.config import build_config
15
+ from audex.config import setconfig
16
+ from audex.exceptions import AudexError
17
+ from audex.utils import flatten_dict
18
+
19
+
20
+ def main() -> int:
21
+ """Main entry point for the Audex CLI.
22
+
23
+ This function parses command-line arguments, executes the appropriate
24
+ command, and handles errors gracefully.
25
+
26
+ Returns:
27
+ Exit code indicating success or type of failure.
28
+ """
29
+
30
+ # Load environment variables from .env file if it exists
31
+ if dotenv.find_dotenv():
32
+ dotenv.load_dotenv()
33
+
34
+ try:
35
+ args = parse_args()
36
+ args.func(args)
37
+ return 0
38
+ except KeyboardInterrupt:
39
+ # Handle Ctrl+C gracefully
40
+ print()
41
+ display.warning("Cancelled by user")
42
+ return 130
43
+ except CLIError as e:
44
+ # Handle known CLI errors
45
+ verbose = "--verbose" in sys.argv or "-v" in sys.argv
46
+ display.show_error(e, verbose=verbose)
47
+ return e.exit_code
48
+ except AudexError as e:
49
+ # Handle known Audex errors
50
+ verbose = "--verbose" in sys.argv or "-v" in sys.argv
51
+ display.show_error(e, verbose=verbose)
52
+ return e.code
53
+ except Exception as e:
54
+ # Handle unexpected errors
55
+ verbose = "--verbose" in sys.argv or "-v" in sys.argv
56
+ display.show_error(e, verbose=verbose)
57
+ return 1
58
+
59
+
60
+ def parse_args() -> argparse.Namespace:
61
+ parser = parser_with_version()
62
+
63
+ parser.add_argument(
64
+ "--verbose",
65
+ "-v",
66
+ action="store_true",
67
+ help="Enable verbose output for debugging",
68
+ )
69
+
70
+ # Add config argument at top level
71
+ parser.add_argument(
72
+ "--config",
73
+ "-c",
74
+ type=pathlib.Path,
75
+ default=None,
76
+ help="Path to the configuration file",
77
+ )
78
+
79
+ # Create subparsers for other commands (serve, init, etc.)
80
+ subparsers = parser.add_subparsers(
81
+ title="Available Commands",
82
+ dest="command",
83
+ help="Command to execute (optional, default is to run the application)",
84
+ metavar="<command>",
85
+ required=False,
86
+ )
87
+
88
+ # Register other commands (not run, since it's default)
89
+ register_apis(subparsers)
90
+
91
+ # Set default function to run the application
92
+ parser.set_defaults(func=run_application)
93
+
94
+ return parser.parse_args()
95
+
96
+
97
+ def run_application(args: argparse.Namespace) -> None:
98
+ """Run the main Audex application (default behavior)."""
99
+ from nicegui import core
100
+
101
+ core.app.native.start_args.update({"gui": "qt"})
102
+
103
+ display.banner("Audex", subtitle="Smart Medical Recording & Transcription System")
104
+
105
+ # Bootstrap
106
+ display.step("Bootstrapping application", step=0)
107
+ print()
108
+
109
+ # Load configuration
110
+ with display.section("Loading Configuration"):
111
+ if args.config:
112
+ display.info(f"Loading config from: {args.config}")
113
+ display.path(args.config, exists=args.config.exists())
114
+
115
+ if args.config.suffix in {".yaml", ".yml"}:
116
+ setconfig(Config.from_yaml(args.config))
117
+ display.success("YAML configuration loaded")
118
+ else:
119
+ from audex.cli.exceptions import InvalidArgumentError
120
+
121
+ raise InvalidArgumentError(
122
+ arg="config",
123
+ value=args.config,
124
+ reason=f"Unsupported config file format: {args.config.suffix}."
125
+ "Supported formats are .yaml, .yml, .json, .jsonc, .json5",
126
+ )
127
+ else:
128
+ display.info("Using default configuration")
129
+
130
+ # Show configuration summary
131
+ cfg = build_config()
132
+ with display.section("Application Configuration"):
133
+ display.table_dict(flatten_dict(cfg.model_dump()))
134
+
135
+ # Initialize container
136
+ display.step("Initializing application", step=1)
137
+ with display.loading("Wiring dependencies..."):
138
+ from audex.container import Container
139
+ import audex.view.pages
140
+
141
+ container = Container()
142
+ container.wire(packages=[audex.view.pages])
143
+
144
+ display.success("Application initialized")
145
+
146
+ # Launch info
147
+ display.step("Launching application", step=2)
148
+ print()
149
+
150
+ import platform
151
+
152
+ if cfg.core.app.native:
153
+ display.info("Launching in native window mode")
154
+ display.info(f"GUI Backend: PyQt6 ({platform.system()})")
155
+ else:
156
+ display.info("Application will open in your default browser")
157
+
158
+ display.info("Press Ctrl+C to stop")
159
+
160
+ # Separator before app logs
161
+ print()
162
+ display.separator()
163
+ print()
164
+
165
+ # Start application
166
+ view = container.views().view()
167
+ view.run()
168
+
169
+
170
+ def cli() -> None:
171
+ """Entry point for installed command-line script.
172
+
173
+ This function is called when running `audex` as an installed command.
174
+ It's registered in pyproject.toml as a console script entry point.
175
+
176
+ Example:
177
+ After installing with pip:
178
+
179
+ ```bash
180
+ audex --help
181
+ audex -c .config.yml
182
+ audex serve --port 8080
183
+ ```
184
+ """
185
+ sys.exit(main())
186
+
187
+
188
+ if __name__ == "__main__":
189
+ sys.exit(main())
@@ -0,0 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+
5
+
6
+ def register_apis(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
7
+ from audex.cli.apis import init
8
+ from audex.cli.apis import serve
9
+
10
+ # Only register serve and init, not run
11
+ serve.Args.register_subparser(subparsers, name="serve", help_text="Serve Audex export service")
12
+ init.register(subparsers)
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+
5
+
6
+ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
7
+ from audex.cli.apis.init import gencfg
8
+ from audex.cli.apis.init import setup
9
+ from audex.cli.apis.init import vprgroup
10
+
11
+ parser = subparsers.add_parser(
12
+ "init",
13
+ help="Initialize various Audex components.",
14
+ )
15
+ init_subparsers = parser.add_subparsers(
16
+ title="init commands",
17
+ dest="init_command",
18
+ )
19
+
20
+ gencfg.Args.register_subparser(
21
+ init_subparsers,
22
+ name="gencfg",
23
+ help_text="Generate a default configuration file for Audex.",
24
+ )
25
+ setup.Args.register_subparser(
26
+ init_subparsers,
27
+ name="setup",
28
+ help_text="Run the initial setup wizard for Audex.",
29
+ )
30
+ vprgroup.Args.register_subparser(
31
+ init_subparsers,
32
+ name="vprgroup",
33
+ help_text="Initialize a VPR service group.",
34
+ )
@@ -0,0 +1,130 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import pathlib
5
+ import typing as t
6
+
7
+ from pydantic import Field
8
+
9
+ from audex.cli.args import BaseArgs
10
+ from audex.cli.helper import display
11
+ from audex.utils import flatten_dict
12
+
13
+
14
+ class Args(BaseArgs):
15
+ format: t.Literal["dotenv", "yaml", "json", "system"] = Field(
16
+ default="dotenv",
17
+ alias="f",
18
+ description="The format of the generated configuration file.",
19
+ )
20
+
21
+ output: pathlib.Path | None = Field(
22
+ default=None,
23
+ alias="o",
24
+ description="The output file path.If not provided, the configuration will be printed to stdout.",
25
+ )
26
+
27
+ platform: t.Literal["linux", "windows"] | None = Field(
28
+ default=None,
29
+ alias="p",
30
+ description="Target platform for system configuration (only used with --format=system).",
31
+ )
32
+
33
+ def run(self) -> None:
34
+ from audex.config import Config
35
+
36
+ display.banner("Configuration Generator", subtitle="Generate Configuration File")
37
+
38
+ # Show format selection
39
+ with display.section("Generation Options"):
40
+ options_info = {
41
+ "Format": self.format.upper(),
42
+ "Output": str(self.output) if self.output else "(auto-generated filename)",
43
+ }
44
+ if self.format == "system":
45
+ options_info["Platform"] = self.platform or "(current platform)" # type: ignore
46
+ display.key_value(options_info)
47
+
48
+ # Load default configuration
49
+ display.step("Loading default configuration", step=1)
50
+ cfg = Config()
51
+
52
+ # For system format, show platform-specific preview
53
+ platform = self.platform or ("linux" if os.name == "posix" else "windows") # type: ignore
54
+ if self.format == "system":
55
+ with display.section(f"System Configuration Preview ({platform})"):
56
+ display.info(f"Generating system configuration for {platform.upper()}")
57
+ display.warning("Only fields with platform-specific defaults will be included")
58
+ display.info("Unset fields will be omitted from the output")
59
+ else:
60
+ # Preview configuration
61
+ with display.section("Default Configuration Preview"):
62
+ cfg_dict = flatten_dict(cfg.model_dump())
63
+ display.info(f"Total {len(cfg_dict)} configuration keys")
64
+ display.table_dict(cfg_dict)
65
+
66
+ # Confirm generation
67
+ if not display.confirm("Generate configuration file?", default=True):
68
+ display.warning("Operation cancelled by user")
69
+ return
70
+
71
+ # Generate configuration file
72
+ display.step("Generating configuration file", step=2)
73
+
74
+ out = self.output
75
+
76
+ with display.loading(f"Writing {self.format.upper()} configuration..."):
77
+ if self.format == "dotenv":
78
+ cfg.to_dotenv(out or (out := pathlib.Path(".env.gen")))
79
+ elif self.format == "yaml":
80
+ cfg.to_yaml(out or (out := pathlib.Path(".config.gen.yml")))
81
+ elif self.format == "json":
82
+ cfg.to_json(out or (out := pathlib.Path(".config.gen.jsonc")))
83
+ elif self.format == "system":
84
+ platform = self.platform or ("linux" if os.name == "posix" else "windows")
85
+ default_filename = f"config.system.{platform}.yml"
86
+ cfg.to_system_yaml(
87
+ out or (out := pathlib.Path(default_filename)),
88
+ platform=platform, # type: ignore
89
+ )
90
+
91
+ # Show result
92
+ print()
93
+ display.success("Configuration file generated successfully!")
94
+
95
+ # Summary
96
+ display.header("Generation Summary")
97
+ summary_data: dict[str, t.Any] = {
98
+ "Format": self.format.upper(),
99
+ "Output File": str(out),
100
+ }
101
+
102
+ if self.format == "system":
103
+ summary_data["Platform"] = platform.upper()
104
+ summary_data["Note"] = "Only non-Unset fields included"
105
+ else:
106
+ summary_data["Total Keys"] = len(cfg_dict)
107
+
108
+ display.key_value(summary_data)
109
+
110
+ # Show file path with existence check
111
+ display.path(out, label="Saved to", exists=out.exists())
112
+
113
+ # Show usage hints
114
+ if self.format == "system":
115
+ print()
116
+ display.header("Usage Instructions")
117
+ display.info("This system configuration file is intended for:")
118
+ print(" • Deployment to /etc/audex/config.system.yml on Linux")
119
+ print(" • Use as read-only system-wide defaults")
120
+ print(" • User configurations should override this at ~/.config/audex/config.yml")
121
+
122
+ if platform == "linux":
123
+ print()
124
+ display.info("To deploy on Linux:")
125
+ print(f" sudo cp {out} /etc/audex/config.system.yml")
126
+ print(" sudo chown root:root /etc/audex/config.system.yml")
127
+ print(" sudo chmod 644 /etc/audex/config.system.yml")
128
+
129
+ print()
130
+ display.success("Done! 🎉")