在2024年使用FastAPI创建以LLM为动力的API(第2部分)

FastAPI + OpenAI

Sure, here is the text translated to simplified Chinese while keeping the HTML structure intact: ```html

第二部分:项目结构、数据库建模和API端点

```

To translate the provided English text into simplified Chinese while keeping the HTML structure, you can use the following code snippet: ```html

欢迎回来参加我们关于构建LLM驱动API系列的文章。在第一篇文章中,我们介绍了项目并设置了开发环境。现在,是时候深入了解项目的结构、数据库建模和初始API端点了(Github仓库在这里)。

``` This HTML snippet includes the translated Chinese text within a paragraph (`

`) tag, preserving the structure as requested. Adjust the HTML structure further based on your specific needs for integration into your project or webpage.

Sure, here's the translation: 以下是本系列文章的索引:

  • Sure, here is the translated text in simplified Chinese: 第一部分:介绍、问题定义和设置
  • Sure, here is the translated text in simplified Chinese, keeping the HTML structure intact: ```html 第二部分:结构、数据库建模、API 终端点(当前位置) ```
  • Sure, here is the text translated to simplified Chinese while keeping HTML structure: ```html 第三部分:用户功能,认证和安全 ```

在这篇文章中,我们将涵盖:

  • Sure, here is the translation in simplified Chinese, while keeping the HTML structure intact: ```html 详细项目结构及每个文件的目的。 ```
  • 在我们的应用程序中定义用户和电子邮件日志模型。
  • Certainly! Here's the translation in simplified Chinese, keeping the HTML structure: ```html

    设置SQLite数据库并创建必要的函数。

    ```
  • 在HTML结构中保持不变,将以下英文文本翻译成简体中文: 定义用户和电子邮件操作的模式。
  • 在使用FastCRUD实现CRUD操作。
  • Sure, here is the translated text in simplified Chinese while maintaining the HTML structure: ```html 设置FastAPI应用程序并创建电子邮件生成端点。

    设置FastAPI应用程序并创建电子邮件生成端点。

    ```

Sure, here is the translation of "Step-by-Step Tutorial" into simplified Chinese, while keeping the HTML structure: ```html 逐步教程 ``` In this HTML snippet: - `` is used to inline the translated text. - `lang="zh-CN"` indicates the language of the text is simplified Chinese, which helps with accessibility and correct rendering in web browsers.

Sure, the translation of "Project Structure" into simplified Chinese while keeping the HTML structure would be: ```html 项目结构 ``` This HTML snippet ensures the text "项目结构" is correctly marked as simplified Chinese for display and processing purposes.

Certainly! Here's the translated text in simplified Chinese while keeping the HTML structure intact: ```html

现在让我们开始创建这个项目将要使用的结构。对于一个 FastAPI 应用,我们主要有三样东西:模型(models)、模式(schemas)和端点(endpoints)。由于这个 API 很简单,我们可以像这样创建我们的结构:

