amaye15 commited on
Commit
2f0453b
·
1 Parent(s): d576ad8
Files changed (4) hide show
  1. Dockerfile +0 -21
  2. app/main.py +16 -16
  3. requirements.txt +3 -1
  4. tests/api.py +4 -157
Dockerfile CHANGED
@@ -1,24 +1,3 @@
1
- # # Use an official Python runtime as a parent image
2
- # FROM python:3.12-slim
3
-
4
- # WORKDIR /code
5
-
6
- # COPY ./requirements.txt /code/requirements.txt
7
-
8
- # RUN pip install --no-cache-dir --upgrade pip && \
9
- # pip install --no-cache-dir -r requirements.txt
10
-
11
- # # Copy application code
12
- # COPY ./app /code/app
13
- # # Copy static files and templates
14
- # COPY ./static /code/static
15
- # COPY ./templates /code/templates
16
-
17
- # EXPOSE 7860
18
-
19
- # # Command to run the FastAPI application
20
- # CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
21
-
22
  # Use an official Python runtime as a parent image
23
  FROM python:3.12-slim as builder
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # Use an official Python runtime as a parent image
2
  FROM python:3.12-slim as builder
3
 
app/main.py CHANGED
@@ -6,10 +6,8 @@ from fastapi.responses import HTMLResponse
6
  from fastapi.staticfiles import StaticFiles
7
 
8
  from .database import connect_db, disconnect_db, database, users
9
- from .api import router as api_router
10
 
11
- from sqlalchemy.schema import CreateTable
12
- from sqlalchemy.dialects import sqlite
13
 
14
  # Configure logging
15
  logging.basicConfig(level=logging.INFO)
@@ -22,19 +20,16 @@ async def lifespan(app: FastAPI):
22
  logger.info("Application startup: DB Connected. Checking/Creating tables...")
23
  if database.is_connected:
24
  try:
25
- check_query = "SELECT name FROM sqlite_master WHERE type='table' AND name=:table_name;"
26
- table_exists = await database.fetch_one(query=check_query, values={"table_name": users.name})
27
- if not table_exists:
28
- logger.info(f"Table '{users.name}' not found, creating...")
29
- dialect = sqlite.dialect()
30
- create_table_stmt = str(CreateTable(users).compile(dialect=dialect))
31
- await database.execute(query=create_table_stmt)
32
- logger.info(f"Table '{users.name}' created.")
33
- table_exists_after = await database.fetch_one(query=check_query, values={"table_name": users.name})
34
- if table_exists_after: logger.info(f"Table '{users.name}' verified.")
35
- else: logger.error(f"Table '{users.name}' verification FAILED!")
36
- else:
37
- logger.info(f"Table '{users.name}' already exists.")
38
  except Exception as db_setup_err:
39
  logger.exception(f"CRITICAL error during async DB table setup: {db_setup_err}")
40
  else:
@@ -63,6 +58,11 @@ async def read_root(request: Request):
63
  logger.error("templates/index.html not found!")
64
  return HTMLResponse(content="<html><body><h1>Error: Frontend not found</h1></body></html>", status_code=500)
65
 
 
 
 
 
 
66
  if __name__ == "__main__":
67
  import uvicorn
68
  uvicorn.run("app.main:app", host="0.0.0.0", port=7860, reload=True)
 
6
  from fastapi.staticfiles import StaticFiles
7
 
8
  from .database import connect_db, disconnect_db, database, users
 
9
 
10
+ from .api import router as api_router
 
11
 
12
  # Configure logging
13
  logging.basicConfig(level=logging.INFO)
 
20
  logger.info("Application startup: DB Connected. Checking/Creating tables...")
21
  if database.is_connected:
22
  try:
23
+ # Use CREATE TABLE IF NOT EXISTS to avoid race conditions with multiple workers
24
+ create_table_query = f"""
25
+ CREATE TABLE IF NOT EXISTS {users.name} (
26
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
27
+ email VARCHAR UNIQUE NOT NULL,
28
+ hashed_password VARCHAR NOT NULL
29
+ )
30
+ """
31
+ await database.execute(query=create_table_query)
32
+ logger.info(f"Table '{users.name}' exists or was created.")
 
 
 
33
  except Exception as db_setup_err:
34
  logger.exception(f"CRITICAL error during async DB table setup: {db_setup_err}")
35
  else:
 
58
  logger.error("templates/index.html not found!")
59
  return HTMLResponse(content="<html><body><h1>Error: Frontend not found</h1></body></html>", status_code=500)
60
 
61
+ @app.get("/health", status_code=200)
62
+ async def health_check():
63
+ """Health check endpoint for container health monitoring"""
64
+ return {"status": "ok"}
65
+
66
  if __name__ == "__main__":
67
  import uvicorn
68
  uvicorn.run("app.main:app", host="0.0.0.0", port=7860, reload=True)
requirements.txt CHANGED
@@ -10,4 +10,6 @@ python-multipart==0.0.9
10
  itsdangerous==2.1.2
11
  websockets>=11.0.3,<13.0
12
  aiofiles==23.2.1
13
- httpx==0.27.0
 
 
 
10
  itsdangerous==2.1.2
11
  websockets>=11.0.3,<13.0
12
  aiofiles==23.2.1
