Skip to content

Commit

Permalink
Generate documentation using Techdocs
Browse files Browse the repository at this point in the history
  • Loading branch information
HemanthSai7 committed Nov 7, 2023
2 parents 4407704 + 5d17aad commit d597a61
Show file tree
Hide file tree
Showing 16 changed files with 99 additions and 92 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ build
dist
techdocs.egg-info

test.py
test.py
temp.py
52 changes: 10 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,40 @@
---
title: TechdocsAPI
emoji: 🚀
colorFrom: green
colorTo: green
sdk: docker
app_file: TechdocsAPI/app.py
pinned: false
---

# Techdocs: A code documentation generator

# Techdocs
### Code Documentation, Redefined: Where AI Meets Clarity!


## Introduction

**Code Documentation Generation** is a tool that generates documentation for your code. It is a simple tool that can be used by anyone who wants to generate documentation for their code. It leverages the power of **OpenAI GPT-3, Huggingface Transformers, Langchain and Clarifai** to generate documentation for your code.
**Code Documentation Generation** is a tool that generates documentation for your code. It is a simple tool that can be used by anyone who wants to generate documentation for their code. It leverages the power of **Huggingface Transformers, Langchain and Clarifai** to generate documentation for your code.

To use the application, you need to provide your code as input. The tool will analyze your code and generate documentation for it. The documentation will include comments, descriptions, parameters, return values, examples, and more.

It is a useful tool for developers who want to document their code without spending too much time and effort. It can help you improve the readability, maintainability, and quality of your code. It can also help you share your code with others more easily.

## Installation
> Download zip or Clone the repository and run the following command in the terminal to install the required packages.
> We recommend using a virtual environment for the installation.

```bash
$ git clone https://github.com/HemanthSai7/Techdocs
$ cd Techdocs
$ pip install -r requirements.txt
$ -- Run backend
$ uvicorn app:app --reload # For running the FastAPI server
$ -- Run frontend
$ cd frontend
$ streamlit run app.py # For running the Streamlit App
$ pip install techdocs
```

