nothere990 commited on
Commit
950d6aa
·
1 Parent(s): 5c939f6

yo first release

Browse files
Files changed (3) hide show
  1. Dockerfile +13 -0
  2. app.py +153 -0
  3. requirements.txt +7 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException, Depends
2
+ from pydantic import BaseModel
3
+ from itertools import islice
4
+ from typing import Dict, Any, Optional
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from xnxx_api import search_filters
7
+ from xnxx_api.xnxx_api import Client as xnxx_client
8
+
9
+ # Constants
10
+ CREATOR = "EyePatch"
11
+ API_VERSION = "1.3.0"
12
+
13
+ # ----- Pydantic Models -----
14
+ class SuccessResponse(BaseModel):
15
+ creator: str = CREATOR
16
+ status: str = "success"
17
+ api_version: str = API_VERSION
18
+ data: Dict[str, Any]
19
+
20
+ class ErrorResponse(BaseModel):
21
+ status: str = "error"
22
+ creator: str = CREATOR
23
+ api_version: str = API_VERSION
24
+ error_code: int
25
+ message: str
26
+
27
+ class ItemPayload(BaseModel):
28
+ name: str
29
+ description: Optional[str] = None
30
+ price: float
31
+ tags: list[str] = []
32
+
33
+ # ----- FastAPI Setup -----
34
+ app = FastAPI(title="Awesome API", version=API_VERSION)
35
+
36
+ # CORS Configuration
37
+ app.add_middleware(
38
+ CORSMiddleware,
39
+ allow_origins=["*"],
40
+ allow_methods=["*"],
41
+ allow_headers=["*"],
42
+ )
43
+
44
+ # ----- Helper Functions -----
45
+ async def get_api_version():
46
+ return API_VERSION
47
+
48
+ # ----- API Endpoints -----
49
+ @app.get("/", response_model=SuccessResponse)
50
+ async def root(version: str = Depends(get_api_version)):
51
+ """Service health check endpoint"""
52
+ return SuccessResponse(data={
53
+ "message": "Service operational",
54
+ })
55
+
56
+ @app.get("/prono/xnxxsearch", response_model=SuccessResponse)
57
+ async def xnxx_search(
58
+ query: str,
59
+ quality: Optional[str] = None,
60
+ upload_time: Optional[str] = None,
61
+ length: Optional[str] = None,
62
+ mode: Optional[str] = None,
63
+ page: Optional[int] = None,
64
+ results: Optional[int] = 20
65
+ ):
66
+ data_dict = {
67
+ "quality": {
68
+ "720p": search_filters.SearchingQuality.X_720p,
69
+ "1080p": search_filters.SearchingQuality.X_1080p_plus
70
+ },
71
+ "upload_time": {
72
+ "year": search_filters.UploadTime.year,
73
+ "month": search_filters.UploadTime.month
74
+ },
75
+ "length": {
76
+ "0-10min": search_filters.Length.X_0_10min,
77
+ "10min+": search_filters.Length.X_10min_plus,
78
+ "10-20min": search_filters.Length.X_10_20min,
79
+ "20min+": search_filters.Length.X_20min_plus
80
+ },
81
+ "mode": {
82
+ "default": search_filters.Mode.default,
83
+ "hits": search_filters.Mode.hits,
84
+ "random": search_filters.Mode.random
85
+ }
86
+ }
87
+
88
+ try:
89
+ # Prepare search parameters
90
+ search_kwargs = {
91
+ "query": query
92
+ }
93
+ if length is not None:
94
+ search_kwargs["length"] = data_dict["length"][length]
95
+
96
+ if quality is not None:
97
+ search_kwargs["searching_quality"] = data_dict["quality"][quality]
98
+
99
+ if upload_time is not None:
100
+ search_kwargs["upload_time"] = data_dict["upload_time"][upload_time]
101
+
102
+ if mode is not None:
103
+ search_kwargs["mode"] = data_dict["mode"][mode]
104
+
105
+ if page is not None:
106
+ search_kwargs["limit"] = page
107
+
108
+ # Perform the search with only the provided parameters
109
+ search = xnxx_client().search(**search_kwargs)
110
+ res = search.videos
111
+ if results is not None:
112
+ response = islice(res, results)
113
+
114
+ results_list = []
115
+ for x in response:
116
+ results_list.append({
117
+ "title": x.title,
118
+ "url": x.url,
119
+ "author": x.author,
120
+ "length": x.length,
121
+ "highest_quality": x.highest_quality,
122
+ "publish_date": x.publish_date,
123
+ "views": x.views,
124
+ "thumb": x.thumbnail_url[0] if isinstance(x.thumbnail_url, list) and len(x.thumbnail_url) > 0 else None
125
+ })
126
+ return SuccessResponse(
127
+ status="True",
128
+ randydev={
129
+ "results": results_list
130
+ }
131
+ )
132
+ except Exception as e:
133
+ return SuccessResponse(
134
+ status="False",
135
+ randydev={"error": f"Error: {e}"}
136
+ )
137
+
138
+ @app.get("/protected", responses={
139
+ 200: {"model": SuccessResponse},
140
+ 403: {"model": ErrorResponse}
141
+ })
142
+ async def protected_route(secret_key: Optional[str] = None):
143
+ """Endpoint demonstrating error responses"""
144
+ if not secret_key or secret_key != "supersecret123":
145
+ return ErrorResponse(
146
+ error_code=403,
147
+ message="Invalid or missing secret key"
148
+ )
149
+
150
+ return SuccessResponse(data={
151
+ "secret_data": "🔐 You've unlocked premium content!",
152
+ "access_level": "VIP"
153
+ })
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ httpx>=0.28.1
4
+ GitPython
5
+ phub
6
+ xnxx_api
7
+ xvideos_api