Starchik1 commited on
Commit
0b67e3c
·
verified ·
1 Parent(s): 698a44f

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +68 -32
main.py CHANGED
@@ -1,40 +1,76 @@
1
- from fastapi import FastAPI, WebSocket, WebSocketDisconnect
2
- from fastapi.responses import HTMLResponse
3
  import uuid
 
 
 
 
4
 
5
- app = FastAPI()
6
- transfers = {}
7
 
8
- class ConnectionManager:
9
- def __init__(self):
10
- self.active_connections = {}
 
 
11
 
12
- async def connect(self, transfer_id: str, websocket: WebSocket):
13
- await websocket.accept()
14
- if transfer_id not in self.active_connections:
15
- self.active_connections[transfer_id] = []
16
- self.active_connections[transfer_id].append(websocket)
 
 
 
 
17
 
18
- def disconnect(self, transfer_id: str, websocket: WebSocket):
19
- self.active_connections[transfer_id].remove(websocket)
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- manager = ConnectionManager()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- @app.post("/create_transfer")
24
- async def create_transfer():
25
- transfer_id = str(uuid.uuid4())
26
- transfers[transfer_id] = {"status": "waiting"}
27
- return {"transfer_id": transfer_id}
 
 
 
28
 
29
- @app.websocket("/ws/{transfer_id}")
30
- async def websocket_endpoint(websocket: WebSocket, transfer_id: str):
31
- await manager.connect(transfer_id, websocket)
32
- try:
33
- while True:
34
- data = await websocket.receive_bytes()
35
- # Пересылаем данные всем подключенным получателям
36
- for connection in manager.active_connections.get(transfer_id, []):
37
- if connection != websocket:
38
- await connection.send_bytes(data)
39
- except WebSocketDisconnect:
40
- manager.disconnect(transfer_id, websocket)
 
1
+ from flask import Flask, request, jsonify, Response
2
+ from flask_executor import Executor
3
  import uuid
4
+ import time
5
+ import logging
6
+ from collections import defaultdict, deque
7
+ from threading import Lock
8
 
9
+ app = Flask(__name__)
10
+ executor = Executor(app)
11
 
12
+ # Хранилище для передачи чанков
13
+ transfers = defaultdict(deque)
14
+ locks = defaultdict(Lock)
15
+ metadata = {}
16
+ CHUNK_TIMEOUT = 300 # 5 минут
17
 
18
+ @app.route('/create_transfer', methods=['POST'])
19
+ def create_transfer():
20
+ transfer_id = str(uuid.uuid4())
21
+ metadata[transfer_id] = {
22
+ 'filename': request.json.get('filename', 'file'),
23
+ 'created_at': time.time(),
24
+ 'completed': False
25
+ }
26
+ return jsonify({'transfer_id': transfer_id})
27
 
28
+ @app.route('/upload/<transfer_id>', methods=['POST'])
29
+ def upload_chunk(transfer_id):
30
+ if transfer_id not in metadata:
31
+ return jsonify({'error': 'Invalid transfer ID'}), 404
32
+
33
+ with locks[transfer_id]:
34
+ chunk = request.data
35
+ if chunk:
36
+ transfers[transfer_id].append(chunk)
37
+ else:
38
+ metadata[transfer_id]['completed'] = True
39
+
40
+ return jsonify({'status': 'ok'})
41
 
42
+ @app.route('/stream/<transfer_id>')
43
+ def stream_chunks(transfer_id):
44
+ def generate():
45
+ last_activity = time.time()
46
+
47
+ while True:
48
+ with locks[transfer_id]:
49
+ if transfers[transfer_id]:
50
+ chunk = transfers[transfer_id].popleft()
51
+ last_activity = time.time()
52
+ yield chunk
53
+ elif metadata.get(transfer_id, {}).get('completed', False):
54
+ break
55
+ elif time.time() - last_activity > CHUNK_TIMEOUT:
56
+ break
57
+
58
+ time.sleep(0.1) # Задержка для уменьшения нагрузки
59
+
60
+ # Очистка данных
61
+ if transfer_id in metadata:
62
+ del metadata[transfer_id]
63
+ del transfers[transfer_id]
64
+ del locks[transfer_id]
65
 
66
+ return Response(
67
+ generate(),
68
+ mimetype='application/octet-stream',
69
+ headers={
70
+ 'Content-Disposition': f'attachment; filename="{metadata[transfer_id]["filename"]}"',
71
+ 'Transfer-Encoding': 'chunked'
72
+ }
73
+ )
74
 
75
+ if __name__ == '__main__':
76
+ app.run(debug=True)