Spaces:
Running
Running
Upload 3 files
Browse files- Dockerfile +13 -0
- main.py +119 -0
- requirements.txt +39 -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"]
|
main.py
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import fastapi
|
2 |
+
import enum
|
3 |
+
import numpy
|
4 |
+
import pydantic
|
5 |
+
import typing
|
6 |
+
import jwt
|
7 |
+
import os
|
8 |
+
|
9 |
+
class ModelName(str, enum.Enum):
|
10 |
+
alexnet = "alexnet"
|
11 |
+
resnet = "resnet"
|
12 |
+
lenet = "lenet"
|
13 |
+
|
14 |
+
app = fastapi.FastAPI()
|
15 |
+
|
16 |
+
array = numpy.array(range(1000))
|
17 |
+
|
18 |
+
def check_valid_email(email: str):
|
19 |
+
#initial_query = fastapi.Query(min_length = 3, max_length = 32)
|
20 |
+
if "@" in email:
|
21 |
+
return email
|
22 |
+
raise ValueError("Email is invalid")
|
23 |
+
|
24 |
+
@app.get("/")
|
25 |
+
def index():
|
26 |
+
return {"name" : "First Data"}
|
27 |
+
|
28 |
+
@app.get("/items/{item_id}")
|
29 |
+
async def read_item(item_id: int):
|
30 |
+
return {"item_id": item_id}
|
31 |
+
|
32 |
+
@app.get("/users/me")
|
33 |
+
async def read_user_me():
|
34 |
+
return {"user_id": "the current user"}
|
35 |
+
|
36 |
+
@app.get("/users/{user_id}")
|
37 |
+
async def read_user(user_id: str):
|
38 |
+
return {"user_id": user_id}
|
39 |
+
|
40 |
+
@app.get("/models/{model_name}")
|
41 |
+
async def get_model(model_name: ModelName):
|
42 |
+
if model_name == ModelName.alexnet:
|
43 |
+
return {"model_name": model_name, "message": "Deep Learning FTW!"}
|
44 |
+
if model_name.value == "lenet":
|
45 |
+
return {"model_name": model_name, "message": "LeCNN all the images"}
|
46 |
+
return {"model_name": model_name, "message": "Have some residuals"}
|
47 |
+
|
48 |
+
@app.get("/files/{file_path:path}")
|
49 |
+
async def read_file(file_path: str):
|
50 |
+
return {"file_path": file_path}
|
51 |
+
|
52 |
+
@app.get("/array_at_val")
|
53 |
+
async def get_array(start: int, skip: int = 10):
|
54 |
+
print(array[start : start + skip].tolist())
|
55 |
+
return {"array": array[start : start + skip].tolist()}
|
56 |
+
|
57 |
+
@app.get("/test")
|
58 |
+
async def test(test : bool):
|
59 |
+
return {"test": test}
|
60 |
+
|
61 |
+
@app.get("/c/{channel_owner}/store/{product_id}")
|
62 |
+
async def read_item(channel_owner: str, product_id: int, q: str = None):
|
63 |
+
return {"product_owner": channel_owner, "product_id": product_id, "q": q}
|
64 |
+
|
65 |
+
|
66 |
+
class User(pydantic.BaseModel):
|
67 |
+
username: typing.Annotated[str, fastapi.Query(min_length = 3, max_length = 32)]
|
68 |
+
display_name: str
|
69 |
+
email: typing.Annotated[str, pydantic.AfterValidator(check_valid_email)]
|
70 |
+
|
71 |
+
@app.post("/create_user")
|
72 |
+
async def create_user(user: User):
|
73 |
+
|
74 |
+
return {"user": user}
|
75 |
+
|
76 |
+
@app.get("c/{channel_owner}/followers")
|
77 |
+
async def get_followers(channel_owner: str, limit: typing.Annotated[int, fastapi.Path(title = "The number of followers to retrieve")]):
|
78 |
+
return {"channel_owner": channel_owner, "limit": limit}
|
79 |
+
|
80 |
+
encryption_key = os.getenv("ENCRYPTION_KEY")
|
81 |
+
encryption_algorithm = os.getenv("ENCRYPTION_ALGORITHM")
|
82 |
+
if encryption_key is None:
|
83 |
+
raise ValueError("No ENCRYPTION_KEY set for the application")
|
84 |
+
if encryption_algorithm is None:
|
85 |
+
raise ValueError("No ENCRYPTION_ALGORITHM set for the application")
|
86 |
+
|
87 |
+
|
88 |
+
def encode_data(user: User):
|
89 |
+
payload = {
|
90 |
+
"username": user.username,
|
91 |
+
"display_name": user.display_name,
|
92 |
+
"email": user.email
|
93 |
+
}
|
94 |
+
payload = jwt.encode(payload, encryption_key, algorithm = encryption_algorithm)
|
95 |
+
print(payload)
|
96 |
+
return payload
|
97 |
+
|
98 |
+
def decode_data(token: str):
|
99 |
+
try:
|
100 |
+
payload = jwt.decode(token, encryption_key, algorithms = [encryption_algorithm])
|
101 |
+
print(payload)
|
102 |
+
return payload
|
103 |
+
except jwt.JWTError:
|
104 |
+
return None
|
105 |
+
|
106 |
+
@app.post("/login")
|
107 |
+
async def login(user: User):
|
108 |
+
payload = encode_data(user)
|
109 |
+
print(decode_data(payload))
|
110 |
+
return {"token": payload}
|
111 |
+
|
112 |
+
@app.get("/verify")
|
113 |
+
async def verify(token: str):
|
114 |
+
return decode_data(token)
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
# @app.get("")
|
requirements.txt
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
annotated-types==0.7.0
|
2 |
+
anyio==4.8.0
|
3 |
+
certifi==2025.1.31
|
4 |
+
cffi==1.17.1
|
5 |
+
click==8.1.8
|
6 |
+
cryptography==44.0.2
|
7 |
+
dnspython==2.7.0
|
8 |
+
email_validator==2.2.0
|
9 |
+
fastapi==0.115.11
|
10 |
+
fastapi-cli==0.0.7
|
11 |
+
h11==0.14.0
|
12 |
+
httpcore==1.0.7
|
13 |
+
httptools==0.6.4
|
14 |
+
httpx==0.28.1
|
15 |
+
idna==3.10
|
16 |
+
Jinja2==3.1.5
|
17 |
+
markdown-it-py==3.0.0
|
18 |
+
MarkupSafe==3.0.2
|
19 |
+
mdurl==0.1.2
|
20 |
+
numpy==2.2.3
|
21 |
+
pycparser==2.22
|
22 |
+
pydantic==2.10.6
|
23 |
+
pydantic_core==2.27.2
|
24 |
+
Pygments==2.19.1
|
25 |
+
PyJWT==2.10.1
|
26 |
+
python-dotenv==1.0.1
|
27 |
+
python-multipart==0.0.20
|
28 |
+
PyYAML==6.0.2
|
29 |
+
rich==13.9.4
|
30 |
+
rich-toolkit==0.13.2
|
31 |
+
shellingham==1.5.4
|
32 |
+
sniffio==1.3.1
|
33 |
+
starlette==0.46.0
|
34 |
+
typer==0.15.2
|
35 |
+
typing_extensions==4.12.2
|
36 |
+
uvicorn==0.34.0
|
37 |
+
uvloop==0.21.0
|
38 |
+
watchfiles==1.0.4
|
39 |
+
websockets==15.0
|