ariansyahdedy commited on
Commit
4dbe421
·
1 Parent(s): cdd4928

Add users

Browse files
app/__pycache__/dependencies.cpython-310.pyc ADDED
Binary file (1.13 kB). View file
 
app/__pycache__/main.cpython-310.pyc CHANGED
Binary files a/app/__pycache__/main.cpython-310.pyc and b/app/__pycache__/main.cpython-310.pyc differ
 
app/api/v1/endpoints/__pycache__/auth.cpython-310.pyc ADDED
Binary file (1.21 kB). View file
 
app/api/v1/endpoints/__pycache__/user.cpython-310.pyc ADDED
Binary file (1.18 kB). View file
 
app/api/v1/endpoints/auth.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/api/v1/endpoints/auth.py
2
+ from fastapi import APIRouter, Depends, HTTPException, status
3
+ from fastapi.security import OAuth2PasswordRequestForm
4
+ from datetime import timedelta
5
+ from app.models.token import Token
6
+ from app.core.security import create_access_token
7
+ from app.crud.users import authenticate_user
8
+ from app.core.config import settings
9
+
10
+ router = APIRouter()
11
+
12
+ @router.post("/token", response_model=Token)
13
+ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
14
+ user = await authenticate_user(form_data.username, form_data.password)
15
+ if not user:
16
+ raise HTTPException(
17
+ status_code=status.HTTP_401_UNAUTHORIZED,
18
+ detail="Incorrect username or password",
19
+ headers={"WWW-Authenticate": "Bearer"},
20
+ )
21
+ access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
22
+ access_token = create_access_token(
23
+ data={"sub": user["username"]}, expires_delta=access_token_expires
24
+ )
25
+ return {"access_token": access_token, "token_type": "bearer"}
app/api/v1/endpoints/user.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/api/v1/endpoints/user.py
2
+ from fastapi import APIRouter, Depends, HTTPException
3
+ from app.models.users import *
4
+ from app.crud.users import *
5
+ from app.core.security import get_password_hash
6
+ from app.dependencies import get_current_user
7
+
8
+ router = APIRouter()
9
+
10
+ @router.post("/")
11
+ async def register_user(user: User):
12
+
13
+ db_user = await get_user_by_username(user.username)
14
+ if db_user:
15
+ raise HTTPException(status_code=400, detail="Username already exists")
16
+
17
+ db_user = await get_user_by_email(user.email)
18
+ if db_user:
19
+ raise HTTPException(status_code=400, detail="Email already exists")
20
+
21
+ user_in_db = UserInDB(**user.dict(), hashed_password=get_password_hash(user.password))
22
+
23
+ user_id = await create_user(user_in_db)
24
+
25
+ return {"id": user_id}
26
+
27
+ @router.get("/me/", response_model=User)
28
+ async def read_users_me(current_user: User = Depends(get_current_user)):
29
+ print("Current user:", current_user)
30
+
31
+
32
+ return current_user
app/core/__pycache__/auth.cpython-310.pyc CHANGED
Binary files a/app/core/__pycache__/auth.cpython-310.pyc and b/app/core/__pycache__/auth.cpython-310.pyc differ
 
app/core/__pycache__/config.cpython-310.pyc ADDED
Binary file (867 Bytes). View file
 
app/core/__pycache__/database.cpython-310.pyc ADDED
Binary file (1.24 kB). View file
 
app/core/__pycache__/schemas.cpython-310.pyc CHANGED
Binary files a/app/core/__pycache__/schemas.cpython-310.pyc and b/app/core/__pycache__/schemas.cpython-310.pyc differ
 
app/core/__pycache__/security.cpython-310.pyc ADDED
Binary file (1.57 kB). View file
 