``` Feel free to use this HTML snippet as needed!
email_assistant_api/

├── app/
│ ├── __init__.py
│ ├── main.py # The main application file
│ ├── routes.py # Contains API route definitions and endpoint logic
│ ├── database.py # Database setup and session management
│ ├── models.py # SQLModel models for the application
│ ├── crud.py # CRUD operation implementations using FastCRUD
│ ├── schemas.py # Schemas for request and response models
│ └── .env # Environment variables

├── pyproject.toml # Project configuration and dependencies
├── README.md # Provides an overview and documentation
└── .gitignore # Files to be ignored by version control
  • Sure, here's the translation in simplified Chinese while keeping the HTML structure: ```html

    我们在 models.py 文件中定义我们的模型(对应数据库表的抽象)。

    ```
  • To translate "Our schemas (used to validate and serialize data) go in schemas.py" to simplified Chinese while keeping the HTML structure, you can use the following: ```html

    我们的模式(用于验证和序列化数据)存放在schemas.py中。

    ``` In this translation: - "我们的模式" translates to "Our schemas". - "用于验证和序列化数据" translates to "used to validate and serialize data". - "存放在schemas.py中" translates to "go in schemas.py". This maintains the HTML structure with a `

    ` tag for paragraph formatting.

  • Sure, here's the translation of "The endpoints are defined in routes.py" in simplified Chinese while keeping the HTML structure: ```html

    端点在 routes.py 中定义。

    ```
  • To translate "We still need a file to set up our database, that is database.py" into simplified Chinese without altering the HTML structure, you can use the following: ```html 我们仍然需要一个文件来设置我们的数据库,那就是 database.py ``` Make sure to replace the English text within the HTML structure with the translated Chinese text while keeping the HTML tags intact.
  • Sure, here's the translation in simplified Chinese while keeping the HTML structure: ```html

    我们还需要一个文件,用来定义我们与数据库的交互方式,即我们的CRUD操作,这就是crud.py。

    ```
  • Sure, here's the translated text in simplified Chinese while keeping the HTML structure: ```html 我们为环境变量创建一个文件 — 例如 API 密钥或密码 ``` This HTML structure ensures that the translated text can be integrated into a web page or document seamlessly.
  • Sure, here is the translation of the English text into simplified Chinese while maintaining HTML structure: ```html

    最后是我们的 main.py 文件,这是我们定义 FastAPI 应用程序和 API 入口点的地方。

    ```

保留HTML结构,将以下英文文本翻译为简体中文: 请注意,这种结构适合小型应用,但如果您希望为更大的应用程序使用更健壮的样板,可以查看这个。

Sure, here is the text "Modeling the Database" translated into simplified Chinese while keeping HTML structure: ```html 建模数据库 ```

To translate "For the database, we have a simple model" into simplified Chinese while keeping the HTML structure intact, you would write: ```html 对于数据库,我们有一个简单的模型 ``` In this HTML snippet, the translated Chinese text replaces the English sentence while maintaining the overall structure of the document.

  • Sure, here's the translated text in simplified Chinese while keeping the HTML structure: ```html

    用户拥有一个用户名、姓名、电子邮件,我们会存储一个经过哈希处理的密码。

    ```
  • Sure, here is the translated text in simplified Chinese while maintaining the HTML structure: ```html

    邮件日志包括我们定义的输入内容,以及时间戳、生成的电子邮件和与此日志相关联的用户ID。

    ``` This HTML snippet will display the translated text in a paragraph format.
  • 在HTML结构中保持不变,将以下英文文本翻译为简体中文: 用户可能有多个电子邮件日志。
  • user table one to many to email_logs table

现在让我们在我们的models.py文件中编写实际的模型:

# app/models.py

from sqlmodel import SQLModel, Field
from typing import Optional

class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(..., min_length=2, max_length=30)
username: str = Field(..., min_length=2, max_length=20)
email: str
hashed_password: str

class EmailLog(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
user_input: str
reply_to: Optional[str] = Field(default=None)
context: Optional[str] = Field(default=None)
length: Optional[int] = Field(default=None)
tone: str
generated_email: str
timestamp: str

在保持HTML结构的情况下,将以下英文文本翻译为简体中文: 并且为了与我们的数据库交互,我们将在crud.py中为每个模型实例化FastCRUD:

# app/crud.py

from fastcrud import FastCRUD
from .models import User, EmailLog
crud_user = FastCRUD(User)
crud_email_log = FastCRUD(EmailLog)

在保持HTML结构的情况下,将英文文本"Creating Schemas"翻译成简体中文为:"创建模式"

在schemas.py中也让我们创建我们的模式:

# app/schemas.py

from datetime import datetime
from typing import Optional
from sqlmodel import SQLModel, Field


# ------- user -------
class UserCreate(SQLModel):
name: str
username: str
email: str
password: str

class UserRead(SQLModel):
id: int
name: str
username: str
email: str

class UserCreateInternal(SQLModel):
name: str
username: str
email: str
hashed_password: str


# ------- email -------
class EmailRequest(SQLModel):
user_input: str
reply_to: Optional[str] = None
context: Optional[str] = None
length: int = 120
tone: str = "formal"

class EmailResponse(SQLModel):
generated_email: str


# ------- email log -------
class EmailLogCreate(SQLModel):
user_id: int
user_input: str
reply_to: Optional[str] = None
context: Optional[str] = None
length: Optional[int] = None
tone: Optional[str] = None
generated_email: str
timestamp: datetime = Field(
default_factory=lambda: datetime.now(UTC)
)

class EmailLogRead(SQLModel):
user_id: int
user_input: str
reply_to: Optional[str]
context: Optional[str]
length: Optional[int]
tone: Optional[str]
generated_email: str
timestamp: datetime

在考虑:

  • Sure, here's the HTML structure with the text translated into simplified Chinese: ```html

    创建用户需要输入姓名、用户名、电子邮件和密码(我们会存储密码的哈希值)。

    ``` In simplified Chinese: ``` 创建用户需要输入姓名、用户名、电子邮件和密码(我们会存储密码的哈希值)。 ```
  • Sure, here's the translation in simplified Chinese while keeping the HTML structure intact: ```html 我们将默认长度设为120,并将默认语气设为“正式”。 ``` This HTML snippet maintains the structure for embedding directly into web content while displaying the translated Chinese text.
  • 在保留HTML结构的情况下,将以下英文文本翻译为简体中文: 我们自动生成电子邮件日志的时间戳

在保持HTML结构的情况下,将英文文本"Creating our Application and Setting up the Database"翻译成简体中文如下: 创建我们的应用程序并设置数据库

即使我们已经有了我们的模型和模式,实际上我们既没有一个应用程序来服务端点,也没有一个数据库来创建表。让我们改变这一点。

在保留HTML结构的情况下,将英文文本“Starting with our database.py:”翻译成简体中文: 从我们的database.py开始:

# app/database.py

from sqlmodel import SQLModel, create_engine, AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "sqlite+aiosqlite:///./emailassistant.db"
engine = create_async_engine(DATABASE_URL, echo=True)

async_session = sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)

async def create_db_and_tables():
async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)

async def get_session() -> AsyncSession:
async with async_session() as session:
yield session

Certainly! Here's the translation of the text into simplified Chinese while keeping the HTML structure: ```html

