coollsd commited on
Commit
498c9ed
1 Parent(s): cec6e17

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -117
app.py CHANGED
@@ -1,23 +1,12 @@
1
- from fastapi import FastAPI, File, UploadFile, Request, HTTPException
2
  from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
3
- from fastapi.middleware.cors import CORSMiddleware
4
  import requests
 
5
  import asyncio
6
  from typing import Dict
7
- import os
8
- import json
9
- import re
10
 
11
  app = FastAPI()
12
 
13
- app.add_middleware(
14
- CORSMiddleware,
15
- allow_origins=["*"],
16
- allow_credentials=True,
17
- allow_methods=["*"],
18
- allow_headers=["*"],
19
- )
20
-
21
  HTML_CONTENT = """
22
  <!DOCTYPE html>
23
  <html lang="en">
@@ -624,90 +613,27 @@ async def index():
624
  return HTML_CONTENT
625
 
626
  @app.post("/upload")
627
- async def handle_upload(request: Request, file: UploadFile = File(...)):
628
- content_range = request.headers.get('Content-Range')
629
- if not content_range:
630
- raise HTTPException(status_code=400, detail="Content-Range header is missing")
631
-
632
- # Parse Content-Range header
633
- content_range_match = re.match(r'bytes (\d+)-(\d+)/(\d+)', content_range)
634
- if not content_range_match:
635
- raise HTTPException(status_code=400, detail="Invalid Content-Range header format")
636
-
637
- start_byte = int(content_range_match.group(1))
638
- end_byte = int(content_range_match.group(2))
639
- total_size = int(content_range_match.group(3))
640
-
641
- if start_byte > end_byte or end_byte >= total_size:
642
- raise HTTPException(status_code=400, detail="Invalid Content-Range header values")
643
-
644
- if not file:
645
- raise HTTPException(status_code=400, detail="No file part")
646
- if file.filename == '':
647
- raise HTTPException(status_code=400, detail="No selected file")
648
-
649
- # Create temporary directory to store the chunks if it doesn't exist
650
- upload_dir = os.path.join('/tmp', 'uploads')
651
- os.makedirs(upload_dir, exist_ok=True)
652
-
653
- # Temporary file path
654
- temp_file_path = os.path.join(upload_dir, file.filename)
655
-
656
- # Path to store upload metadata
657
- meta_file_path = temp_file_path + '.json'
658
-
659
- if start_byte == 0:
660
- # Start of a new upload
661
- cookies = await get_cookies()
662
- if 'csrftoken' not in cookies or 'sessionid' not in cookies:
663
- raise HTTPException(status_code=500, detail="Failed to obtain necessary cookies")
664
-
665
- # Initiate the upload
666
- upload_result = await initiate_upload(cookies, file.filename, file.content_type)
667
- if not upload_result or 'upload_url' not in upload_result:
668
- raise HTTPException(status_code=500, detail="Failed to initiate upload")
669
-
670
- # Save the upload_url and serving_url to a metadata file
671
- with open(meta_file_path, 'w') as meta_file:
672
- json.dump(upload_result, meta_file)
673
- else:
674
- # For subsequent chunks, read the metadata file to get upload_url and serving_url
675
- if not os.path.exists(meta_file_path):
676
- raise HTTPException(status_code=400, detail="Upload metadata not found")
677
- with open(meta_file_path, 'r') as meta_file:
678
- upload_result = json.load(meta_file)
679
-
680
- # Read the chunk content
681
  file_content = await file.read()
 
 
 
682
 
683
- # Write the chunk to the temporary file at the correct offset
684
- with open(temp_file_path, 'ab') as f:
685
- f.seek(start_byte)
686
- f.write(file_content)
687
-
688
- # Check if the upload is complete
689
- file_size = os.path.getsize(temp_file_path)
690
- if file_size == total_size:
691
- # Read the entire file content
692
- with open(temp_file_path, 'rb') as f:
693
- full_file_content = f.read()
694
-
695
- # Upload the file to Replicate
696
- upload_success = await retry_upload(upload_result['upload_url'], full_file_content, file.content_type)
697
- if not upload_success:
698
- raise HTTPException(status_code=500, detail="Failed to upload file to Replicate")
699
-
700
- original_url = upload_result.get('serving_url')
701
- if original_url:
702
- mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
703
- # Clean up the temporary files
704
- os.remove(temp_file_path)
705
- os.remove(meta_file_path)
706
- return JSONResponse(content={"url": mirrored_url})
707
- else:
708
- raise HTTPException(status_code=500, detail="serving_url not found")
709
- else:
710
- return JSONResponse(content={"status": "chunk uploaded"})
711
 
712
  @app.get("/rbxg/{path:path}")
713
  async def handle_video_stream(path: str, request: Request):
@@ -774,7 +700,7 @@ async def embed_video(url: str, thumbnail: str):
774
  async def get_cookies() -> Dict[str, str]:
775
  try:
776
  response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
777
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
778
  })
779
  return dict(response.cookies)
780
  except Exception as e:
@@ -784,9 +710,9 @@ async def get_cookies() -> Dict[str, str]:
784
  async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
785
  url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
786
  try:
787
- headers = {
788
  'X-CSRFToken': cookies.get('csrftoken'),
789
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
790
  'Referer': 'https://replicate.com/levelsio/neon-tokyo',
791
  'Origin': 'https://replicate.com',
792
  'Accept': '*/*',
@@ -794,9 +720,10 @@ async def initiate_upload(cookies: Dict[str, str], filename: str, content_type:
794
  'Accept-Encoding': 'identity',
795
  'Sec-Fetch-Dest': 'empty',
796
  'Sec-Fetch-Mode': 'cors',
797
- 'Sec-Fetch-Site': 'same-origin'
798
- }
799
- response = requests.post(url, cookies=cookies, headers=headers)
 
800
  return response.json()
801
  except Exception as e:
802
  print(f'Error initiating upload: {e}')
@@ -804,24 +731,23 @@ async def initiate_upload(cookies: Dict[str, str], filename: str, content_type:
804
 
805
  async def upload_file(upload_url: str, file_content: bytes, content_type: str) -> bool:
806
  try:
807
- headers = {
808
- 'Content-Type': content_type
809
- }
810
- response = requests.put(upload_url, data=file_content, headers=headers)
811
- return response.status_code in [200, 201, 204]
812
  except Exception as e:
813
  print(f'Error uploading file: {e}')
814
  return False
815
 
816
  async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
817
- retries = 0
818
- while retries < max_retries:
819
- success = await upload_file(upload_url, file_content, content_type)
820
- if success:
821
- return True
822
- else:
823
- print(f"Upload attempt {retries + 1} failed. Retrying...")
824
- retries += 1
825
- await asyncio.sleep(delay)
826
- delay = min(delay * 2, 60) # Exponential backoff
827
- return False
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Request
2
  from fastapi.responses import HTMLResponse, JSONResponse, StreamingResponse
 
3
  import requests
4
+ import time
5
  import asyncio
6
  from typing import Dict
 
 
 
7
 
8
  app = FastAPI()
9
 
 
 
 
 
 
 
 
 
10
  HTML_CONTENT = """
