Spaces:
Sleeping
Sleeping
Create main.py
Browse files
main.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI, HTTPException, Query, Request
|
| 2 |
+
from pydantic import BaseModel
|
| 3 |
+
from typing import Optional, Dict, List, Any
|
| 4 |
+
import asyncio
|
| 5 |
+
import logging
|
| 6 |
+
|
| 7 |
+
# Hardcoded cookies (from your request)
|
| 8 |
+
COOKIES = {
|
| 9 |
+
'pplx.visitor-id': '712960de-28ad-41c8-939f-480b703c70ee',
|
| 10 |
+
'g_state': '{"i_l":0,"i_ll":1769717814738,"i_b":"gBcJjnhJuupOuCDdBabINoIsf6604w/8Gi6OD0DxmLc","i_e":{"enable_itp_optimization":3}}',
|
| 11 |
+
'__ps_r': '_',
|
| 12 |
+
'__ps_lu': 'https://www.perplexity.ai/onboarding?redirect=https%3A%2F%2Fwww.perplexity.ai%2F%3Flogin-source%3DfloatingSignup%26login-new%3Dtrue%23locale%3Den-US ',
|
| 13 |
+
'__ps_fva': '1769717851792',
|
| 14 |
+
'_gcl_au': '1.1.840583653.1769717852',
|
| 15 |
+
'_fbp': 'fb.1.1769717851924.246154841382399244',
|
| 16 |
+
'sidebar-upgrade-badge-30day': '5',
|
| 17 |
+
'__cf_bm': '_nGeJEhOfX9PTCcj8gB6XslTISyXhlE94.i9d0WODBM-1770115842-1.0.1.1-AMoVeKAfZpiY1Ev9KP1TYcabA.zmHBKxvS6jbCw7jLmtg0u.3fS8Ra8NhXYbzdGKVjcFOUXeDvXg40vu3OXZxqHfrKSHnTjbjr_23NhYN14',
|
| 18 |
+
'__cflb': '02DiuDyvFMmK5p9jVbVnMNSKYZhUL9aGmrTbYPN5s7xRA',
|
| 19 |
+
'pplx.session-id': '9934273c-4f6b-4f7f-b092-75681a0100fd',
|
| 20 |
+
'cf_clearance': 'MvVM3iTW57M3un0OPJ1lE92Z9VUadUjxdF1HFsTnH3Y-1770115847-1.2.1.1-.ZPX_G0dgDxzAaxifqqmcT.aWc6ck916zGTYOHhvqWZA8KdJbCwveBFkJh57NRIpsHIZ.ZWN3FQRQ4dNq.j6K6c0mcqDtoBs5ihuLwM_dw8kQr7Rdox99PlTpCZTv3cH8hIVfZpmvGToLBlk8t5pyGjTD0MOoG8GTWoM0xZzcTfVA4Pm_6m67NJp7nZmzftoxmyELzXrZrK8uoJpIQ06T7aslgbbA4RAHVgNWx6pwFk',
|
| 21 |
+
'__ps_sr': '_',
|
| 22 |
+
'__ps_slu': 'https://www.perplexity.ai/search/hi-Km1fNgiUTIiQBPHPXPPDRw ',
|
| 23 |
+
'_dd_s': 'aid=b3cdfc91-8ae5-42ca-8313-fd3464265b7c&rum=2&id=3d5d5ff2-38b9-4dd1-987f-dd4348eb1093&created=1770115845969&expire=1770116989591&logs=0',
|
| 24 |
+
'pplx.metadata': '{%22qc%22:4%2C%22qcu%22:3%2C%22qcm%22:0%2C%22qcc%22:0%2C%22qcco%22:0%2C%22qccol%22:0%2C%22qcdr%22:0%2C%22qcs%22:0%2C%22qcd%22:0%2C%22hli%22:true%2C%22hcga%22:false%2C%22hcds%22:false%2C%22hso%22:true%2C%22hfo%22:true%2C%22hsco%22:false%2C%22hfco%22:false%2C%22hsma%22:false%2C%22hdc%22:false%2C%22hdttb%22:false%2C%22fqa%22:1769717863030%2C%22lqa%22:1770115870300}',
|
| 25 |
+
'__Secure-next-auth.session-token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..envLMas9-Txsy_I6.6Di02enfpLyp0SqjvIqvOjeBrAh-Ua7OT95mPaC_Bm4hU-CLu9vf6xGEhwgcOFiwPkPIAXEYcZ7iAEaqiHlL7tf6RPHo17bICsuOApRNkP5f9C4o_bRG4ZApfDmNq9iYpoadgkojzEiFEy9XdGG_-fjMMdevzQ_LQNPb-URfJwmXWrUtPB2durHzvRJkjPmrndyHih7ljDKWfQMSszxz9LIkEjR4QyPGntrXHYCyStIC_qg13RFPLR10SZyptDKLiWM.OlKoZQWB0wzsIODRxV28fA',
|
| 26 |
+
'_rdt_uuid': '1769717851824.81056fd1-32a5-4a91-b6e8-9bc24110b278',
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
EXPECTED_API_KEY = "11223344"
|
| 30 |
+
|
| 31 |
+
app = FastAPI(title="Perplexity AI Proxy", version="1.0")
|
| 32 |
+
|
| 33 |
+
logging.basicConfig(level=logging.INFO)
|
| 34 |
+
|
| 35 |
+
class SearchRequest(BaseModel):
|
| 36 |
+
query: str
|
| 37 |
+
mode: str = "auto"
|
| 38 |
+
model: Optional[str] = None
|
| 39 |
+
sources: List[str] = ["web"]
|
| 40 |
+
language: str = "en-US"
|
| 41 |
+
incognito: bool = False
|
| 42 |
+
|
| 43 |
+
@app.post("/search")
|
| 44 |
+
async def search_post(request: Request, body: SearchRequest):
|
| 45 |
+
api_key = request.headers.get("x-api-key")
|
| 46 |
+
if api_key != EXPECTED_API_KEY:
|
| 47 |
+
raise HTTPException(status_code=401, detail="Invalid API key")
|
| 48 |
+
|
| 49 |
+
try:
|
| 50 |
+
# Import AFTER installation (now available as local editable package)
|
| 51 |
+
import perplexity_async
|
| 52 |
+
client = await perplexity_async.Client(cookies=COOKIES)
|
| 53 |
+
resp = await client.search(
|
| 54 |
+
query=body.query,
|
| 55 |
+
mode=body.mode,
|
| 56 |
+
model=body.model,
|
| 57 |
+
sources=body.sources,
|
| 58 |
+
files={},
|
| 59 |
+
stream=False,
|
| 60 |
+
language=body.language,
|
| 61 |
+
follow_up=None,
|
| 62 |
+
incognito=body.incognito
|
| 63 |
+
)
|
| 64 |
+
return {"success": True, "response": resp}
|
| 65 |
+
except Exception as e:
|
| 66 |
+
logging.error(f"Error: {e}")
|
| 67 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 68 |
+
|
| 69 |
+
@app.get("/search")
|
| 70 |
+
async def search_get(
|
| 71 |
+
request: Request,
|
| 72 |
+
q: str = Query(..., description="Question"),
|
| 73 |
+
api_key: Optional[str] = None,
|
| 74 |
+
mode: str = "auto",
|
| 75 |
+
model: Optional[str] = None,
|
| 76 |
+
sources: str = "web",
|
| 77 |
+
language: str = "en-US",
|
| 78 |
+
incognito: bool = False
|
| 79 |
+
):
|
| 80 |
+
key = request.headers.get("x-api-key") or api_key
|
| 81 |
+
if key != EXPECTED_API_KEY:
|
| 82 |
+
raise HTTPException(status_code=401, detail="Invalid API key")
|
| 83 |
+
|
| 84 |
+
try:
|
| 85 |
+
import perplexity_async
|
| 86 |
+
client = await perplexity_async.Client(cookies=COOKIES)
|
| 87 |
+
sources_list = [s.strip() for s in sources.split(",")] if sources else ["web"]
|
| 88 |
+
resp = await client.search(
|
| 89 |
+
query=q,
|
| 90 |
+
mode=mode,
|
| 91 |
+
model=model,
|
| 92 |
+
sources=sources_list,
|
| 93 |
+
files={},
|
| 94 |
+
stream=False,
|
| 95 |
+
language=language,
|
| 96 |
+
follow_up=None,
|
| 97 |
+
incognito=incognito
|
| 98 |
+
)
|
| 99 |
+
return {"success": True, "response": resp}
|
| 100 |
+
except Exception as e:
|
| 101 |
+
logging.error(f"Error: {e}")
|
| 102 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 103 |
+
|
| 104 |
+
@app.get("/health")
|
| 105 |
+
async def health():
|
| 106 |
+
return {"status": "ok"}
|