在这里,我们连接到一个SQLite数据库,创建了一个函数来创建我们的数据库和表,以及一个会话,使我们能够与这个数据库进行交互。

``` In simplified Chinese characters, the translation reads: "在这里,我们连接到一个SQLite数据库,创建了一个函数来创建我们的数据库和表,以及一个会话,使我们能够与这个数据库进行交互。"

To translate "Now let’s finally create our FastAPI application:" into simplified Chinese while keeping the HTML structure, you can use the following: ```html 现在让我们最终创建我们的FastAPI应用程序: ``` This HTML structure maintains the original English text while embedding the Chinese translation seamlessly.

# app/main.py

from fastapi import FastAPI
from .database import create_db_and_tables

async def lifespan(app):
await create_db_and_tables()
yield

app = FastAPI(lifespan=lifespan)

在我们的应用程序启动和停止时,此生命周期用于执行操作,我们在这里定义它,以便在启动时创建数据库和表格。

To test this, run: 要测试这个,请运行:

poetry run fastapi run

你应该看到类似的东西

Sure, here's the translation in simplified Chinese while keeping the HTML structure: ```html 然后打开浏览器并前往 ```

127.0.0.1:8000/docs

To translate "You will see this:" into simplified Chinese and keep the HTML structure intact, you can use the following: ```html 您将看到这个: ``` This HTML snippet maintains the structure while displaying the translated text in simplified Chinese.

现在在您的终端中按Ctrl C来暂时关闭应用程序。

在保持HTML结构的情况下,将英文文本"Creating our Endpoints"翻译为简体中文: 创建我们的端点

Sure, here is the text translated into simplified Chinese while keeping the HTML structure: ```html

让我们首先创建生成电子邮件的端点,用户创建和验证将留待稍后处理。

``` In this HTML snippet, the translated text is wrapped in `

