Compare commits
5
Commits
81623b1857
...
85964d002f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85964d002f | ||
|
|
af97cae9d8 | ||
|
|
8f6b2bc136 | ||
|
|
544baffba2 | ||
|
|
d719c949e2 |
No files matched your search
@@ -5,3 +5,7 @@
|
|||||||
shell.nix
|
shell.nix
|
||||||
README.md
|
README.md
|
||||||
.metadata/
|
.metadata/
|
||||||
|
.results/
|
||||||
|
backend.db
|
||||||
|
__pycache__/
|
||||||
|
.ruff_cache/
|
||||||
@@ -233,3 +233,4 @@ dist-ssr
|
|||||||
*.db
|
*.db
|
||||||
|
|
||||||
.metadata/
|
.metadata/
|
||||||
|
.results/
|
||||||
+1
-1
@@ -9,4 +9,4 @@ RUN pip install --no-cache-dir -r dependencies.txt
|
|||||||
ENV FLASK_ENV=production
|
ENV FLASK_ENV=production
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:80", "--workers", "1"]
|
CMD ["sh", "-c", "python -m db.InitDB && gunicorn app:app -b 0.0.0.0:80 --workers 1"]
|
||||||
@@ -1,38 +1,91 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from flask import Flask, jsonify, request
|
from flask import Flask, jsonify, request, send_file
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
from pydantic import ValidationError
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
|
from db.InitDB import DB_PATH, init_db
|
||||||
|
from models import AIRequest
|
||||||
|
|
||||||
# Создаем приложение Flask
|
# Создаем приложение Flask
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
METADATA_DIR = Path(__file__).parent / ".metadata"
|
init_db()
|
||||||
|
|
||||||
|
METADATA_DIR = Path(os.environ.get("METADATA_DIR") or Path(__file__).parent / ".metadata")
|
||||||
|
RESULT_DIR = Path(os.environ.get("RESULT_DIR") or Path(__file__).parent / ".results")
|
||||||
|
|
||||||
@app.route('/AI', methods=['POST'], strict_slashes=False)
|
@app.route('/AI', methods=['POST'], strict_slashes=False)
|
||||||
def ai_request():
|
def ai_request():
|
||||||
try:
|
try:
|
||||||
id = request.form.get("id")
|
payload = AIRequest(
|
||||||
text = request.form.get("text")
|
id=request.form.get("id", ""),
|
||||||
files = request.files.getlist("files")
|
text=request.form.get("text", ""),
|
||||||
|
file=[],
|
||||||
|
)
|
||||||
|
except ValidationError as e:
|
||||||
|
return jsonify({"error": e.errors()}), 422
|
||||||
|
|
||||||
request_dir = METADATA_DIR / (secure_filename(id) or "unknown")
|
try:
|
||||||
|
request_dir = METADATA_DIR / (secure_filename(payload.id) or "unknown")
|
||||||
request_dir.mkdir(parents=True, exist_ok=True)
|
request_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
saved_files = []
|
for file in request.files.getlist("files"):
|
||||||
for file in files:
|
|
||||||
filename = secure_filename(file.filename)
|
filename = secure_filename(file.filename)
|
||||||
if not filename:
|
if not filename:
|
||||||
continue
|
continue
|
||||||
file.save(request_dir / filename)
|
path = request_dir / filename
|
||||||
saved_files.append(filename)
|
file.save(path)
|
||||||
|
payload.file.append(str(path))
|
||||||
|
|
||||||
return jsonify({
|
with sqlite3.connect(DB_PATH) as conn:
|
||||||
"id": id,
|
conn.execute(
|
||||||
"text": text,
|
"INSERT INTO requests (id, text, file) VALUES (?, ?, ?)",
|
||||||
"files": saved_files,
|
(payload.id, payload.text, json.dumps(payload.file)),
|
||||||
}), 200
|
)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
return jsonify(payload.model_dump()), 200
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
return jsonify({"error": f"task {payload.id} already exists"}), 409
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
@app.route("/AI/<string:id>", methods=["GET"])
|
||||||
|
def req_status(id):
|
||||||
|
try:
|
||||||
|
with sqlite3.connect(DB_PATH) as conn:
|
||||||
|
row = conn.execute(
|
||||||
|
"SELECT status, result FROM requests WHERE id = ?", (id,)
|
||||||
|
).fetchone()
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
if row is None:
|
||||||
|
return jsonify({"error": f"task {id} not found"}), 404
|
||||||
|
|
||||||
|
status, result = row
|
||||||
|
|
||||||
|
if status not in ("OK", "ОК"):
|
||||||
|
return jsonify({"id": id, "status": status}), 200
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
return jsonify({"error": f"task {id} is OK but has no result file"}), 500
|
||||||
|
|
||||||
|
path = Path(result)
|
||||||
|
if not path.is_absolute():
|
||||||
|
path = RESULT_DIR / path
|
||||||
|
|
||||||
|
if not path.is_file():
|
||||||
|
return jsonify({"error": f"result file not found: {path}"}), 404
|
||||||
|
|
||||||
|
try:
|
||||||
|
return send_file(path, as_attachment=True, download_name=path.name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"error": str(e)}), 500
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
DB_PATH = Path(os.environ.get("DB_PATH") or PROJECT_ROOT / "backend.db")
|
||||||
|
|
||||||
|
SCHEMA = """
|
||||||
|
CREATE TABLE IF NOT EXISTS requests (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
file TEXT NOT NULL DEFAULT '[]',
|
||||||
|
status TEXT NOT NULL DEFAULT 'WAITING',
|
||||||
|
worker INTEGER NOT NULL DEFAULT 0,
|
||||||
|
result TEXT DEFAULT NULL
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def init_db() -> Path:
|
||||||
|
DB_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with sqlite3.connect(DB_PATH) as conn:
|
||||||
|
conn.executescript(SCHEMA)
|
||||||
|
conn.commit()
|
||||||
|
return DB_PATH
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(f"DB initialized: {init_db()}")
|
||||||
Whitespace-only changes.
@@ -0,0 +1,3 @@
|
|||||||
|
from models.request import AIRequest
|
||||||
|
|
||||||
|
__all__ = ["AIRequest"]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
|
||||||
|
class AIRequest(BaseModel):
|
||||||
|
id: str
|
||||||
|
text: str
|
||||||
|
file: list[str] = Field(default_factory=list)
|
||||||
Reference in new issue
Block a user