app/core/config.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # app/core/config.py
3
+ import os
4
+ from pydantic import BaseSettings
5
+ from dotenv import load_dotenv
6
+
7
+ load_dotenv()
8
+
9
+ class Settings(BaseSettings):
10
+ MONGO_DETAILS: str = os.getenv("mongodb_uri")
11
+ MongoDB_NAME: str = "OCRwebapp"
12
+ COLLECTION_NAMES: list = ["users", "files", "templates", "extracted data", "external credentials"]
13
+ SECRET_KEY: str = os.getenv("SECRET_KEY")
14
+ ALGORITHM: str = "HS256"
15
+ ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
16
+
17
+ settings = Settings()
18
+
19
+ print(f"SECRET_KEY: {settings.SECRET_KEY}") # Add this line to verify the SECRET_KEY
app/core/database.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/core/database.py
2
+ from motor.motor_asyncio import AsyncIOMotorClient
3
+ from app.core.config import settings
4
+
5
+ client = AsyncIOMotorClient(settings.MONGO_DETAILS)
6
+
7
+ def get_database(db_name:str):
8
+ return client[db_name]
9
+
10
+ async def create_collection(db_name:str, collection_name:str):
11
+ database = get_database(db_name)
12
+ existing_collections = await database.list_collection_names()
13
+ if collection_name not in existing_collections:
14
+ await database.create_collection(collection_name)
15
+ else:
16
+ print(f"Collection '{collection_name}' already exists in database '{db_name}'")
17
+
18
+
19
+ async def list_collection_names(db_name: str):
20
+ database = get_database(db_name)
21
+ collection_names = await database.list_collection_names()
22
+ return collection_names
23
+
24
+ async def init_db():
25
+ print(settings.MongoDB_NAME)
26
+ for collection_name in settings.COLLECTION_NAMES:
27
+ await create_collection(settings.MongoDB_NAME, collection_name)
28
+
29
+ collections = await list_collection_names(settings.MongoDB_NAME)
30
+ print(f"Collections in '{settings.MongoDB_NAME}': {collections}")
31
+
app/core/security.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/core/security.py
2
+ from datetime import datetime, timedelta
3
+ from typing import Optional
4
+ from jose import JWTError, jwt
5
+ from fastapi.security import OAuth2PasswordBearer
6
+ from passlib.context import CryptContext
7
+ from app.core.config import settings
8
+ from fastapi import Depends, HTTPException, status
9
+
10
+
11
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
12
+
13
+ def verify_password(plain_password, hashed_password):
14
+ return pwd_context.verify(plain_password, hashed_password)
15
+
16
+ def get_password_hash(password):
17
+ return pwd_context.hash(password)
18
+
19
+ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
20
+ to_encode = data.copy()
21
+ if expires_delta:
22
+ expire = datetime.utcnow() + expires_delta
23
+ else:
24
+ expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
25
+ to_encode.update({"exp": expire})
26
+ encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
27
+ return encoded_jwt
28
+
29
+ def decode_access_token(token: str):
30
+ try:
31
+ payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
32
+ return payload
33
+ except JWTError:
34
+ return None
35
+
36
+
app/crud/__pycache__/users.cpython-310.pyc ADDED
Binary file (1.38 kB). View file
 
app/crud/users.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/crud/user.py
2
+ from app.core.database import get_database
3
+ from app.models.users import UserInDB, User
4
+ from app.core.security import get_password_hash, verify_password
5
+ from bson import ObjectId
6
+ from app.core.config import settings
7
+
8
+
9
+ async def create_user(user: UserInDB):
10
+ user_dict = user.dict()
11
+ user_dict["password"] = get_password_hash(user.password)
12
+ db = get_database(settings.MongoDB_NAME)
13
+ result = await db["users"].insert_one(user_dict)
14
+ user_dict["_id"] = str(result.inserted_id)
15
+ return User(**user_dict)
16
+
17
+ async def get_user_by_username(username: str):
18
+ db = get_database(settings.MongoDB_NAME)
19
+ user = await db["users"].find_one({"username": username})
20
+
21
+ return user
22
+
23
+ async def get_user_by_email(email: str):
24
+ db = get_database(settings.MongoDB_NAME)
25
+ user = await db["users"].find_one({"email": email})
26
+ return user
27
+
28
+ async def authenticate_user(username: str, password: str):
29
+ user = await get_user_by_username(username)
30
+ print("User:", user)
31
+ if user and verify_password(password, user["password"]):
32
+ return user
33
+ return False
app/db/__pycache__/base.cpython-310.pyc CHANGED
Binary files a/app/db/__pycache__/base.cpython-310.pyc and b/app/db/__pycache__/base.cpython-310.pyc differ
 
app/db/base.py CHANGED
@@ -1,5 +1,5 @@
1
  import asyncio, contextlib, logging, os, sys, time
2
- from dotenv import load_dotenv
3
  from typing import AsyncIterator, Any, Dict, List, Optional, Tuple, Type, Union