` tags to maintain structure.

Sure, here is the translated text in simplified Chinese while keeping the HTML structure: ```html

让我们首先在我们的 .env 文件中写入我们的 OpenAI API 密钥(这将被 .gitignore 忽略,并且不会出现在我们的代码仓库中):

```
# app/.env

OPENAI_API_KEY="my_openai_api_key"

Sure, here's the translation of the text into simplified Chinese while keeping the HTML structure intact: ```html 让我们将其写入我们的 .gitignore 文件,确保这个 API 密钥不会被提交: ```

# .gitignore

.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

现在我们应该从我们的 .env 文件中获取 OpenAI API 密钥,并实例化客户端:

# app/routes.py

import os

from starlette.config import Config
from openai import OpenAI

current_file_dir = os.path.dirname(os.path.realpath(__file__))
env_path = os.path.join(current_file_dir, ".env")

config = Config(env_path)

OPENAI_API_KEY = config("OPENAI_API_KEY")
open_ai_client = OpenAI(api_key=OPENAI_API_KEY)

Sure, here's the translated text in simplified Chinese, keeping the HTML structure: ```html

同时让我们为电子邮件端点创建一个路由器,并实际创建电子邮件端点:

``` This HTML snippet maintains the structure while presenting the translated text in simplified Chinese.
  • Sure, here is the translation of "We’ll create a system prompt to adapt the output to what we want" in simplified Chinese, while keeping the HTML structure intact: ```html 我们将创建一个系统提示来使输出适应我们想要的内容。 ``` In this HTML snippet, the Chinese text is inserted as the content between `

    ` tags (assuming it's a paragraph), but the actual HTML structure could vary based on context.

  • Sure, here's the translation of "We’ll create a basic prompt that formats the passed information" into simplified Chinese, while keeping the HTML structure: ```html

    我们将创建一个基本的提示,格式化传递的信息。

    ```
  • Sure, here is the translation of "Then we’ll pass this information to the OpenAI Client" in simplified Chinese, while keeping the HTML structure: ```html

    然后我们将这些信息传递给OpenAI客户端。

    ```
  • 最后,我们将在数据库中创建一个日志条目,并返回生成的电子邮件。
# app/routes.py

...

from openai import OpenAI
from fastapi import APIRouter, Depends, HTTPException

from .schemas import EmailRequest, EmailResponse
from .database import get_session

...

# ------- email -------
email_router = APIRouter()
@email_router.post("/", response_model=EmailResponse)
async def generate_email(
request: EmailRequest,
db: AsyncSession = Depends(get_session)
):
try:
system_prompt = f"""
You are a helpful email assistant.
You get a prompt to write an email,
you reply with the email and nothing else.
"""

prompt = f"""
Write an email based on the following input:
- User Input: {request.user_input}
- Reply To: {request.reply_to if request.reply_to else 'N/A'}
- Context: {request.context if request.context else 'N/A'}
- Length: {request.length if request.length else 'N/A'} characters
- Tone: {request.tone if request.tone else 'N/A'}
"""

response = await open_ai_client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt},
],
max_tokens=request.length
)

generated_email = response.choices[0].message['content'].strip()
log_entry = EmailLogCreate(
user_id=request.user_id,
user_input=request.user_input,
reply_to=request.reply_to,
context=request.context,
length=request.length,
tone=request.tone,
generated_email=generated_email,
)
await crud_email_logs.create(db, log_entry)

return EmailResponse(generated_email=generated_email)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

Certainly! Here's the translated text in simplified Chinese, keeping the HTML structure: ```html 现在让我们回到 app/main.py,将这个电子邮件路由器包含到我们的 FastAPI 应用程序中: ``` This translation should fit well into an HTML structure.

# app/main.py

from fastapi import FastAPI

from .database import create_db_and_tables
from .routes import email_router

async def lifespan(app):
await create_db_and_tables()
yield

app = FastAPI(lifespan=lifespan)
app.include_router(email_router, prefix="/generate", tags=["Email"])

Sure, here is the translated text in simplified Chinese while keeping the HTML structure: ```html Saving and running our FastAPI app (127.0.0.1:8000/docs) again we get: ``` Translated to simplified Chinese: ```html 保存并运行我们的 FastAPI 应用程序(127.0.0.1:8000/docs),我们再次得到: ```

Sure, here is the translated text in simplified Chinese while keeping the HTML structure: ```html 点击这个新创建的POST端点,我们可以实际尝试它。所以让我们做吧,传递一些信息并点击执行。 ``` This HTML structure preserves the text while allowing it to be displayed correctly in web environments.

Sure, here's the text translated into simplified Chinese while keeping the HTML structure: ```html 而我们收到的回复是: ```

To translate the provided English text into simplified Chinese, while keeping the HTML structure intact, you can use the following: ```html

