初始化项目基础结构

添加了完整的前后端开发环境配置,包括:
- 创建 .gitignore 文件忽略本地生成目录和环境文件
- 添加详细的 README.md 开发指南文档
- 配置 backend 目录结构和 FastAPI 应用基础框架
- 实现应用配置管理、健康检查和状态接口
- 设置 uv 依赖管理和虚拟环境配置
- 完成 CORS 中间件配置支持前端开发联调
This commit is contained in:
2026-08-27 11:19:36 +08:00
commit 08e4aeea0c
29 changed files with 3539 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
APP_NAME=Notes Agent AI Core
APP_VERSION=0.1.0
APP_ENVIRONMENT=development
APP_HOST=127.0.0.1
APP_PORT=8000
+15
View File
@@ -0,0 +1,15 @@
# Backend
FastAPI + Pydantic 的最小后端壳子。项目使用 uv 管理依赖和虚拟环境。
```powershell
uv sync
uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
```
`uv sync` 首次运行时会自动创建由 uv 管理的 `.venv`,无需手动执行 `python -m venv` 或激活环境。
启动后可访问:
- 健康检查:<http://127.0.0.1:8000/health>
- API 文档:<http://127.0.0.1:8000/docs>
+1
View File
@@ -0,0 +1 @@
"""Notes Agent AI Core."""
+25
View File
@@ -0,0 +1,25 @@
import os
from dataclasses import dataclass
from functools import lru_cache
@dataclass(frozen=True)
class Settings:
"""应用基础配置;正式环境可通过 APP_* 环境变量覆盖。"""
name: str
version: str
environment: str
host: str
port: int
@lru_cache
def get_settings() -> Settings:
return Settings(
name=os.getenv("APP_NAME", "Notes Agent AI Core"),
version=os.getenv("APP_VERSION", "0.1.0"),
environment=os.getenv("APP_ENVIRONMENT", "development"),
host=os.getenv("APP_HOST", "127.0.0.1"),
port=int(os.getenv("APP_PORT", "8000")),
)
+35
View File
@@ -0,0 +1,35 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import get_settings
from app.schemas import HealthResponse, ServiceStatusResponse
settings = get_settings()
app = FastAPI(
title=settings.name,
version=settings.version,
description="AI 笔记软件的本地 FastAPI 服务壳子。",
)
app.add_middleware(
CORSMiddleware,
allow_origins=["http://127.0.0.1:5173", "http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/health", response_model=HealthResponse, tags=["System"])
async def health() -> HealthResponse:
return HealthResponse()
@app.get("/api/status", response_model=ServiceStatusResponse, tags=["System"])
async def service_status() -> ServiceStatusResponse:
return ServiceStatusResponse(
name=settings.name,
version=settings.version,
environment=settings.environment,
)
+13
View File
@@ -0,0 +1,13 @@
from typing import Literal
from pydantic import BaseModel
class HealthResponse(BaseModel):
status: Literal["ok"] = "ok"
class ServiceStatusResponse(HealthResponse):
name: str
version: str
environment: str
@@ -0,0 +1,22 @@
Metadata-Version: 2.4
Name: notes-agent-backend
Version: 0.1.0
Summary: Notes Agent 的 FastAPI 基础壳子
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: fastapi<1.0,>=0.116
Requires-Dist: uvicorn[standard]<1.0,>=0.35
# Backend
FastAPI + Pydantic 的最小后端壳子。
```powershell
uv sync
uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
```
启动后可访问:
- 健康检查:<http://127.0.0.1:8000/health>
- API 文档:<http://127.0.0.1:8000/docs>
@@ -0,0 +1,12 @@
README.md
pyproject.toml
app/__init__.py
app/config.py
app/main.py
app/schemas.py
notes_agent_backend.egg-info/PKG-INFO
notes_agent_backend.egg-info/SOURCES.txt
notes_agent_backend.egg-info/dependency_links.txt
notes_agent_backend.egg-info/requires.txt
notes_agent_backend.egg-info/top_level.txt
tests/test_api.py
@@ -0,0 +1 @@
@@ -0,0 +1,2 @@
fastapi<1.0,>=0.116
uvicorn[standard]<1.0,>=0.35
@@ -0,0 +1 @@
app
+19
View File
@@ -0,0 +1,19 @@
[project]
name = "notes-agent-backend"
version = "0.1.0"
description = "Notes Agent 的 FastAPI 基础壳子"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.116,<1.0",
"uvicorn[standard]>=0.35,<1.0",
]
[dependency-groups]
dev = [
"pytest>=8.4,<9.0",
]
[tool.pytest.ini_options]
pythonpath = ["."]
testpaths = ["tests"]
+16
View File
@@ -0,0 +1,16 @@
import asyncio
from app.main import health, service_status
def test_health() -> None:
response = asyncio.run(health())
assert response.model_dump() == {"status": "ok"}
def test_service_status() -> None:
response = asyncio.run(service_status())
assert response.name == "Notes Agent AI Core"
assert response.status == "ok"