13
+ httpx==0.27.0
14
+ aiohttp==3.9.3
15
+ Faker==22.2.0
tests/api.py CHANGED
@@ -1,156 +1,3 @@
1
- # import requests
2
- # import time
3
- # from faker import Faker
4
-
5
-
6
- # class AuthClient:
7
- # """
8
- # Python client for interacting with the Authentication API
9
- # """
10
-
11
- # def __init__(self, base_url="http://localhost:7860/api"):
12
- # """
13
- # Initialize the client with the API base URL
14
-
15
- # Args:
16
- # base_url (str): The base URL of the API
17
- # """
18
- # self.base_url = base_url
19
- # self.token = None
20
-
21
- # def register(self, email, password):
22
- # """
23
- # Register a new user
24
-
25
- # Args:
26
- # email (str): User's email
27
- # password (str): User's password (should be at least 8 characters)
28
-
29
- # Returns:
30
- # dict: The user data returned by the API
31
-
32
- # Raises:
33
- # Exception: If registration fails
34
- # """
35
- # url = f"{self.base_url}/register"
36
- # data = {
37
- # "email": email,
38
- # "password": password
39
- # }
40
-
41
- # response = requests.post(url, json=data)
42
-
43
- # if response.status_code == 201:
44
- # return response.json()
45
- # else:
46
- # error_detail = response.json().get("detail", "Unknown error")
47
- # raise Exception(f"Registration failed: {error_detail} (Status: {response.status_code})")
48
-
49
- # def login(self, email, password):
50
- # """
51
- # Login to obtain an authentication token
52
-
53
- # Args:
54
- # email (str): User's email
55
- # password (str): User's password
56
-
57
- # Returns:
58
- # dict: The token data returned by the API
59
-
60
- # Raises:
61
- # Exception: If login fails
62
- # """
63
- # url = f"{self.base_url}/login"
64
- # data = {
65
- # "email": email,
66
- # "password": password
67
- # }
68
-
69
- # response = requests.post(url, json=data)
70
-
71
- # if response.status_code == 200:
72
- # token_data = response.json()
73
- # self.token = token_data["access_token"]
74
- # return token_data
75
- # else:
76
- # error_detail = response.json().get("detail", "Unknown error")
77
- # raise Exception(f"Login failed: {error_detail} (Status: {response.status_code})")
78
-
79
- # def get_current_user(self):
80
- # """
81
- # Get information about the current logged-in user
82
-
83
- # Returns:
84
- # dict: The user data returned by the API
85
-
86
- # Raises:
87
- # Exception: If not authenticated or request fails
88
- # """
89
- # if not self.token:
90
- # raise Exception("Not authenticated. Please login first.")
91
-
92
- # url = f"{self.base_url}/users/me"
93
- # headers = {"Authorization": f"Bearer {self.token}"}
94
-
95
- # response = requests.get(url, headers=headers)
96
-
97
- # if response.status_code == 200:
98
- # return response.json()
99
- # else:
100
- # error_detail = response.json().get("detail", "Unknown error")
101
- # raise Exception(f"Failed to get user info: {error_detail} (Status: {response.status_code})")
102
-
103
- # def logout(self):
104
- # """Clear the authentication token"""
105
- # self.token = None
106
-
107
-
108
- # # Example usage
109
- # def main():
110
- # # Initialize the client
111
- # client = AuthClient("https://amaye15-authenticationapp.hf.space/api")
112
-
113
- # # Initialize Faker
114
- # fake = Faker()
115
-
116
- # for i in range(10):
117
- # try:
118
- # # Generate random user data
119
- # first_name = fake.first_name()
120
- # last_name = fake.last_name()
121
- # email = fake.email()
122
- # password = fake.password(length=12, special_chars=True, digits=True, upper_case=True, lower_case=True)
123
-
124
- # # Register a new user
125
- # print(f"Registering a new user: {first_name} {last_name}...")
126
- # try:
127
- # user = client.register(email, password)
128
- # print(f"Registered user: {user}")
129
- # except Exception as e:
130
- # print(f"Registration failed: {e}")
131
-
132
- # # Login
133
- # print("\nLogging in...")
134
- # token_data = client.login(email, password)
135
- # print(f"Login successful, token: {token_data['access_token'][:10]}...")
136
-
137
- # # Get current user
138
- # print("\nGetting current user info...")
139
- # user_info = client.get_current_user()
140
- # print(f"Current user: {user_info}")
141
-
142
- # # Logout
143
- # print("\nLogging out...")
144
- # client.logout()
145
- # print("Logged out successfully")
146
-
147
- # except Exception as e:
148
- # print(f"Error: {e}")
149
-
150
-
151
- # if __name__ == "__main__":
152
- # main()
153
-
154
  import asyncio
155
  import aiohttp
156
  import time
@@ -359,9 +206,9 @@ async def load_test(num_users=10, concurrency=5, base_url="https://amaye15-authe
359
 
360
 
361
  # Example usage
362
- async def main():
363
  # Initialize the client
364
- base_url = "https://amaye15-authenticationapp.hf.space/api"
365
 
366
  # Run a simple example with a single user
367
  fake = Faker()
@@ -398,8 +245,8 @@ async def main():
398
 
399
  # Run a load test
400
  print("\nRunning load test...")
401
- await load_test(10, 5, base_url)
402
 
403
 
404
  if __name__ == "__main__":
405
- asyncio.run(main())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import asyncio
2
  import aiohttp
3
  import time
 
206
 
207
 
208
  # Example usage
209
+ async def remote():
210
  # Initialize the client
211
+ base_url = "http://localhost:7860/api"
212
 
213
  # Run a simple example with a single user
214
  fake = Faker()
 
245
 
246
  # Run a load test
247
  print("\nRunning load test...")
248
+ await load_test(100, 10, base_url)
249
 
250
 
251
  if __name__ == "__main__":
252
+ asyncio.run(remote())