Publish #1

Merged
IgorVolochay merged 29 commits from dev into main 2026-01-10 16:02:13 +00:00
5 changed files with 57 additions and 18 deletions
Showing only changes of commit ecd3d79f2b - Show all commits
+29 -14
View File
@@ -1,5 +1,3 @@
from fastapi import FastAPI, File, UploadFile
import dotenv
import os
import random
@@ -8,6 +6,13 @@ import string
import asyncio
import uvicorn
from datetime import datetime
from fastapi import FastAPI, Response, status, Request
from schemas.api_schemas import *
from s3_worker import S3Worker
from redis_worker import RedisWorker
dotenv.load_dotenv()
disable_docs = os.getenv("DISABLE_DOCS", "true").lower() == "true"
app: FastAPI = FastAPI(title="DropMeFiles analog")
@@ -18,21 +23,31 @@ app: FastAPI = FastAPI(title="DropMeFiles analog")
# docs_url=None if disable_docs else "/docs",
# redoc_url=None if disable_docs else "/redoc",
# openapi_url=None if disable_docs else "/openapi.json")
s3_worker = S3Worker()
redis_worker = RedisWorker()
data = dict()
@app.post("/upload_file")
async def create_upload_file(file: UploadFile = File(...)):
random_string = ''.join(random.choices(string.ascii_letters + string.digits, k=6))
data[random_string] = file.filename
return {"filename": file.filename, "content_type": file.content_type, "id": random_string}
@app.get("/upload_token", status_code=200)
async def get_upload_token(file_name: str, file_type: str, file_size: int, response: Response, request: Request) -> UploadToken | BaseResponse:
if file_size > int(os.getenv('MAX_FILES_SIZE')):
response.status_code = status.HTTP_413_CONTENT_TOO_LARGE
return BaseResponse(result="The uploaded file is too large", error=True)
elif file_size <= 0:
response.status_code = status.HTTP_400_BAD_REQUEST
return BaseResponse(result="The file you are uploading is less than 1 byte, WTF?", error=True)
@app.get("/{item_id}")
async def read_item(item_id: str):
if item_id in data.keys():
return {"return": data[item_id]}
else:
return {"return": "NO DATA!"}
user_ip = request.client.host
file_uuid = ''.join(random.choices(string.ascii_letters + string.digits, k=6))
async with s3_worker as worker:
try:
post_data = await worker.generate_upload_post(file_name, content_type=file_type)
except Exception as exception:
response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
return BaseResponse(result="Error generating S3 access token. Error: " + str(exception), error=True)
redis_worker.create_record(user_ip, file_name, file_uuid, file_type, datetime.now().isoformat(), file_size)
print(post_data)
return UploadToken.model_validate(post_data)
async def main():
config = uvicorn.Config("main:app", port=5000, host="0.0.0.0", log_level="debug")
+2
View File
@@ -9,6 +9,8 @@ dependencies = [
"dotenv>=0.9.9",
"fastapi>=0.121.1",
"minio>=7.2.20",
"pydantic>=2.12.5",
"python-multipart>=0.0.20",
"redis>=7.1.0",
"uvicorn>=0.38.0",
]
+3 -1
View File
@@ -17,15 +17,17 @@ class RedisWorker:
)
self.files_ttl = int(os.getenv('FILES_TTL'))
def create_record(self, user_ip: str, file_name: str, file_uuid: str, file_type: str, add_date):
def create_record(self, user_ip: str, file_name: str, file_uuid: str, file_type: str, add_date:str, file_size:int):
self.client.hset(file_uuid, mapping={
"file_name": file_name,
"file_size": file_size,
"user_ip": user_ip,
"file_type": file_type,
"add_date": add_date
})
self.client.expire(file_uuid, self.files_ttl)
def get_record(self, file_uuid:str):
return self.client.hgetall(file_uuid)
+2 -3
View File
@@ -2,7 +2,6 @@ import os
import asyncio
from anyio import Condition
from dotenv import load_dotenv
from aiobotocore.session import get_session
@@ -75,9 +74,9 @@ class S3Worker:
ExpiresIn=expires_in,
)
s3_worker = S3Worker()
async def test_run():
async with S3Worker() as worker:
async with s3_worker as worker:
await worker.upload_file("test.txt", b"hello")
file = await worker.download_file("test.txt")
file_text = await file["Body"].read()
+21
View File
@@ -0,0 +1,21 @@
import typing
from pydantic import BaseModel, Field, HttpUrl, PositiveInt
class BaseResponse(BaseModel):
result: typing.Any
error: bool = False
class UploadFields(BaseModel):
content_type: str = Field(alias="Content-Type")
acl: str
key: str
aws_access_key_id: str = Field(alias="AWSAccessKeyId")
policy: str
signature: str
class UploadToken(BaseModel):
url: HttpUrl
fields: UploadFields