sameerbanchhor commited on
Commit
438ec1c
·
verified ·
1 Parent(s): 693ef3f

Upload folder using huggingface_hub

Browse files
.gitignore CHANGED
@@ -2,4 +2,10 @@
2
  prompt.txt
3
 
4
  #cache
5
- __pycache__
 
 
 
 
 
 
 
2
  prompt.txt
3
 
4
  #cache
5
+ __pycache__
6
+
7
+ # documentations
8
+ llm_documentation.md
9
+
10
+ # enironment variable
11
+ .env
app/main.py CHANGED
@@ -1,11 +1,25 @@
1
  from fastapi import FastAPI
2
  from fastapi.responses import HTMLResponse
3
 
 
 
 
 
 
4
  # ==========================
5
  # 📌 Image Module
6
  # ==========================
7
  from app.routers.image import jpgcompressor
8
 
 
 
 
 
 
 
 
 
 
9
 
10
  # ==========================
11
  # 🧪 Test Utilities
@@ -13,7 +27,7 @@ from app.routers.image import jpgcompressor
13
  from app.routers.testers import random_number_generator
14
  from app.routers.testers import help
15
  from app.routers.testers import calculator
16
-
17
 
18
  # ==========================
19
  # 🚀 App Initialization
@@ -24,10 +38,15 @@ app = FastAPI()
24
  # ==========================
25
  # 🔗 Router Registration
26
  # ==========================
 
27
  app.include_router(jpgcompressor.router) # Image compression handler
 
28
  app.include_router(random_number_generator.router) # Random number tester
29
  app.include_router(help.router) # Helper/test info
30
  app.include_router(calculator.router) # Mini calculator service
 
 
 
31
 
32
 
33
  # ==========================
@@ -38,4 +57,4 @@ def greet_json():
38
  return """
39
  <h2>Go to the Swagger docs 👇</h2>
40
  <a href="/docs">Click here for API Docs</a>
41
- """
 
1
  from fastapi import FastAPI
2
  from fastapi.responses import HTMLResponse
3
 
4
+ # ==========================
5
+ # 📄 PDF Module
6
+ # ==========================
7
+ from app.routers.pdf import pdf_tools
8
+
9
  # ==========================
10
  # 📌 Image Module
11
  # ==========================
12
  from app.routers.image import jpgcompressor
13
 
14
+ # ==========================
15
+ # 🔒 Security Module
16
+ # ==========================
17
+ from app.routers.security import password_generator
18
+
19
+ # ==========================
20
+ # 🛡️ Auth Module (NEW)
21
+ # ==========================
22
+ from app.routers.auth import system as auth_system
23
 
24
  # ==========================
25
  # 🧪 Test Utilities
 
27
  from app.routers.testers import random_number_generator
28
  from app.routers.testers import help
29
  from app.routers.testers import calculator
30
+ from app.routers.testers import server_status # <-- NEW IMPORT
31
 
32
  # ==========================
33
  # 🚀 App Initialization
 
38
  # ==========================
39
  # 🔗 Router Registration
40
  # ==========================
41
+ app.include_router(pdf_tools.router) # pdf manipulation
42
  app.include_router(jpgcompressor.router) # Image compression handler
43
+ app.include_router(password_generator.router) # Generate a powerfull password that are harder to crack
44
  app.include_router(random_number_generator.router) # Random number tester
45
  app.include_router(help.router) # Helper/test info
46
  app.include_router(calculator.router) # Mini calculator service
47
+ app.include_router(auth_system.router) # <-- NEW AUTH SYSTEM
48
+ app.include_router(server_status.router) # function to check the system
49
+
50
 
51
 
52
  # ==========================
 
