geqintan commited on
Commit
d462ad5
·
1 Parent(s): f37d062

first commit

Browse files
Files changed (8) hide show
  1. .gitignore +2 -0
  2. Dockerfile +16 -0
  3. app.py +21 -0
  4. database.py +19 -0
  5. models/user.py +38 -0
  6. requirements.txt +4 -0
  7. routes/v1.py +66 -0
  8. routes/v2.py +1 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ __pycache__
2
+ test.db
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.11
5
+
6
+ RUN useradd -m -u 1000 user
7
+ USER user
8
+ ENV PATH="/home/user/.local/bin:$PATH"
9
+
10
+ WORKDIR /app
11
+
12
+ COPY --chown=user ./requirements.txt requirements.txt
13
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
14
+
15
+ COPY --chown=user . /app
16
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 导入FastAPI框架
2
+ from fastapi import FastAPI
3
+ from routes import v1
4
+ # 导入数据库引擎
5
+ from database import engine
6
+ # 导入用户模型的Base类
7
+ from models.user import Base
8
+
9
+ # 创建所有表结构
10
+ Base.metadata.create_all(bind=engine)
11
+
12
+ # 创建FastAPI应用实例
13
+ app = FastAPI()
14
+
15
+ app.include_router(v1.router, prefix="/v1")
16
+
17
+ # 定义根路径的GET请求处理函数
18
+ @app.get("/")
19
+ def greet_json():
20
+ # 返回JSON格式的问候信息
21
+ return {"Hello": "World!"}
database.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 导入SQLAlchemy的create_engine函数
2
+ from sqlalchemy import create_engine
3
+ # 导入SQLAlchemy的sessionmaker函数
4
+ from sqlalchemy.orm import sessionmaker
5
+ # 导入SQLAlchemy的declarative_base函数
6
+ from sqlalchemy.ext.declarative import declarative_base
7
+
8
+ # 定义SQLAlchemy数据库URL
9
+ SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"
10
+
11
+ # 创建SQLAlchemy引擎实例
12
+ engine = create_engine(
13
+ SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
14
+ )
15
+ # 创建会话本地实例
16
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
17
+
18
+ # 创建SQLAlchemy的Base类实例
19
+ Base = declarative_base()
models/user.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 导入类型注解模块
2
+ from typing import Optional
3
+ # 导入Pydantic的BaseModel类
4
+ from pydantic import BaseModel
5
+ # 导入SQLAlchemy的列、整数、字符串、布尔类型
6
+ from sqlalchemy import Column, Integer, String, Boolean
7
+ # 导入SQLAlchemy的declarative_base函数
8
+ from sqlalchemy.ext.declarative import declarative_base
9
+ # 导入SQLAlchemy的relationship函数
10
+ from sqlalchemy.orm import relationship
11
+
12
+ # 创建SQLAlchemy的Base类实例
13
+ Base = declarative_base()
14
+
15
+ # 定义用户模型类,继承自Base
16
+ class User(Base):
17
+ # 定义表名
18
+ __tablename__ = "users"
19
+
20
+ # 定义用户ID列,主键,索引
21
+ id = Column(Integer, primary_key=True, index=True)
22
+ # 定义用户名列,唯一,索引
23
+ username = Column(String, unique=True, index=True)
24
+ # 定义哈希密码列
25
+ hashed_password = Column(String)
26
+ # 定义邮箱列,唯一,索引
27
+ email = Column(String, unique=True, index=True)
28
+ # 定义禁用状态列,默认为False
29
+ disabled = Column(Boolean, default=False)
30
+
31
+ # 定义用户创建模型类,继承自BaseModel
32
+ class UserCreate(BaseModel):
33
+ # 定义用户名字段
34
+ username: str
35
+ # 定义密码字段
36
+ password: str
37
+ # 定义邮箱字段
38
+ email: str
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ fastapi==0.115.8
2
+ uvicorn[standard]==0.34.0
3
+ httpx==0.28.1
4
+ sqlalchemy==2.0.38
routes/v1.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import httpx
2
+ from fastapi import APIRouter, HTTPException, Request
3
+ import json
4
+
5
+ router = APIRouter()
6
+
7
+ @router.get("/")
8
+ async def v1():
9
+ return {"message": "Hello World from v1"}
10
+
11
+ @router.get("/{protocol}/{url:path}")
12
+ async def proxy_request(protocol:str, url: str):
13
+ async with httpx.AsyncClient() as client:
14
+ try:
15
+ target_url = f"{protocol}://{url}"
16
+ response = await client.get(
17
+ target_url,
18
+ headers={},
19
+ )
20
+ response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
21
+ return response.content
22
+ except httpx.HTTPStatusError as e:
23
+ raise HTTPException(status_code=e.response.status_code, detail=str(e))
24
+ except httpx.RequestError as e:
25
+ raise HTTPException(status_code=500, detail=str(e))
26
+
27
+ @router.post("/{protocol}/{url:path}")
28
+ async def proxy_post(protocol:str, url: str, request: Request):
29
+ body = await request.body()
30
+ headers = dict(request.headers) # 将请求头转换为字典
31
+
32
+ # 移除 Content-Length 和 Host 头部
33
+ if 'content-length' in headers:
34
+ del headers['content-length']
35
+ if 'host' in headers:
36
+ del headers['host']
37
+
38
+ headers['User-Agent']='curl/8.7.1'
39
+
40
+ dest_url = f"{protocol}://{url}"
41
+
42
+ async with httpx.AsyncClient() as client:
43
+ try:
44
+ # 向目标 URL 发送 POST 请求
45
+ response = await client.post(dest_url, content=body, headers=headers)
46
+
47
+ # 检查响应状态码
48
+ if response.status_code == 200:
49
+ # 检查响应内容类型是否为 JSON
50
+ if 'application/json' in response.headers.get('content-type', ''):
51
+ return response.json()
52
+ else:
53
+ return {"error": "Response is not in JSON format"}
54
+ else:
55
+ # 将错误响应转换为 JSON 格式并返回给客户端
56
+ try:
57
+ error_data = response.json()
58
+ except ValueError:
59
+ error_data = {"status_code": response.status_code, "detail": response.text}
60
+ return error_data
61
+
62
+ except httpx.RequestError as e:
63
+ # 处理请求错误
64
+ raise HTTPException(status_code=500, detail=str(e))
65
+
66
+ # routes for v1 API
routes/v2.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # routes for v2 API