11
  <!DOCTYPE html>
12
  <html lang="en">
 
613
  return HTML_CONTENT
614
 
615
  @app.post("/upload")
616
+ async def handle_upload(file: UploadFile = File(...)):
617
+ if not file.filename:
618
+ return JSONResponse(content={"error": "No file selected."}, status_code=400)
619
+
620
+ cookies = await get_cookies()
621
+ if 'csrftoken' not in cookies or 'sessionid' not in cookies:
622
+ return JSONResponse(content={"error": "Failed to obtain necessary cookies"}, status_code=500)
623
+
624
+ upload_result = await initiate_upload(cookies, file.filename, file.content_type)
625
+ if not upload_result or 'upload_url' not in upload_result:
626
+ return JSONResponse(content={"error": "Failed to initiate upload"}, status_code=500)
627
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
  file_content = await file.read()
629
+ upload_success = await retry_upload(upload_result['upload_url'], file_content, file.content_type)
630
+ if not upload_success:
631
+ return JSONResponse(content={"error": "File upload failed after multiple attempts"}, status_code=500)
632
 
633
+ original_url = upload_result['serving_url']
634
+ mirrored_url = f"/rbxg/{original_url.split('/pbxt/')[1]}"
635
+
636
+ return JSONResponse(content={"url": mirrored_url})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
 
638
  @app.get("/rbxg/{path:path}")
639
  async def handle_video_stream(path: str, request: Request):
 
700
  async def get_cookies() -> Dict[str, str]:
701
  try:
702
  response = requests.get('https://replicate.com/levelsio/neon-tokyo', headers={
703
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
704
  })
705
  return dict(response.cookies)
706
  except Exception as e:
 
710
  async def initiate_upload(cookies: Dict[str, str], filename: str, content_type: str) -> Dict:
711
  url = f'https://replicate.com/api/upload/{filename}?content_type={content_type}'
712
  try:
713
+ response = requests.post(url, cookies=cookies, headers={
714
  'X-CSRFToken': cookies.get('csrftoken'),
715
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
716
  'Referer': 'https://replicate.com/levelsio/neon-tokyo',
717
  'Origin': 'https://replicate.com',
718
  'Accept': '*/*',
 
720
  'Accept-Encoding': 'identity',
721
  'Sec-Fetch-Dest': 'empty',
722
  'Sec-Fetch-Mode': 'cors',
723
+ 'Sec-Fetch-Site': 'same-origin',
724
+ 'Sec-GPC': '1',
725
+ 'Priority': 'u=1, i'
726
+ })
727
  return response.json()
728
  except Exception as e:
729
  print(f'Error initiating upload: {e}')
 
731
 
732
  async def upload_file(upload_url: str, file_content: bytes, content_type: str) -> bool:
733
  try:
734
+ response = requests.put(upload_url, data=file_content, headers={'Content-Type': content_type})
735
+ return response.status_code == 200
 
 
 
736
  except Exception as e:
737
  print(f'Error uploading file: {e}')
738
  return False
739
 
740
  async def retry_upload(upload_url: str, file_content: bytes, content_type: str, max_retries: int = 5, delay: int = 1) -> bool:
741
+ while True:
742
+ try:
743
+ success = await upload_file(upload_url, file_content, content_type)
744
+ if success:
745
+ return True
746
+ print("Upload failed. Retrying...")
747
+ except Exception as e:
748
+ print(f"Error during upload: {e}")
749
+
750
+ await asyncio.sleep(delay)
751
+ delay = min(delay * 2, 60) # Exponential backoff, capped at 60 seconds
752
+
753
+ return False