amaye15 commited on
Commit
c6c0b60
·
1 Parent(s): 2f0453b

Feat - Final Deployment V1

Browse files
Files changed (2) hide show
  1. README.md +96 -1
  2. tests/api.py +91 -12
README.md CHANGED
@@ -12,6 +12,101 @@ python_version: 3.12
12
  port: 7860
13
  ---
14
 
15
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
 
 
12
  port: 7860
13
  ---
14
 
15
+ # AuthenticationApp
16
+
17
+ A secure authentication application with real-time notifications built using FastAPI, SQLite, WebSockets, and modern JavaScript. The app demonstrates full-stack development practices including secure password handling, token-based authentication, and real-time communication.
18
+
19
+ ## Features
20
+
21
+ - 🔐 Secure user registration and login
22
+ - 🔑 Token-based authentication
23
+ - 📲 Real-time notifications via WebSockets
24
+ - 🎨 Modern responsive UI with auto light/dark mode
25
+ - 🐳 Docker containerization
26
+ - 🧪 Load testing utilities
27
+ - 📊 API documentation with Swagger UI
28
+
29
+ ## Live Demo
30
+
31
+ You can access the live demo at:
32
+ [https://amaye15-authenticationapp.hf.space/](https://amaye15-authenticationapp.hf.space/)
33
+
34
+ API documentation is available at:
35
+ [https://amaye15-authenticationapp.hf.space/docs](https://amaye15-authenticationapp.hf.space/docs)
36
+
37
+ ## Installation and Setup
38
+
39
+ ### Local Development Setup
40
+
41
+ 1. Clone the repository:
42
+ ```bash
43
+ git clone https://github.com/yourusername/authenticationapp.git
44
+ cd authenticationapp
45
+ ```
46
+
47
+ 2. Create and activate a virtual environment:
48
+ ```bash
49
+ uv venv --python 3.12
50
+ source venv/bin/activate # On Windows: venv\Scripts\activate
51
+ ```
52
+
53
+ 3. Install dependencies:
54
+ ```bash
55
+ uv pip install -r requirements.txt
56
+ ```
57
+
58
+ ### Using Docker
59
+
60
+ 1. Build the Docker image:
61
+ ```bash
62
+ docker build -t auth-app .
63
+ ```
64
+
65
+ 2. Run the container:
66
+ ```bash
67
+ docker run -p 7860:7860 auth-app
68
+ ```
69
+
70
+ 3. Open your browser and navigate to:
71
+ ```
72
+ http://localhost:7860
73
+ ```
74
+
75
+ ## Testing
76
+
77
+ ### API Testing
78
+
79
+ The application includes a test script (`tests/api.py`) that simulates user registration, login, and basic actions. It also provides load testing capabilities.
80
+
81
+ #### Run Load Tests
82
+
83
+ Local load testing:
84
+ ```bash
85
+ uv run tests/api.py load
86
+ ```
87
+
88
+ Remote load testing (against the deployed app):
89
+ ```bash
90
+ uv run tests/api.py --remote load
91
+ ```
92
+
93
+ ## Security Notes
94
+
95
+ - The app uses bcrypt for password hashing
96
+ - Authentication is handled via signed session tokens
97
+ - A non-root user is used in the Docker container
98
+ - The application includes a healthcheck configuration
99
+
100
+ ## API Documentation
101
+
102
+ Interactive API documentation is available when the app is running:
103
+ - Swagger UI: http://localhost:7860/docs
104
+ - ReDoc: http://localhost:7860/redoc
105
+
106
+ ## License
107
+
108
+ This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
109
+
110
+
111
 
112
 
tests/api.py CHANGED
@@ -1,6 +1,7 @@
1
  import asyncio
2
  import aiohttp
3
  import time
 
4
  from faker import Faker
5
 
6
 
@@ -126,8 +127,7 @@ class AuthClient:
126
  self.token = None
127
 
128
 
129
- # Load testing function
130
- async def load_test(num_users=10, concurrency=5, base_url="https://amaye15-authenticationapp.hf.space/api"):
131
  """
132
  Run a load test with multiple simulated users
133
 
@@ -205,12 +205,8 @@ async def load_test(num_users=10, concurrency=5, base_url="https://amaye15-authe
205
  print(f"Requests per second: {success_count/duration:.2f}")
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()
215
  async with AuthClient(base_url) as client:
216
  # Generate random user data
@@ -242,11 +238,94 @@ async def remote():
242
 
243
  except Exception as e:
244
  print(f"Error: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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())
 
1
  import asyncio
2
  import aiohttp
3
  import time
4
+ import argparse
5
  from faker import Faker
6
 
7
 
 
127
  self.token = None
128
 
129
 
130
+ async def load_test(num_users=10, concurrency=5, base_url="http://localhost:7860/api"):
 
131
  """
132
  Run a load test with multiple simulated users
133
 
 
205
  print(f"Requests per second: {success_count/duration:.2f}")
206
 
207
 
208
+ async def single_user_test(base_url):
209
+ """Run a test with a single user"""
 
 
 
 
210
  fake = Faker()
211
  async with AuthClient(base_url) as client:
212
  # Generate random user data
 
238
 
239
  except Exception as e:
240
  print(f"Error: {e}")
241
+
242
+
243
+ async def custom_user_test(email, password, base_url):
244
+ """Test with specific user credentials"""
245
+ async with AuthClient(base_url) as client:
246
+ try:
247
+ # Try to login first (for existing users)
248
+ print(f"\nAttempting to login with email: {email}...")
249
+ try:
250
+ token_data = await client.login(email, password)
251
+ print(f"Login successful, token: {token_data['access_token'][:10]}...")
252
+ except Exception as e:
253
+ print(f"Login failed: {e}")
254
+
255
+ # If login fails, try to register
256
+ print(f"\nAttempting to register with email: {email}...")
257
+ user = await client.register(email, password)
258
+ print(f"Registered user: {user}")
259
+
260
+ # Now try login again after registration
261
+ print("\nLogging in after registration...")
262
+ token_data = await client.login(email, password)
263
+ print(f"Login successful, token: {token_data['access_token'][:10]}...")
264
+
265
+ # Get current user
266
+ print("\nGetting current user info...")
267
+ user_info = await client.get_current_user()
268
+ print(f"Current user: {user_info}")
269
+
270
+ # Logout
271
+ print("\nLogging out...")
272
+ client.logout()
273
+ print("Logged out successfully")
274
+
275
+ except Exception as e:
276
+ print(f"Error: {e}")
277
+
278
+
279
+ async def main():
280
+ # Define command-line arguments
281
+ parser = argparse.ArgumentParser(description='Authentication API Client CLI')
282
+
283
+ # Main command options
284
+ parser.add_argument('--url', type=str, default="http://localhost:7860/api",
285
+ help='Base URL for the API (default: http://localhost:7860/api)')
286
+ parser.add_argument('--remote', action='store_true',
287
+ help='Use the remote API endpoint')
288
+
289
+ # Create subparsers for different commands
290
+ subparsers = parser.add_subparsers(dest='command', help='Command to execute')
291
+
292
+ # Single user test command
293
+ single_parser = subparsers.add_parser('single', help='Run a test with a single random user')
294
+
295
+ # Load test command
296
+ load_parser = subparsers.add_parser('load', help='Run a load test with multiple users')
297
+ load_parser.add_argument('--users', type=int, default=10,
298
+ help='Number of users to simulate (default: 10)')
299
+ load_parser.add_argument('--concurrency', type=int, default=5,
300
+ help='Maximum number of concurrent users (default: 5)')
301
+
302
+ # Custom user test command
303
+ custom_parser = subparsers.add_parser('custom', help='Test with specific user credentials')
304
+ custom_parser.add_argument('--email', type=str, required=True, help='User email')
305
+ custom_parser.add_argument('--password', type=str, required=True, help='User password')
306
+
307
+ # Parse arguments
308
+ args = parser.parse_args()
309
+
310
+ # Set remote URL if specified
311
+ if args.remote:
312
+ base_url = "https://amaye15-authenticationapp.hf.space/api"
313
+ print(f"Using remote API at: {base_url}")
314
+ else:
315
+ base_url = args.url
316
+ print(f"Using API at: {base_url}")
317
 
318
+ # Execute the appropriate command
319
+ if args.command == 'single':
320
+ await single_user_test(base_url)
321
+ elif args.command == 'load':
322
+ await load_test(args.users, args.concurrency, base_url)
323
+ elif args.command == 'custom':
324
+ await custom_user_test(args.email, args.password, base_url)
325
+ else:
326
+ # If no command specified, show help
327
+ parser.print_help()
328
 
329
 
330
  if __name__ == "__main__":
331
+ asyncio.run(main())