太好了,这正是我们希望得到的回应。我们实际上看不到日志是否在工作,所以让我们也创建电子邮件日志端点:

``` In this HTML snippet: - `

` and `

` are paragraph tags, indicating that the enclosed text should be treated as a paragraph. - The Chinese text is placed inside the paragraph tags, ensuring it is displayed as regular text on a webpage. Make sure your HTML document is properly structured and encoded to support Chinese characters (UTF-8 encoding is typically used).
# app/routes.py

...

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio.session import AsyncSession

from .schemas import EmailLogCreate, EmailLogRead

...

# ------- email log -------
log_router = APIRouter()

@log_router.get("/")
async def read_logs(db: AsyncSession = Depends(get_session)):
logs = await crud_email_logs.get_multi(db)
return logs

@log_router.get("/{log_id}", response_model=EmailLogRead)
async def read_log(log_id: int, db: AsyncSession = Depends(get_session)):
log = await crud_email_logs.get(db, id=log_id)
if not log:
raise HTTPException(status_code=404, detail="Log not found")
return log

在这里,我们可以看到多个日志或者根据其ID查看单个日志。让我们也将这个路由器包含到我们的应用程序中去:

# app/main.py

from fastapi import FastAPI

from .database import create_db_and_tables
from .routes import email_router, log_router

async def lifespan(app):
await create_db_and_tables()
yield

app = FastAPI(lifespan=lifespan)

app.include_router(email_router, prefix="/generate", tags=["Email"])
app.include_router(log_router, prefix="/logs", tags=["Logs"])

To translate the English text "You may head to 127.0.0.1:8000/docs and see for yourself that it’s working." into simplified Chinese while keeping the HTML structure, you can use the following: ```html

你可以访问127.0.0.1:8000/docs,亲自查看它是否正常工作。

``` This HTML structure maintains the link and conveys the translated message clearly in simplified Chinese.

Sure, the translation of "What’s Next?" into simplified Chinese while keeping HTML structure would be: ```html

接下来是什么?

```

在本篇文章中,我们涵盖了项目结构、数据库建模和初始的API端点。在最后部分,我们将添加用户功能、认证,并实施安全功能,确保只有经过身份验证的用户可以访问和管理他们的电子邮件日志。

现在让我们进入最后一部分,第三部分:用户功能、身份验证和安全性。

在保持HTML结构不变的情况下,将英文文本"Connect with Me"翻译成简体中文,可以这样写: ```html 连接我 ``` 这段HTML代码保持了原始的结构,并将英文翻译成了简体中文。

在保持HTML结构的情况下,将以下英文文本翻译为简体中文: 如果您有任何问题,想讨论技术相关的话题,或者分享您的反馈意见,请随时通过社交媒体联系我:

  • Sure, here's the translation in simplified Chinese while keeping the HTML structure: ```html

    GitHub: igorbenav

    ``` Translated to simplified Chinese: ```html

    GitHub:igorbenav

    ```
  • Sure, here's the translation in simplified Chinese while maintaining the HTML structure: ```html X/Twitter: igorbenav ``` Translated to simplified Chinese: ```html X/Twitter:igorbenav ```
  • LinkedIn: 伊戈

2024-06-25 05:23:26 AI中文站翻译自原文