aimd-api 0.9.2__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.
- aimd_api/__init__.py +22 -0
- aimd_api/app.py +158 -0
- aimd_api-0.9.2.dist-info/METADATA +10 -0
- aimd_api-0.9.2.dist-info/RECORD +6 -0
- aimd_api-0.9.2.dist-info/WHEEL +4 -0
- aimd_api-0.9.2.dist-info/entry_points.txt +3 -0
aimd_api/__init__.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""HTTP API package for aimd."""
|
|
2
|
+
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"EngineCapabilityResponse",
|
|
7
|
+
"EnginesResponse",
|
|
8
|
+
"HealthResponse",
|
|
9
|
+
"ProcessRequest",
|
|
10
|
+
"ProcessResponse",
|
|
11
|
+
"app",
|
|
12
|
+
"create_app",
|
|
13
|
+
"main",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def __getattr__(name: str):
|
|
18
|
+
if name in __all__:
|
|
19
|
+
app_module = import_module(".app", __name__)
|
|
20
|
+
|
|
21
|
+
return getattr(app_module, name)
|
|
22
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
aimd_api/app.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""FastAPI service package for aimd."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from fastapi import FastAPI, HTTPException
|
|
7
|
+
from logly import logger
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from aimd.application.bootstrap import build_container
|
|
11
|
+
from aimd.application.models import TaskType
|
|
12
|
+
from aimd.application.services.interface_payloads import (
|
|
13
|
+
build_process_input,
|
|
14
|
+
engine_capabilities_payload,
|
|
15
|
+
get_request_temp_dir,
|
|
16
|
+
process_result_payload,
|
|
17
|
+
)
|
|
18
|
+
from aimd.application.services.output_writer import persist_result_output_if_requested
|
|
19
|
+
from aimd.errors import AimdError
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class HealthResponse(BaseModel):
|
|
23
|
+
status: str = "ok"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class EngineCapabilityResponse(BaseModel):
|
|
27
|
+
name: str
|
|
28
|
+
available: bool
|
|
29
|
+
reason: str | None = None
|
|
30
|
+
fix_hint: str | None = None
|
|
31
|
+
selected_by_auto: bool = False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class EnginesResponse(BaseModel):
|
|
35
|
+
auto_selected_engine: str | None = None
|
|
36
|
+
engines: list[EngineCapabilityResponse]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ProcessRequest(BaseModel):
|
|
40
|
+
input_source: str = Field(
|
|
41
|
+
..., description="Audio/video file path, video URL, or document file path."
|
|
42
|
+
)
|
|
43
|
+
output_file: str | None = Field(
|
|
44
|
+
default=None, description="Optional path to write resulting markdown output."
|
|
45
|
+
)
|
|
46
|
+
transcribe_engine: str = Field(
|
|
47
|
+
default="auto",
|
|
48
|
+
description="Transcription engine: auto, mlx, qwen.",
|
|
49
|
+
)
|
|
50
|
+
model: str | None = Field(
|
|
51
|
+
default=None,
|
|
52
|
+
description="Model for transcription. mlx defaults to mlx-community/Qwen3-ASR-1.7B-4bit "
|
|
53
|
+
"and also supports other documented mlx-audio STT model IDs. "
|
|
54
|
+
"qwen supports Qwen/Qwen3-ASR-1.7B (default) or Qwen/Qwen3-ASR-0.6B.",
|
|
55
|
+
)
|
|
56
|
+
language: str | None = Field(
|
|
57
|
+
default=None, description="Language code for transcription, e.g. zh, en, ja."
|
|
58
|
+
)
|
|
59
|
+
save_original: str | None = Field(
|
|
60
|
+
default=None,
|
|
61
|
+
description="Optional path to persist downloaded audio from URL processing.",
|
|
62
|
+
)
|
|
63
|
+
cookies: str | None = Field(
|
|
64
|
+
default=None,
|
|
65
|
+
description="Path to Netscape-format cookies file for URL extraction.",
|
|
66
|
+
)
|
|
67
|
+
cookies_from_browser: str | None = Field(
|
|
68
|
+
default=None,
|
|
69
|
+
description="Browser cookie source for URL extraction, e.g. chrome:default.",
|
|
70
|
+
)
|
|
71
|
+
raw_transcript: bool = Field(
|
|
72
|
+
default=False,
|
|
73
|
+
description="Preserve original subtitle formatting (SRT/VTT timestamps). "
|
|
74
|
+
"By default, subtitles are simplified to plain text.",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ProcessResponse(BaseModel):
|
|
79
|
+
task_type: TaskType
|
|
80
|
+
title: str
|
|
81
|
+
chunk_list: list[str]
|
|
82
|
+
split_header_level: int | None = None
|
|
83
|
+
platform: str | None = None
|
|
84
|
+
output_file: str | None = None
|
|
85
|
+
output_dir: str | None = None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def create_app() -> FastAPI:
|
|
89
|
+
"""Build FastAPI app instance."""
|
|
90
|
+
app = FastAPI(
|
|
91
|
+
title="aimd API",
|
|
92
|
+
description="Context preparation API for LLM workflows",
|
|
93
|
+
version=version("aimd-cli"),
|
|
94
|
+
)
|
|
95
|
+
container = build_container()
|
|
96
|
+
|
|
97
|
+
@app.get("/healthz", response_model=HealthResponse)
|
|
98
|
+
async def healthz() -> HealthResponse:
|
|
99
|
+
return HealthResponse()
|
|
100
|
+
|
|
101
|
+
@app.get("/v1/engines", response_model=EnginesResponse)
|
|
102
|
+
async def engines() -> EnginesResponse:
|
|
103
|
+
result = container.list_engines_use_case.execute()
|
|
104
|
+
return EnginesResponse(**engine_capabilities_payload(result))
|
|
105
|
+
|
|
106
|
+
@app.post("/v1/process", response_model=ProcessResponse)
|
|
107
|
+
async def process(request: ProcessRequest) -> ProcessResponse:
|
|
108
|
+
try:
|
|
109
|
+
temp_dir = get_request_temp_dir()
|
|
110
|
+
|
|
111
|
+
result = await container.process_input_use_case.execute(
|
|
112
|
+
build_process_input(
|
|
113
|
+
input_source=request.input_source,
|
|
114
|
+
transcribe_engine=request.transcribe_engine,
|
|
115
|
+
model=request.model,
|
|
116
|
+
language=request.language,
|
|
117
|
+
save_original=request.save_original,
|
|
118
|
+
cookies=request.cookies,
|
|
119
|
+
cookies_from_browser=request.cookies_from_browser,
|
|
120
|
+
temp_dir=temp_dir,
|
|
121
|
+
raw_transcript=request.raw_transcript,
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
persisted = persist_result_output_if_requested(result, request.output_file)
|
|
126
|
+
if persisted.ignored_output_file:
|
|
127
|
+
logger.warning(
|
|
128
|
+
"Ignoring output_file for book conversions; output is a directory."
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return ProcessResponse(
|
|
132
|
+
**process_result_payload(
|
|
133
|
+
result,
|
|
134
|
+
output_file=persisted.output_file,
|
|
135
|
+
output_dir=persisted.output_dir,
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
except AimdError as exc:
|
|
139
|
+
raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc
|
|
140
|
+
except ValueError as exc:
|
|
141
|
+
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
142
|
+
except Exception as exc:
|
|
143
|
+
logger.error(f"API processing failed: {exc}")
|
|
144
|
+
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
|
145
|
+
|
|
146
|
+
return app
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
app = create_app()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def main() -> None:
|
|
153
|
+
"""Run FastAPI service via uvicorn."""
|
|
154
|
+
import uvicorn
|
|
155
|
+
|
|
156
|
+
host = os.getenv("AIMD_API_HOST", "127.0.0.1")
|
|
157
|
+
port = int(os.getenv("AIMD_API_PORT", "8000"))
|
|
158
|
+
uvicorn.run("aimd_api:app", host=host, port=port, reload=False)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: aimd-api
|
|
3
|
+
Version: 0.9.2
|
|
4
|
+
Summary: FastAPI service for aimd.
|
|
5
|
+
Author: Shu Li
|
|
6
|
+
Author-email: Shu Li <zetarylee@gmail.com>
|
|
7
|
+
Requires-Dist: aimd-cli
|
|
8
|
+
Requires-Dist: fastapi>=0.116.1
|
|
9
|
+
Requires-Dist: uvicorn>=0.35.0
|
|
10
|
+
Requires-Python: >=3.10, <3.13
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
aimd_api/__init__.py,sha256=YLH1Wgf_cKn7nOlQpiUbKptSnUXY2AZxxrKVcc3z41A,472
|
|
2
|
+
aimd_api/app.py,sha256=u1KeAOgFWfy4ecxwiF0BBiad9clDniRbeIsxsvFnHBY,5338
|
|
3
|
+
aimd_api-0.9.2.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
4
|
+
aimd_api-0.9.2.dist-info/entry_points.txt,sha256=sgB6NImUHyK7NwaqyFQmV_fUdxN05bQiroJC-HqwFJw,44
|
|
5
|
+
aimd_api-0.9.2.dist-info/METADATA,sha256=J99mmz97dmM2MphEcEaCPAgBPDVUOyPeHRnIt-pc2ss,263
|
|
6
|
+
aimd_api-0.9.2.dist-info/RECORD,,
|