Spaces:
Running
Running
from fastapi import FastAPI, Request | |
from fastapi.responses import JSONResponse | |
import httpx | |
import asyncio | |
import json | |
from datetime import datetime, timedelta | |
app = FastAPI() | |
async def make_request(options): | |
url = f"https://{options['hostname']}{options['path']}" | |
async with httpx.AsyncClient() as client: | |
try: | |
response = await client.get(url, headers=options['headers'], follow_redirects=False) | |
return { | |
'status': response.status_code, | |
'headers': dict(response.headers) | |
} | |
except Exception as e: | |
raise Exception("Failed to fetch asset") | |
async def handler(request: Request): | |
if request.method != 'POST': | |
return JSONResponse( | |
content={"errors":[{"code":0,"message":"MethodNotAllowed"}]}, | |
status_code=405 | |
) | |
try: | |
body = await request.body() | |
requests = json.loads(body) | |
except: | |
return JSONResponse( | |
content={"errors":[{"code":0,"message":"BadRequest"}]}, | |
status_code=400 | |
) | |
if not isinstance(requests, list) or len(requests) > 300: | |
return JSONResponse( | |
content={"errors":[{"code":0,"message":"BadRequest"}]}, | |
status_code=400 | |
) | |
async def process_request(req): | |
options = { | |
'hostname': 'assetdelivery.roblox.com', | |
'path': f"/v1/asset/?assetVersionId={req['assetId']}", | |
'method': 'GET', | |
'headers': { | |
'User-Agent': 'Roblox/WinInet' | |
} | |
} | |
try: | |
response = await make_request(options) | |
return { | |
'requestId': req['requestId'], | |
'location': response['headers'].get('location'), | |
'assetId': response['headers'].get('roblox-assetid'), | |
'assetTypeId': response['headers'].get('roblox-assettypeid') | |
} | |
except: | |
return { | |
'requestId': req['requestId'], | |
'error': "Failed to fetch asset" | |
} | |
results = await asyncio.gather(*[process_request(req) for req in requests]) | |
response = JSONResponse(content=results) | |
# Set custom headers | |
response.headers['access-control-allow-credentials'] = 'true' | |
response.headers['content-type'] = 'application/json' | |
response.headers['date'] = (datetime.utcnow() + timedelta(days=1)).strftime('%a, %d %b %Y %H:%M:%S GMT') | |
response.headers['link'] = '<https://VVBB.co/spaces/coollsd/hippityhoppiti1>;rel="canonical"' | |
response.headers['server'] = 'uvicorn' | |
response.headers['vary'] = 'origin, access-control-request-method, access-control-request-headers' | |
response.headers['x-proxied-host'] = 'http://10.27.201.194' | |
response.headers['x-proxied-path'] = '/' | |
response.headers['x-request-id'] = '9sbie_' | |
# Set content-length after the content has been set | |
response.headers['content-length'] = str(len(response.body)) | |
return response | |
if __name__ == "__main__": | |
import uvicorn | |
uvicorn.run(app, host="0.0.0.0", port=7860) |