## Streamlit App
- Head over to the [Website](https://techdocs.streamlit.app) and `signup/login` to use the tool.
- Once you are logged in, Head over to [Code](techdocs.streamlit.app/Code) page and generate your `API KEY` by clicking on the `Generate API KEY` button. Please note that the API KEY will be visible only once and you need to copy it and save it somewhere safe.
- Copy the API KEY and paste it in the `API KEY` field in the [Code](techdocs.streamlit.app/Code)
- Now, you can paste your code in the `Code` field and click on the `Generate Documentation` button.
- The generated documentation will be displayed in the `Documentation` field.


## Demo and Screenshots
##### Demo Screenshot 1
![Result 1](assets/results1.png)

##### Demo Screenshot 2
![Result 2](assets/results2.png)

##### Demo Screenshot 3
![Result 3](assets/results3.png)
## Demo
[![thumbnail](https://i9.ytimg.com/vi_webp/T7FMd7jGb8w/mqdefault.webp?v=6548c43c&sqp=CICSp6oG&rs=AOn4CLDDRJuaPfqJuYNM649GdckHfBklbA)](https://youtu.be/T7FMd7jGb8w)

## Tech Stack Used
![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge&logo=python&logoColor=ffdd54)
![Azure](https://img.shields.io/badge/azure_SQL-%230072C6.svg?style=for-the-badge&logo=microsoftazure&logoColor=white)
![Azure SQL](https://img.shields.io/badge/azure_SQL-%230072C6.svg?style=for-the-badge&logo=microsoftazure&logoColor=white)
![FastAPI](https://img.shields.io/badge/FastAPI-005571?style=for-the-badge&logo=fastapi)
![Vercel](https://img.shields.io/badge/vercel-%23000000.svg?style=for-the-badge&logo=vercel&logoColor=white)
![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge&logo=JSON%20web%20tokens)
![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white)
![Streamlit](https://img.shields.io/badge/Streamlit-EA6566?style=for-the-badge&logo=streamlit&logoColor=white)
![Langchain](https://img.shields.io/badge/Langchain-F70A8D?style=for-the-badge&logo=langchain&logoColor=white)
![Clarifai](https://img.shields.io/badge/Clarifai-FFA500?style=for-the-badge&logo=clarifai&logoColor=white)
![Huggingface 🤗](https://img.shields.io/badge/huggingface-FFA500?style=for-the-badge&logo=huggingface&logoColor=white)
![Docker](https://img.shields.io/badge/docker-%230072C6.svg?style=for-the-badge&logo=docker&logoColor=white)

## Team Members
| Name | Github |
| --- | --- |
| Mayuresh Agashe | [Mayuresh Agashe](https://github.com/mayureshagashe2105) |
| Hemanth Sai Garladinne | [Hemanth Sai Garladinne](https://github.com/HemanthSai7) |
| Hemanth Sai Garladinne | [Hemanth Sai Garladinne](https://github.com/HemanthSai7) |
20 changes: 1 addition & 19 deletions TechdocsAPI/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@

from langchain.llms import Clarifai
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.prompts import PromptTemplate

from fastapi_mail import ConnectionConfig, FastMail

app = FastAPI(title="Techdocs",
version="V0.0.1",
Expand Down Expand Up @@ -46,23 +45,6 @@
app.state.llmchain = llmchain


conf = ConnectionConfig(
MAIL_USERNAME=config.MAIL_USERNAME,
MAIL_PASSWORD=config.MAIL_PASSWORD,
MAIL_FROM=config.MAIL_FROM,
MAIL_PORT=587,
MAIL_SERVER="smtp.gmail.com",
MAIL_STARTTLS=True,
MAIL_SSL_TLS=False,
TEMPLATE_FOLDER="backend/templates",
USE_CREDENTIALS = True,
VALIDATE_CERTS = True

# MAIL_TLS=True,
# MAIL_SSL=False
)

app.state.mail_client = FastMail(conf)
app.state.templates = Jinja2Templates(directory="./backend/templates")


Expand Down
9 changes: 6 additions & 3 deletions TechdocsAPI/backend/core/ConfigEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ class Settings(BaseSettings):
MODEL_ID: str
CLARIFAI_PAT: str
MODEL_VERSION_ID: str
MAIL_USERNAME: str
MAIL_PASSWORD: str
MAIL_FROM: str

MAIL_SERVER_URL:str

MAIL_USERNAME:str
MAIL_PASSWORD:str
MAIL_FROM:str

class Config:
env_file = '.env'

Expand Down
6 changes: 6 additions & 0 deletions TechdocsAPI/backend/core/ExceptionHandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ async def email_not_verified(request: Request, exec: EmailNotVerifiedException):
content=repr(exec)
)

@app.exception_handler(EmailNotSentException)
async def email_not_sent(request: Request, exec: EmailNotSentException):
return JSONResponse(status_code=status.HTTP_403_FORBIDDEN,
content=repr(exec)
)

@app.exception_handler(InvalidCredentialsException)
async def handle_login_failed(request: Request, exec: InvalidCredentialsException):
return JSONResponse(status_code=status.HTTP_403_FORBIDDEN,
Expand Down
14 changes: 13 additions & 1 deletion TechdocsAPI/backend/core/Exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,16 @@ def __repr__(self):
Returns:
str: A string representation of the object.
"""
return 'exception.EmailNotVerifiedException()'
return 'exception.EmailNotVerifiedException()'


class EmailNotSentException(Exception):
def __init__(self):
self.set_statuses()
super(EmailNotSentException, self).__init__()

def set_statuses(self):
self.status = 'EmailNotSentException'

def __repr__(self):
return "exception.EmailNotSentException()"
1 change: 0 additions & 1 deletion TechdocsAPI/backend/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ async def inference(generate: Generate, access_token:str=Depends(JWTBearer())):

return ops_inference(generate.code_block,generate.api_key,user_sub)


@app.get("/auth/verify/{token}", summary="Verify Email", response_model=GeneralResponse, tags=["Auth Server"])
async def verify_email(request: Request, token:str):
response_result = GeneralResponse.get_instance(data={},
Expand Down
3 changes: 2 additions & 1 deletion TechdocsAPI/backend/services/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .ops import *
from .utils.JWTBearer import *
from .utils.JWTBearer import *
from .utils.functools import *
46 changes: 28 additions & 18 deletions TechdocsAPI/backend/services/auth/ops.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .utils.auth_funcs import *
from .utils.functools import *
from .utils.JWTBearer import *
from backend.models import *
from backend.services.db.utils.DBQueries import DBQueries
Expand All @@ -9,7 +10,6 @@
from fastapi import HTTPException, BackgroundTasks
from pydantic import ValidationError
from jose import jwt
from fastapi_mail import MessageSchema, MessageType

async def ops_signup(bgtasks: BackgroundTasks, response_result: GeneralResponse, data: UserAuth):
"""Wrapper method to handle signup process.
Expand All @@ -29,24 +29,32 @@ async def ops_signup(bgtasks: BackgroundTasks, response_result: GeneralResponse,
if len(list(user)) != 0:
# user with the entered credentials already exists
raise ExistingUserException(response_result)

verifiction_token = Auth.create_access_token(f'{data.username} {data.email}', secret_name='VERIFICATION')
verification_link = f'https://caffeinecrew-techdocs.hf.space/auth/verify/{verifiction_token}'
verifiction_token = Auth.create_access_token(f"{data.username} {data.email}", secret_name='VERIFICATION')
verification_link = f"https://caffeinecrew-techdocs.hf.space/auth/verify/{verifiction_token}"

email_body_params = {
'username': data.username,
'verify_link': verification_link
}

message = MessageSchema(
subject='Welcome to Techdocs:[Account Verification]',
recipients=[data.email],
template_body=email_body_params,
subtype=MessageType.html
)
bgtasks.add_task(app.state.mail_client.send_message, message=message, template_name='email_verification.html')
DBQueries.insert_to_database('auth', (data.username, Auth.get_password_hash(data.password), '', 0), ['username', 'password', 'email', 'is_verified'])
details = {
"recipients": [data.email],
"subject": "Welcome to Techdocs:[Account Verification]",
"template_name": "email_verification.html",
"template_kwargs": email_body_params
}

status = post_request(url=config.MAIL_SERVER_URL, data=details, headers=None)
if status != 200:
raise EmailNotSentException()



DBQueries.insert_to_database('auth', (data.username, Auth.get_password_hash(data.password), "", 0),
['username', 'password', 'email', 'is_verified'])



response_result.status = 'success'
response_result.message = [f'Activate your account by clicking on the link sent to {data.email}.\nMake sure to check your spam folder.']

Expand Down Expand Up @@ -180,7 +188,10 @@ def ops_verify_email(request: Request, response_result: GeneralResponse, token:
"""
try:
payload = jwt.decode(token, config.JWT_VERIFICATION_SECRET_KEY, algorithms=[config.ALGORITHM])
payload = jwt.decode(
token, config.JWT_VERIFICATION_SECRET_KEY, algorithms=[config.ALGORITHM]
)

token_data = TokenPayload(**payload)

if datetime.fromtimestamp(token_data.exp) < datetime.now():
Expand All @@ -195,11 +206,10 @@ def ops_verify_email(request: Request, response_result: GeneralResponse, token:

# print(registered_email[0][0])
if registered_email[0][0]:
return app.state.templates.TemplateResponse('verification_failure.html', context={'request': request})

DBQueries.update_data_in_database('auth', 'is_verified', f"username='{username}'", (True,))
DBQueries.update_data_in_database('auth', 'email', f"username='{username}'", email)

return app.state.templates.TemplateResponse("verification_failure.html", context={"request": request})

DBQueries.update_data_in_database('auth','is_verified',f"username='{username}'", (True,))
DBQueries.update_data_in_database('auth','email',f"username='{username}'", email)
response_result.status = 'success'
response_result.message = [f'Email verified successfully']
return app.state.templates.TemplateResponse('verification_success.html', context={'request': request})
Expand Down
9 changes: 9 additions & 0 deletions TechdocsAPI/backend/services/auth/utils/functools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import requests
from typing import Any, Dict
import json

def post_request(url: str, data: Dict[str, Any], headers: Dict[str, str]=None):
json_data = json.dumps(data)
headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
response = requests.post(url, data=json_data, headers=headers)
return response.status_code
2 changes: 1 addition & 1 deletion TechdocsAPI/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ pydantic[email]
langchain
clarifai
Pillow
fastapi_mail==1.3.1
jinja2
2 changes: 1 addition & 1 deletion techdocs/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ scripts = {techdocs = "techdocs.cli:main"}
packages = ["techdocs", "techdocs.utils"]

[tool.setuptools.package-data]
"*" = ["*.json"]
"*" = ["*.json"]
4 changes: 4 additions & 0 deletions techdocs/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[metadata]
name = techdocs
<<<<<<< HEAD:techdocs/setup.cfg
version = 0.2.0
=======
version = 0.2.1
>>>>>>> 7b80f1bcac446d89a72c4146689db74f434ec4c6:setup.cfg

[options]
packages = techdocs
Expand Down
4 changes: 4 additions & 0 deletions techdocs/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

setup(
name='techdocs',
<<<<<<< HEAD:techdocs/setup.py
version='0.2.0',
=======
version='0.2.1',
>>>>>>> 7b80f1bcac446d89a72c4146689db74f434ec4c6:setup.py
# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
Expand Down
2 changes: 1 addition & 1 deletion techdocs/techdocs/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.1"
__version__ = "0.2.1"
14 changes: 11 additions & 3 deletions techdocs/techdocs/utils/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def get_access_token(data, return_refresh_token=False):
Raises:
None
"""

def get_access_token(data, return_refresh_token=False):
try:
url = BASE_URL + '/auth/login'
headers = {'accept': 'application/json'}
Expand All @@ -27,12 +29,14 @@ def get_access_token(data, return_refresh_token=False):
return (access_token, refresh_token)
return access_token
except Exception as e:
if response.json() == 'exception.InvalidCredentialsException()':
print('Please check your credentials')

if response.json() == "exception.InvalidCredentialsException()":
print("Please check your credentials")
else:
print('Please verify your email before logging in')
return None


def request_inference(config, code_block, max_retries=1):
"""
Request Inference
Expand Down Expand Up @@ -86,6 +90,7 @@ def update_file(file_path, docstr_code):
with open(file_path, 'w', errors='ignore') as file:
file.write(docstr_code)


def issue_api_key(config):
"""
This function generates a new API key for the given user.
Expand Down Expand Up @@ -115,12 +120,15 @@ def signup(config):
def signup(config: dict) -> None:
"""
try:

headers = {'accept': 'application/json'}
response = requests.post(url=BASE_URL + '/auth/signup', headers=headers, data=json.dumps(config))
if response.status_code == 226:
raise Exception('username or email already exists')
elif response.status_code != 200:
raise Exception('Something went wrong, please try again later')
print(response.json()['message'][0].replace('\\n', '\n'), 'Then issue a new `API_KEY` to continue')

print(response.json()["message"][0].replace('\\n','\n'), "Then issue a new `API_KEY` to continue")

except Exception as e:
print(e)

0 comments on commit d597a61

Please sign in to comment.