57
  return """
58
  <h2>Go to the Swagger docs 👇</h2>
59
  <a href="/docs">Click here for API Docs</a>
60
+ """
app/routers/auth/__init__.py ADDED
File without changes
app/routers/auth/database.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine
2
+ from sqlalchemy.ext.declarative import declarative_base
3
+ from sqlalchemy.orm import sessionmaker
4
+
5
+ # This creates a file named "sql_app.db" in your project root
6
+ SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
7
+
8
+ # connect_args is needed only for SQLite
9
+ engine = create_engine(
10
+ SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
11
+ )
12
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
13
+
14
+ Base = declarative_base()
15
+
16
+ # Dependency to get the DB session in endpoints
17
+ def get_db():
18
+ db = SessionLocal()
19
+ try:
20
+ yield db
21
+ finally:
22
+ db.close()
app/routers/auth/models.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, Integer, String, Boolean
2
+ from .database import Base
3
+
4
+ class User(Base):
5
+ __tablename__ = "users"
6
+
7
+ id = Column(Integer, primary_key=True, index=True)
8
+ username = Column(String, unique=True, index=True)
9
+ email = Column(String, unique=True, index=True)
10
+ hashed_password = Column(String)
11
+ is_active = Column(Boolean, default=True)
app/routers/auth/schemas.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class UserCreate(BaseModel):
4
+ username: str
5
+ email: str
6
+ password: str
7
+
8
+ class UserOut(BaseModel):
9
+ username: str
10
+ email: str
11
+ is_active: bool
12
+
13
+ class Config:
14
+ from_attributes = True
app/routers/auth/system.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, Depends, HTTPException, status
2
+ from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
3
+ from sqlalchemy.orm import Session
4
+ from jose import JWTError, jwt
5
+
6
+ # Import local modules
7
+ from . import models, schemas, database
8
+ from .utils import verify_password, create_access_token, get_password_hash, SECRET_KEY, ALGORITHM
9
+
10
+ # Create tables automatically
11
+ models.Base.metadata.create_all(bind=database.engine)
12
+
13
+ router = APIRouter(
14
+ prefix="/auth",
15
+ tags=["Authentication"],
16
+ )
17
+
18
+ # Define the OAuth2 scheme
19
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="auth/token")
20
+
21
+ # ==========================================
22
+ # 🔐 The Missing Dependency (Add this back!)
23
+ # ==========================================
24
+ async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(database.get_db)):
25
+ credentials_exception = HTTPException(
26
+ status_code=status.HTTP_401_UNAUTHORIZED,
27
+ detail="Could not validate credentials",
28
+ headers={"WWW-Authenticate": "Bearer"},
29
+ )
30
+ try:
31
+ # Decode the token
32
+ payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
33
+ username: str = payload.get("sub")
34
+ if username is None:
35
+ raise credentials_exception
36
+ except JWTError:
37
+ raise credentials_exception
38
+
39
+ # Check if user exists in DB
40
+ user = db.query(models.User).filter(models.User.username == username).first()
41
+ if user is None:
42
+ raise credentials_exception
43
+
44
+ return user
45
+
46
+ # ==========================================
47
+ # 🚀 Endpoints
48
+ # ==========================================
49
+
50
+ @router.post("/register", response_model=schemas.UserOut)
51
+ def register_user(user: schemas.UserCreate, db: Session = Depends(database.get_db)):
52
+ # 1. Check if user already exists
53
+ db_user = db.query(models.User).filter(models.User.username == user.username).first()
54
+ if db_user:
55
+ raise HTTPException(status_code=400, detail="Username already registered")
56
+
57
+ # 2. Hash the password
58
+ hashed_pw = get_password_hash(user.password)
59
+
60
+ # 3. Save to DB
61
+ new_user = models.User(
62
+ username=user.username,
63
+ email=user.email,
64
+ hashed_password=hashed_pw
65
+ )
66
+ db.add(new_user)
67
+ db.commit()
68
+ db.refresh(new_user)
69
+
70
+ return new_user
71
+
72
+ @router.post("/token")
73
+ async def login_for_access_token(
74
+ form_data: OAuth2PasswordRequestForm = Depends(),
75
+ db: Session = Depends(database.get_db)
76
+ ):
77
+ # 1. Fetch user from DB
78
+ user = db.query(models.User).filter(models.User.username == form_data.username).first()
79
+
80
+ # 2. Verify password
81
+ if not user or not verify_password(form_data.password, user.hashed_password):
82
+ raise HTTPException(
83
+ status_code=status.HTTP_401_UNAUTHORIZED,
84
+ detail="Incorrect username or password",
85
+ headers={"WWW-Authenticate": "Bearer"},
86
+ )
87
+
88
+ # 3. Create Token
89
+ access_token = create_access_token(data={"sub": user.username})
90
+ return {"access_token": access_token, "token_type": "bearer"}
app/routers/auth/utils.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timedelta
2
+ from typing import Union
3
+ from passlib.context import CryptContext
4
+ from jose import jwt
5
+
6
+ # ⚙️ CONFIGURATION (In production, load these from .env)
7
+ SECRET_KEY = "CHANGE_THIS_TO_A_REALLY_LONG_RANDOM_STRING"
8
+ ALGORITHM = "HS256"
9
+ ACCESS_TOKEN_EXPIRE_MINUTES = 30
10
+
11
+ # Password Hashing Wrapper
12
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
13
+
14
+ def verify_password(plain_password, hashed_password):
15
+ return pwd_context.verify(plain_password, hashed_password)
16
+
17
+ def get_password_hash(password):
18
+ return pwd_context.hash(password)
19
+
20
+ def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
21
+ to_encode = data.copy()
22
+ if expires_delta:
23
+ expire = datetime.utcnow() + expires_delta
24
+ else:
25
+ expire = datetime.utcnow() + timedelta(minutes=15)
26
+
27
+ to_encode.update({"exp": expire})
28
+ encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
29
+ return encoded_jwt
app/routers/pdf/__init__.py ADDED
File without changes
app/routers/pdf/pdf_tools.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, UploadFile, File, HTTPException, Security
2
+ from fastapi.responses import FileResponse
3
+ from pypdf import PdfReader, PdfWriter
4
+ import os
5
+ import shutil
6
+ import tempfile
7
+
8
+ # Define the APIRouter object
9
+ router = APIRouter(
10
+ prefix="/pdf",
11
+ tags=["PDF Manipulation"],
12
+ )
13
+
14
+ @router.post("/merge")
15
+ async def merge_pdfs(files: list[UploadFile] = File(description="List of PDFs to merge")):
16
+ """
17
+ Merges multiple uploaded PDF files into a single PDF.
18
+ """
19
+ if len(files) < 2:
20
+ raise HTTPException(status_code=400, detail="Please upload at least two PDF files to merge.")
21
+
22
+ pdf_writer = PdfWriter()
23
+
24
+ # Create a temporary directory to store files
25
+ with tempfile.TemporaryDirectory() as temp_dir:
26
+ output_path = os.path.join(temp_dir, "merged_output.pdf")
27
+
28
+ for file in files:
29
+ # Save the uploaded file temporarily
30
+ temp_file_path = os.path.join(temp_dir, file.filename)
31
+ with open(temp_file_path, "wb") as buffer:
32
+ shutil.copyfileobj(file.file, buffer)
33
+
34
+ # Read and append pages
35
+ try:
36
+ reader = PdfReader(temp_file_path)
37
+ for page in reader.pages:
38
+ pdf_writer.add_page(page)
39
+ except Exception as e:
40
+ raise HTTPException(status_code=500, detail=f"Error reading PDF file {file.filename}: {e}")
41
+
42
+ # Write the merged PDF to the output path
43
+ with open(output_path, "wb") as output_file:
44
+ pdf_writer.write(output_file)
45
+
46
+ # Return the merged file as a response
47
+ return FileResponse(output_path, media_type="application/pdf", filename="merged_document.pdf")
48
+
49
+ @router.post("/rotate")
50
+ async def rotate_pdf(
51
+ file: UploadFile = File(description="PDF file to rotate"),
52
+ degrees: int = 90 # Default rotation is 90 degrees clockwise
53
+ ):
54
+ """
55
+ Rotates all pages of a single PDF by a specified degree (90, 180, or 270).
56
+ """
57
+ if degrees not in [90, 180, 270]:
58
+ raise HTTPException(status_code=400, detail="Rotation must be 90, 180, or 270 degrees.")
59
+
60
+ pdf_writer = PdfWriter()
61
+
62
+ with tempfile.TemporaryDirectory() as temp_dir:
63
+ input_path = os.path.join(temp_dir, file.filename)
64
+ output_path = os.path.join(temp_dir, "rotated_output.pdf")
65
+
66
+ # Save the uploaded file temporarily
67
+ with open(input_path, "wb") as buffer:
68
+ shutil.copyfileobj(file.file, buffer)
69
+
70
+ # Read, rotate, and write
71
+ try:
72
+ reader = PdfReader(input_path)
73
+ for page in reader.pages:
74
+ page.rotate(degrees)
75
+ pdf_writer.add_page(page)
76
+ except Exception as e:
77
+ raise HTTPException(status_code=500, detail=f"Error processing PDF: {e}")
78
+
79
+ # Write the rotated PDF
80
+ with open(output_path, "wb") as output_file:
81
+ pdf_writer.write(output_file)
82
+
83
+ return FileResponse(output_path, media_type="application/pdf", filename=f"rotated_{degrees}.pdf")
app/routers/security/__init__.py ADDED
File without changes
app/routers/security/password_generator.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import string
3
+ from fastapi import APIRouter, Query, Depends # Added 'Depends'
4
+ from app.routers.auth.system import get_current_user # Import our Auth System
5
+
6
+ # Define the APIRouter object as per documentation standards
7
+ router = APIRouter(
8
+ prefix="/security", # Endpoints will start with /security
9
+ tags=["Password Tools"],
10
+ )
11
+
12
+ @router.get("/generate-password")
13
+ def generate_password(
14
+ length: int = Query(12, ge=8, le=64, description="Length of the password (8-64)"),
15
+ include_uppercase: bool = True,
16
+ include_numbers: bool = True,
17
+ include_symbols: bool = True,
18
+ # 👇 This line locks the endpoint!
19
+ current_user: dict = Depends(get_current_user)
20
+ ):
21
+ """
22
+ Generates a secure, random password.
23
+ **Requires Authentication.**
24
+ """
25
+ # Base character set
26
+ chars = string.ascii_lowercase
27
+
28
+ # Advanced logic to append character sets based on flags
29
+ if include_uppercase:
30
+ chars += string.ascii_uppercase
31
+ if include_numbers:
32
+ chars += string.digits
33
+ if include_symbols:
34
+ chars += string.punctuation
35
+
36
+ # Generate the password
37
+ generated_password = "".join(random.choice(chars) for _ in range(length))
38
+
39
+ return {
40
+ "requested_by": current_user.username, # We can now see who asked for it!
41
+ "password": generated_password,
42
+ "length": length,
43
+ "complexity": "Advanced"
44
+ }
app/routers/testers/help.py CHANGED
@@ -1,4 +1,5 @@
1
- from fastapi import APIRouter
 