4
  # from app.db.models.models import Base
5
 
@@ -10,7 +10,7 @@ from sqlalchemy.ext.asyncio import (
10
  )
11
 
12
 
13
- load_dotenv()
14
 
15
  from sqlalchemy import text
16
  from sqlalchemy.orm import declarative_base
@@ -20,21 +20,21 @@ Base = declarative_base()
20
  # # Define the MySQL connection details
21
  username = os.getenv("usernameDb")
22
  password = os.getenv("password")
23
- host = os.getenv("host") # e.g., 'localhost' or '127.0.0.1'
24
- # port = os.getenv("port") # Default MySQL port
25
- database_name = os.getenv("database_name")
26
 
27
 
28
  # username = 'hidh4125_admin'
29
  # password = 'Alberto471'
30
  # host = 'hidigi.asia' # e.g., 'localhost' or '127.0.0.1'
31
- port = '3306' # Default MySQL port
32
  # database_name = 'hidh4125_speechRecognition'
33
 
34
- print(username,password,host,port,database_name)
35
 
36
  # Create an engine to connect to the MySQL server
37
- engine = create_async_engine(f'mysql+aiomysql://{username}:{password}@{host}:{port}/{database_name}', echo=True, future=True)
38
 
39
 
40
  async_session = async_sessionmaker(
 
1
  import asyncio, contextlib, logging, os, sys, time
2
+ from dotenv import load_dotenv, dotenv_values
3
  from typing import AsyncIterator, Any, Dict, List, Optional, Tuple, Type, Union
4
  # from app.db.models.models import Base
5
 
 
10
  )
11
 
12
 
13
+ dotenv_values(".env")
14
 
15
  from sqlalchemy import text
16
  from sqlalchemy.orm import declarative_base
 
20
  # # Define the MySQL connection details
21
  username = os.getenv("usernameDb")
22
  password = os.getenv("password")
23
+ host = os.getenv("host")
24
+ port = os.environ.get("port")
25
+ mysql_name = os.getenv("MySQLDatabaseName")
26
 
27
 
28
  # username = 'hidh4125_admin'
29
  # password = 'Alberto471'
30
  # host = 'hidigi.asia' # e.g., 'localhost' or '127.0.0.1'
31
+ # port = '3306' # Default MySQL port
32
  # database_name = 'hidh4125_speechRecognition'
33
 
34
+ print('port:',port)
35
 
36
  # Create an engine to connect to the MySQL server
37
+ engine = create_async_engine(f'mysql+aiomysql://{username}:{password}@{host}:{port}/{mysql_name}', echo=True, future=True)
38
 
39
 
