from fastapi import FastAPI, Request import httpx import asyncio import json 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") @app.post("/v1/assets/batch") async def handler(request: Request): if request.method != 'POST': return {"errors":[{"code":0,"message":"MethodNotAllowed"}]} try: body = await request.body() requests = json.loads(body) except: return {"errors":[{"code":0,"message":"BadRequest"}]} if not isinstance(requests, list) or len(requests) > 300: return {"errors":[{"code":0,"message":"BadRequest"}]} 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]) return results if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=7860)