2
 
3
  # Create the router for help/info endpoints
4
  router = APIRouter(
@@ -7,13 +8,15 @@ router = APIRouter(
7
  )
8
 
9
  @router.get("/")
10
- def get_api_info():
11
  """
12
  Returns general information about the API and available endpoints.
13
  """
14
  return {
 
15
  "api_name": "My Awesome FastAPI",
16
  "version": "1.0",
17
  "available_sections": ["/random", "/help"],
18
  "message": "Use the /docs endpoint for interactive API documentation."
 
19
  }
 
1
+ from fastapi import APIRouter , Depends
2
+ from app.routers.auth.system import get_current_user # Import our Auth System
3
 
4
  # Create the router for help/info endpoints
5
  router = APIRouter(
 
8
  )
9
 
10
  @router.get("/")
11
+ def get_api_info(current_user: dict = Depends(get_current_user) ):
12
  """
13
  Returns general information about the API and available endpoints.
14
  """
15
  return {
16
+ "requested_by": current_user.username,
17
  "api_name": "My Awesome FastAPI",
18
  "version": "1.0",
19
  "available_sections": ["/random", "/help"],
20
  "message": "Use the /docs endpoint for interactive API documentation."
21
+
22
  }
app/routers/testers/server_status.py ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, status
2
+ from fastapi.responses import JSONResponse
3
+ import platform
4
+ import psutil
5
+
6
+ # Initialize the router for this feature
7
+ router = APIRouter(
8
+ prefix="/server-status",
9
+ tags=["Server Info"],
10
+ responses={404: {"description": "Not found"}},
11
+ )
12
+
13
+ @router.get(
14
+ "/full-info",
15
+ summary="Get complete server/PC status and information",
16
+ status_code=status.HTTP_200_OK
17
+ )
18
+ def get_server_status():
19
+ """
20
+ Retrieves detailed hardware and software status of the server.
21
+ """
22
+
23
+ # --- System Information ---
24
+ system_info = {
25
+ "system": platform.system(),
26
+ "node_name": platform.node(),
27
+ "release": platform.release(),
28
+ "version": platform.version(),
29
+ "machine": platform.machine(),
30
+ "processor": platform.processor(),
31
+ }
32
+
33
+ # --- CPU Information ---
34
+ cpu_info = {
35
+ "physical_cores": psutil.cpu_count(logical=False),
36
+ "total_cores": psutil.cpu_count(logical=True),
37
+ "cpu_usage_percent": psutil.cpu_percent(interval=1),
38
+ "cpu_frequency_mhz": f"{psutil.cpu_freq().current:.2f}",
39
+ }
40
+
41
+ # --- Memory Information (RAM) ---
42
+ virtual_memory = psutil.virtual_memory()
43
+ memory_info = {
44
+ "total_gb": f"{virtual_memory.total / (1024**3):.2f}",
45
+ "available_gb": f"{virtual_memory.available / (1024**3):.2f}",
46
+ "used_gb": f"{virtual_memory.used / (1024**3):.2f}",
47
+ "usage_percent": virtual_memory.percent,
48
+ }
49
+
50
+ # --- Disk Usage Information (Root partition) ---
51
+ disk_usage = psutil.disk_usage('/')
52
+ disk_info = {
53
+ "total_gb": f"{disk_usage.total / (1024**3):.2f}",
54
+ "used_gb": f"{disk_usage.used / (1024**3):.2f}",
55
+ "free_gb": f"{disk_usage.free / (1024**3):.2f}",
56
+ "usage_percent": disk_usage.percent,
57
+ }
58
+
59
+ # --- Network Information (Simple) ---
60
+ network_info = {
61
+ "bytes_sent_mb": f"{psutil.net_io_counters().bytes_sent / (1024**2):.2f}",
62
+ "bytes_recv_mb": f"{psutil.net_io_counters().bytes_recv / (1024**2):.2f}",
63
+ }
64
+
65
+ response_data = {
66
+ "system_information": system_info,
67
+ "cpu_status": cpu_info,
68
+ "memory_status": memory_info,
69
+ "disk_status": disk_info,
70
+ "network_io": network_info,
71
+ }
72
+
73
+ return JSONResponse(content=response_data, status_code=status.HTTP_200_OK)
requirements.txt CHANGED
@@ -2,4 +2,7 @@ fastapi
2
  uvicorn
3
  requests
4
  pillow
5
- python-multipart
 
 
 
 
2
  uvicorn
3
  requests
4
  pillow
5
+ python-multipart
6
+ pypdf
7
+ python-dotenv
8
+ pydantic-settings
sql_app.db ADDED
Binary file (20.5 kB). View file