支持自定义端口
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
DEEPSEEK_API_KEY=your-api-key
|
||||
SERVICE_PORT=8000
|
||||
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||||
DEEPSEEK_MODEL=deepseek-v4-flash
|
||||
DEFAULT_SYSTEM_PROMPT=You are a helpful assistant.
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
export DEEPSEEK_API_KEY="your-api-key"
|
||||
cp .env.example .env
|
||||
# 编辑 .env 并填写 DEEPSEEK_API_KEY
|
||||
uv run uvicorn main:app --reload
|
||||
```
|
||||
|
||||
服务默认运行在 `http://127.0.0.1:8000`,交互式 API 文档位于 `/docs`。
|
||||
|
||||
可通过环境变量配置 `DEEPSEEK_BASE_URL`、`DEEPSEEK_MODEL`、`DEFAULT_SYSTEM_PROMPT` 和 `CHAT_DATA_DIR`,完整示例见 `.env.example`。第一版应只使用一个 Uvicorn worker。
|
||||
服务会自动加载项目根目录的 `.env`,已有系统环境变量优先级更高。可配置 `DEEPSEEK_BASE_URL`、`DEEPSEEK_MODEL`、`DEFAULT_SYSTEM_PROMPT` 和 `CHAT_DATA_DIR`,完整示例见 `.env.example`。第一版应只使用一个 Uvicorn worker。
|
||||
|
||||
## 使用
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@ from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class Settings:
|
||||
port: int
|
||||
api_key: str | None
|
||||
base_url: str
|
||||
model: str
|
||||
@@ -13,7 +16,9 @@ class Settings:
|
||||
|
||||
@classmethod
|
||||
def from_env(cls) -> "Settings":
|
||||
load_dotenv(dotenv_path=Path.cwd() / ".env", override=False)
|
||||
return cls(
|
||||
port=int(os.getenv("SERVICE_PORT", "8000")),
|
||||
api_key=os.getenv("DEEPSEEK_API_KEY"),
|
||||
base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com"),
|
||||
model=os.getenv("DEEPSEEK_MODEL", "deepseek-v4-flash"),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
from app import app
|
||||
|
||||
from config import Settings
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
||||
settings = Settings.from_env()
|
||||
uvicorn.run("main:app", host="0.0.0.0", port=settings.port, reload=True)
|
||||
|
||||
@@ -8,6 +8,7 @@ dependencies = [
|
||||
"fastapi>=0.115.0",
|
||||
"httpx[socks]>=0.28.0",
|
||||
"openai>=1.55.0",
|
||||
"python-dotenv>=1.0.0",
|
||||
"uvicorn[standard]>=0.32.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ class FakeClient:
|
||||
def client_and_provider(tmp_path: Path) -> tuple[TestClient, FakeClient]:
|
||||
provider = FakeClient()
|
||||
settings = Settings(
|
||||
port=8000,
|
||||
api_key=None,
|
||||
base_url="https://api.deepseek.com",
|
||||
model="deepseek-v4-flash",
|
||||
@@ -66,6 +67,18 @@ def create_session(client: TestClient, **body: str) -> str:
|
||||
return response.json()["session_id"]
|
||||
|
||||
|
||||
def test_settings_load_api_key_from_dotenv(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.chdir(tmp_path)
|
||||
monkeypatch.delenv("DEEPSEEK_API_KEY", raising=False)
|
||||
(tmp_path / ".env").write_text("DEEPSEEK_API_KEY=test-key\n")
|
||||
|
||||
settings = Settings.from_env()
|
||||
|
||||
assert settings.api_key == "test-key"
|
||||
|
||||
|
||||
def test_create_session_uses_default_prompt(
|
||||
client_and_provider: tuple[TestClient, FakeClient], tmp_path: Path
|
||||
) -> None:
|
||||
|
||||
@@ -366,6 +366,7 @@ dependencies = [
|
||||
{ name = "fastapi" },
|
||||
{ name = "httpx", extra = ["socks"] },
|
||||
{ name = "openai" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "uvicorn", extra = ["standard"] },
|
||||
]
|
||||
|
||||
@@ -379,6 +380,7 @@ requires-dist = [
|
||||
{ name = "fastapi", specifier = ">=0.115.0" },
|
||||
{ name = "httpx", extras = ["socks"], specifier = ">=0.28.0" },
|
||||
{ name = "openai", specifier = ">=1.55.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.0.0" },
|
||||
{ name = "uvicorn", extras = ["standard"], specifier = ">=0.32.0" },
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user