Spaces:
Runtime error
Runtime error
Commit
·
dce75a4
1
Parent(s):
1c097b9
Add email microservice
Browse files- TechdocsAPI/backend/__init__.py +0 -30
- TechdocsAPI/backend/core/ConfigEnv.py +1 -3
- TechdocsAPI/backend/core/ExceptionHandlers.py +6 -0
- TechdocsAPI/backend/core/Exceptions.py +13 -1
- TechdocsAPI/backend/services/auth/__init__.py +2 -1
- TechdocsAPI/backend/services/auth/ops.py +17 -25
- TechdocsAPI/backend/services/auth/utils/functools.py +9 -0
- TechdocsAPI/backend/templates/email_verification.html +0 -1
- TechdocsAPI/requirements.txt +0 -2
TechdocsAPI/backend/__init__.py
CHANGED
|
@@ -12,11 +12,6 @@ from langchain.llms import Clarifai
|
|
| 12 |
from langchain.chains import LLMChain
|
| 13 |
from langchain.prompts import PromptTemplate
|
| 14 |
|
| 15 |
-
from fastapi_mail import ConnectionConfig, FastMail
|
| 16 |
-
import yagmail
|
| 17 |
-
from jinja2 import Environment, FileSystemLoader
|
| 18 |
-
import os
|
| 19 |
-
|
| 20 |
app = FastAPI(title="Techdocs",
|
| 21 |
version="V0.0.1",
|
| 22 |
description="API for automatic code documentation generation!"
|
|
@@ -49,33 +44,8 @@ try:
|
|
| 49 |
app.state.llmchain = llmchain
|
| 50 |
|
| 51 |
|
| 52 |
-
conf = ConnectionConfig(
|
| 53 |
-
MAIL_USERNAME=config.MAIL_USERNAME,
|
| 54 |
-
MAIL_PASSWORD=config.MAIL_PASSWORD,
|
| 55 |
-
MAIL_FROM=config.MAIL_FROM,
|
| 56 |
-
MAIL_PORT=8080,
|
| 57 |
-
MAIL_SERVER="smtp.gmail.com",
|
| 58 |
-
MAIL_STARTTLS=False,
|
| 59 |
-
MAIL_SSL_TLS=True,
|
| 60 |
-
TEMPLATE_FOLDER="backend/templates",
|
| 61 |
-
USE_CREDENTIALS = True,
|
| 62 |
-
VALIDATE_CERTS = True
|
| 63 |
-
|
| 64 |
-
# MAIL_TLS=True,
|
| 65 |
-
# MAIL_SSL=False
|
| 66 |
-
)
|
| 67 |
-
|
| 68 |
-
app.state.mail_client = FastMail(conf)
|
| 69 |
app.state.templates = Jinja2Templates(directory="./backend/templates")
|
| 70 |
|
| 71 |
-
#testing yagmail
|
| 72 |
-
yag = yagmail.SMTP(config.MAIL_USERNAME, config.MAIL_PASSWORD)
|
| 73 |
-
app.state.yagmail = yag
|
| 74 |
-
env = Environment(
|
| 75 |
-
loader=FileSystemLoader('./backend/templates/'))
|
| 76 |
-
app.state.jinjaenv = env
|
| 77 |
-
|
| 78 |
-
|
| 79 |
|
| 80 |
|
| 81 |
except mysql.connector.Error as err:
|
|
|
|
| 12 |
from langchain.chains import LLMChain
|
| 13 |
from langchain.prompts import PromptTemplate
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
app = FastAPI(title="Techdocs",
|
| 16 |
version="V0.0.1",
|
| 17 |
description="API for automatic code documentation generation!"
|
|
|
|
| 44 |
app.state.llmchain = llmchain
|
| 45 |
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
app.state.templates = Jinja2Templates(directory="./backend/templates")
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
|
| 51 |
except mysql.connector.Error as err:
|
TechdocsAPI/backend/core/ConfigEnv.py
CHANGED
|
@@ -21,9 +21,7 @@ class Settings(BaseSettings):
|
|
| 21 |
CLARIFAI_PAT:str
|
| 22 |
MODEL_VERSION_ID:str
|
| 23 |
|
| 24 |
-
|
| 25 |
-
MAIL_PASSWORD:str
|
| 26 |
-
MAIL_FROM:str
|
| 27 |
|
| 28 |
class Config:
|
| 29 |
env_file = ".env"
|
|
|
|
| 21 |
CLARIFAI_PAT:str
|
| 22 |
MODEL_VERSION_ID:str
|
| 23 |
|
| 24 |
+
MAIL_SERVER_URL:str
|
|
|
|
|
|
|
| 25 |
|
| 26 |
class Config:
|
| 27 |
env_file = ".env"
|
TechdocsAPI/backend/core/ExceptionHandlers.py
CHANGED
|
@@ -19,6 +19,12 @@ async def email_not_verified(request: Request, exec: EmailNotVerifiedException):
|
|
| 19 |
content=repr(exec)
|
| 20 |
)
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
@app.exception_handler(InvalidCredentialsException)
|
| 23 |
async def handle_login_failed(request: Request, exec: InvalidCredentialsException):
|
| 24 |
return JSONResponse(status_code=status.HTTP_403_FORBIDDEN,
|
|
|
|
| 19 |
content=repr(exec)
|
| 20 |
)
|
| 21 |
|
| 22 |
+
@app.exception_handler(EmailNotSentException)
|
| 23 |
+
async def email_not_sent(request: Request, exec: EmailNotSentException):
|
| 24 |
+
return JSONResponse(status_code=status.HTTP_403_FORBIDDEN,
|
| 25 |
+
content=repr(exec)
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
@app.exception_handler(InvalidCredentialsException)
|
| 29 |
async def handle_login_failed(request: Request, exec: InvalidCredentialsException):
|
| 30 |
return JSONResponse(status_code=status.HTTP_403_FORBIDDEN,
|
TechdocsAPI/backend/core/Exceptions.py
CHANGED
|
@@ -54,4 +54,16 @@ class EmailNotVerifiedException(Exception):
|
|
| 54 |
self.status = 'EmailNotVerifiedException'
|
| 55 |
|
| 56 |
def __repr__(self):
|
| 57 |
-
return "exception.EmailNotVerifiedException()"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
self.status = 'EmailNotVerifiedException'
|
| 55 |
|
| 56 |
def __repr__(self):
|
| 57 |
+
return "exception.EmailNotVerifiedException()"
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class EmailNotSentException(Exception):
|
| 61 |
+
def __init__(self):
|
| 62 |
+
self.set_statuses()
|
| 63 |
+
super(EmailNotSentException, self).__init__()
|
| 64 |
+
|
| 65 |
+
def set_statuses(self):
|
| 66 |
+
self.status = 'EmailNotSentException'
|
| 67 |
+
|
| 68 |
+
def __repr__(self):
|
| 69 |
+
return "exception.EmailNotSentException()"
|
TechdocsAPI/backend/services/auth/__init__.py
CHANGED
|
@@ -1,2 +1,3 @@
|
|
| 1 |
from .ops import *
|
| 2 |
-
from .utils.JWTBearer import *
|
|
|
|
|
|
| 1 |
from .ops import *
|
| 2 |
+
from .utils.JWTBearer import *
|
| 3 |
+
from .utils.functools import *
|
TechdocsAPI/backend/services/auth/ops.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
from .utils.auth_funcs import *
|
|
|
|
| 2 |
from .utils.JWTBearer import *
|
| 3 |
from backend.models import *
|
| 4 |
from backend.services.db.utils.DBQueries import DBQueries
|
|
@@ -11,11 +12,6 @@ from fastapi import HTTPException, BackgroundTasks
|
|
| 11 |
from pydantic import ValidationError
|
| 12 |
from jose import jwt
|
| 13 |
|
| 14 |
-
from fastapi_mail import MessageSchema, MessageType
|
| 15 |
-
|
| 16 |
-
# import openai
|
| 17 |
-
# from transformers import RobertaTokenizer, T5ForConditionalGeneration
|
| 18 |
-
|
| 19 |
async def ops_signup(bgtasks: BackgroundTasks, response_result: GeneralResponse, data: UserAuth):
|
| 20 |
"""Wrapper method to handle signup process.
|
| 21 |
|
|
@@ -41,30 +37,26 @@ async def ops_signup(bgtasks: BackgroundTasks, response_result: GeneralResponse,
|
|
| 41 |
"verify_link": verification_link
|
| 42 |
}
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
# contents=email)
|
| 57 |
-
|
| 58 |
-
# bgtasks.add_task(app.state.mail_client.send_message, message=message, template_name="email_verification.html")
|
| 59 |
-
# await app.state.mail_client.send_message(message=message, template_name="email_verification.html")
|
| 60 |
|
| 61 |
-
DBQueries.insert_to_database('auth', (data.username, Auth.get_password_hash(data.password),
|
| 62 |
['username', 'password', 'email', 'is_verified'])
|
| 63 |
|
| 64 |
|
| 65 |
|
| 66 |
response_result.status = 'success'
|
| 67 |
-
|
| 68 |
|
| 69 |
def ops_login(data:LoginCreds):
|
| 70 |
"""Wrapper method to handle login process.
|
|
@@ -93,8 +85,8 @@ def ops_login(data:LoginCreds):
|
|
| 93 |
# password is incorrect
|
| 94 |
raise InvalidCredentialsException(response_result)
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
| 98 |
|
| 99 |
# password is correct
|
| 100 |
return TokenSchema(access_token=Auth.create_access_token(data.username),
|
|
|
|
| 1 |
from .utils.auth_funcs import *
|
| 2 |
+
from .utils.functools import *
|
| 3 |
from .utils.JWTBearer import *
|
| 4 |
from backend.models import *
|
| 5 |
from backend.services.db.utils.DBQueries import DBQueries
|
|
|
|
| 12 |
from pydantic import ValidationError
|
| 13 |
from jose import jwt
|
| 14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
async def ops_signup(bgtasks: BackgroundTasks, response_result: GeneralResponse, data: UserAuth):
|
| 16 |
"""Wrapper method to handle signup process.
|
| 17 |
|
|
|
|
| 37 |
"verify_link": verification_link
|
| 38 |
}
|
| 39 |
|
| 40 |
+
details = {
|
| 41 |
+
"recipient": [data.email],
|
| 42 |
+
"subject": "Welcome to Techdocs:[Account Verification]",
|
| 43 |
+
"template_name": "email_verification.html",
|
| 44 |
+
"template_kwargs": email_body_params
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
status = post_request(url=config.MAIL_SERVER_URL, data=details, headers=None)
|
| 48 |
+
if status != 200:
|
| 49 |
+
raise EmailNotSentException()
|
| 50 |
+
|
| 51 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
+
DBQueries.insert_to_database('auth', (data.username, Auth.get_password_hash(data.password), "", 0),
|
| 54 |
['username', 'password', 'email', 'is_verified'])
|
| 55 |
|
| 56 |
|
| 57 |
|
| 58 |
response_result.status = 'success'
|
| 59 |
+
response_result.message = [f'Activate your account by clicking on the link sent to {data.email}.\nMake sure to check your spam folder.']
|
| 60 |
|
| 61 |
def ops_login(data:LoginCreds):
|
| 62 |
"""Wrapper method to handle login process.
|
|
|
|
| 85 |
# password is incorrect
|
| 86 |
raise InvalidCredentialsException(response_result)
|
| 87 |
|
| 88 |
+
if not user[2]:
|
| 89 |
+
raise EmailNotVerifiedException()
|
| 90 |
|
| 91 |
# password is correct
|
| 92 |
return TokenSchema(access_token=Auth.create_access_token(data.username),
|
TechdocsAPI/backend/services/auth/utils/functools.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
from typing import Any, Dict
|
| 3 |
+
import json
|
| 4 |
+
|
| 5 |
+
def post_request(url: str, data: Dict[str, Any], headers: Dict[str, str]=None):
|
| 6 |
+
json_data = json.dumps(data)
|
| 7 |
+
headers = headers or {'Content-type': 'application/json', 'Accept': 'application/json'}
|
| 8 |
+
response = requests.post(url, data=data, headers=headers)
|
| 9 |
+
return response.status_code
|
TechdocsAPI/backend/templates/email_verification.html
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
<!DOCTYPE html><html><head><title>Verify Email</title><style>body { font-family: Arial, sans-serif;background-color: #f4f4f4;margin: 0;padding: 0; } .container { width: 80%; margin: 0 auto; padding: 20px; background-color: #fff; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } h3 { color: #333; text-align: center; } p { color: #555; text-align: center; margin-bottom: 20px; } a.button { display: block; width: 50%; margin: 20px auto; padding: 12px; border-radius: 5px; text-align: center; text-decoration: none; background-color: #0275d8; color: #fff; font-size: 1rem; transition: background-color 0.3s; } a.button:hover { background-color: #025aa5; } .disclaimer { color: #777; text-align: center; } </style> </head> <body> <div class="container"> <h3>Account Verification</h3> <p>Hi, {{username}}👋. Thank you for registering with Techdocs. Please click the button below to verify your account:</p> <a class="button" href="{{verify_link}}" target="_blank">Verify your email</a> <p class="disclaimer">Please disregard this email if you did not register with Techdocs. Thank you.</p> </div> </body> </html>
|
|
|
|
|
|
TechdocsAPI/requirements.txt
CHANGED
|
@@ -9,5 +9,3 @@ pydantic[email]
|
|
| 9 |
langchain
|
| 10 |
clarifai
|
| 11 |
Pillow
|
| 12 |
-
fastapi_mail==1.3.1
|
| 13 |
-
yagmail
|
|
|
|
| 9 |
langchain
|
| 10 |
clarifai
|
| 11 |
Pillow
|
|
|
|
|
|