40
  async_session = async_sessionmaker(
app/db/models/__pycache__/models.cpython-310.pyc CHANGED
Binary files a/app/db/models/__pycache__/models.cpython-310.pyc and b/app/db/models/__pycache__/models.cpython-310.pyc differ
 
app/dependencies.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/dependencies.py
2
+ from fastapi import Depends, HTTPException, status
3
+ from fastapi.security import OAuth2PasswordBearer
4
+ from jose import JWTError, jwt
5
+ from app.models.token import TokenData
6
+ from app.crud.users import get_user_by_username
7
+ from app.core.config import settings
8
+
9
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
10
+
11
+ async def get_current_user(token: str = Depends(oauth2_scheme)):
12
+ credentials_exception = HTTPException(
13
+ status_code=status.HTTP_401_UNAUTHORIZED,
14
+ detail="Could not validate credentials",
15
+ headers={"WWW-Authenticate": "Bearer"},
16
+ )
17
+ try:
18
+ payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
19
+ username: str = payload.get("sub")
20
+ if username is None:
21
+ raise credentials_exception
22
+ token_data = TokenData(username=username)
23
+ except JWTError:
24
+ raise credentials_exception
25
+ user = await get_user_by_username(username=token_data.username)
26
+ if user is None:
27
+ raise credentials_exception
28
+ return user
app/main.py CHANGED
@@ -13,41 +13,38 @@ from bson import ObjectId
13
  from contextlib import asynccontextmanager
14
  from pydantic import BaseModel, Field
15
  from datetime import timedelta, datetime
16
- from dotenv import load_dotenv
 
17
  from app.db.base import *
18
  from app.core.auth import *
19
- from app.router.user import *
 
20
 
21
  # Load environment variables from .env file
22
- load_dotenv()
23
 
24
 
25
  # Read environment variables
26
  host = os.getenv("HOST", "0.0.0.0")
27
  port = os.getenv("PORT", 8080)
28
- print(host,port)
29
 
30
  # Configure logging
31
  logging.basicConfig(level=logging.INFO)
32
  logger = logging.getLogger(__name__)
33
 
34
- # Connect to MongoDB
35
- mongodb_uri = os.getenv('mongodb_uri')
36
- db_name = os.getenv('DB_NAME')
37
-
38
- if not mongodb_uri or not db_name:
39
- logger.error("Environment variables mongodb_uri or DB_NAME are not set.")
40
- raise ValueError("Environment variables mongodb_uri or DB_NAME are not set.")
41
 
42
  @asynccontextmanager
43
  async def lifespan(app: FastAPI):
44
- app.mongodb_client = MongoClient(mongodb_uri)
45
- app.database = app.mongodb_client[db_name]
 
46
  logger.info("Connected to the MongoDB database!")
47
 
48
  try:
49
- collections = app.database.list_collection_names()
50
- print(f"Collections in {db_name}: {collections}")
 
51
  yield
52
  except Exception as e:
53
  logger.error(e)
@@ -61,7 +58,8 @@ app.add_middleware(
61
  allow_headers=["*"],
62
  )
63
 
64
- app.include_router(router, prefix='/api/v1/user', tags=["User"])
 
65
 
66
 
67
  class Destination(BaseModel):
 
13
  from contextlib import asynccontextmanager
14
  from pydantic import BaseModel, Field
15
  from datetime import timedelta, datetime
16
+ from dotenv import load_dotenv, dotenv_values
17
+ from app.api.v1.endpoints import user, auth
18
  from app.db.base import *
19
  from app.core.auth import *
20
+ # from app.router.user import *
21
+ from app.core.database import *
22
 
23
  # Load environment variables from .env file
24
+ dotenv_values(".env")
25
 
26
 
27
  # Read environment variables
28
  host = os.getenv("HOST", "0.0.0.0")
29
  port = os.getenv("PORT", 8080)
30
+
31
 
32
  # Configure logging
33
  logging.basicConfig(level=logging.INFO)
34
  logger = logging.getLogger(__name__)
35
 
 
 
 
 
 
 
 
36
 
37
  @asynccontextmanager
38
  async def lifespan(app: FastAPI):
39
+ # app.mongodb_client = MongoClient(mongodb_uri)
40
+ # app.database = app.mongodb_client[db_name]
41
+
42
  logger.info("Connected to the MongoDB database!")
43
 
44
  try:
45
+ await init_db()
46
+ # collections = app.database.list_collection_names()
47
+ # print(f"Collections in {db_name}: {collections}")
48
  yield
49
  except Exception as e:
50
  logger.error(e)
 
58
  allow_headers=["*"],
59
  )
60
 
61
+ app.include_router(user.router, prefix='/api/v1/user', tags=["User"])
62
+ app.include_router(auth.router, tags=["Auth"])
63
 
64
 
65
  class Destination(BaseModel):
app/models/__pycache__/token.cpython-310.pyc ADDED
Binary file (654 Bytes). View file
 
app/models/__pycache__/users.cpython-310.pyc ADDED
Binary file (889 Bytes). View file
 
app/models/token.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/schemas/token.py
2
+ from pydantic import BaseModel
3
+ from typing import Optional
4
+
5
+ class Token(BaseModel):
6
+ access_token: str
7
+ token_type: str
8
+
9
+ class TokenData(BaseModel):
10
+ username: Optional[str] = None
app/models/users.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app/models/user.py
2
+ from pydantic import BaseModel, EmailStr, Field
3
+ from typing import Optional
4
+ from datetime import timedelta, datetime
5
+
6
+ class User(BaseModel):
7
+ username: str
8
+ email: EmailStr
9
+ password: str
10
+
11
+ class UserInDB(User):
12
+ is_validated: bool = Field(default=False)
13
+ created_at: datetime = Field(default_factory=datetime.utcnow)
14
+ updated_at: Optional[str] = None
app/router/__pycache__/user.cpython-310.pyc CHANGED
Binary files a/app/router/__pycache__/user.cpython-310.pyc and b/app/router/__pycache__/user.cpython-310.pyc differ