mayureshagashe2105 commited on
Commit
808bf67
1 Parent(s): 4e54bd9
.gitignore CHANGED
@@ -15,4 +15,6 @@ tempCodeRunnerFile.py
15
  #pypi files
16
  build
17
  dist
18
- techdocs.egg-info
 
 
 
15
  #pypi files
16
  build
17
  dist
18
+ techdocs.egg-info
19
+
20
+ test.py
TechdocsAPI/backend/core/Exceptions.py CHANGED
@@ -13,7 +13,7 @@ class InvalidCredentialsException(Exception):
13
  self.token_result.status = 'login_failed'
14
 
15
  def __repr__(self):
16
- return json.dumps(self.token_result)
17
 
18
  class ExistingUserException(Exception):
19
  def __init__(self, response_result: GeneralResponse):
@@ -27,7 +27,7 @@ class ExistingUserException(Exception):
27
  self.response_result.message[0] = 'authenticated'
28
 
29
  def __repr__(self):
30
- return json.dumps(self.response_result)
31
 
32
  class InfoNotFoundException(Exception):
33
  def __init__(self, response_result: GeneralResponse, message: str):
@@ -42,4 +42,4 @@ class InfoNotFoundException(Exception):
42
  self.response_result['message'].append(self.message)
43
 
44
  def __repr__(self):
45
- return json.dumps(self.response_result)
 
13
  self.token_result.status = 'login_failed'
14
 
15
  def __repr__(self):
16
+ return "exception.InvalidCredentialsException()"
17
 
18
  class ExistingUserException(Exception):
19
  def __init__(self, response_result: GeneralResponse):
 
27
  self.response_result.message[0] = 'authenticated'
28
 
29
  def __repr__(self):
30
+ return "exception.ExistingUserException()"
31
 
32
  class InfoNotFoundException(Exception):
33
  def __init__(self, response_result: GeneralResponse, message: str):
 
42
  self.response_result['message'].append(self.message)
43
 
44
  def __repr__(self):
45
+ return "exception.InfoNotFoundException()"
TechdocsAPI/backend/models/inference.py CHANGED
@@ -3,4 +3,8 @@ from typing import List
3
  from .generic import Base
4
 
5
  class Inference(Base):
6
- docstr:str
 
 
 
 
 
3
  from .generic import Base
4
 
5
  class Inference(Base):
6
+ docstr:str
7
+
8
+ class Generate(Base):
9
+ code_block:str
10
+ api_key:str
TechdocsAPI/backend/router.py CHANGED
@@ -22,7 +22,6 @@ def api_home():
22
 
23
  @app.get("/api/response_check", tags=["Resource Server"])
24
  def api_response_check():
25
- print("api_response_check")
26
  response_result = GeneralResponse.get_instance(data={},
27
  status="not_allowed",
28
  message=["Not authenticated"]
@@ -38,13 +37,12 @@ def api_response_check():
38
  response_result.message.append(db_msg)
39
 
40
  except Exception as e:
41
- print("Exception :", e)
42
 
43
  return response_result
44
 
45
  @app.post("/auth/signup", summary="Creates new user account", response_model=GeneralResponse, tags=["Auth Server"])
46
  async def signup(response: UserAuth):
47
- print("signup")
48
  response_result = GeneralResponse.get_instance(data={},
49
  status="not_allowed",
50
  message=["Not authenticated"]
@@ -59,14 +57,12 @@ async def login(response:LoginCreds):
59
 
60
  @app.put("/auth/regenerate_api_key",summary="Forget Password",response_model=APIKey,tags=["Auth Server"],dependencies=[Depends(JWTBearer())])
61
  async def regenerate_api_key(access_token: str = Depends(JWTBearer())):
62
- print("regenerate_api_key")
63
  user_sub=Auth.get_user_credentials(access_token)
64
 
65
  return ops_regenerate_api_key(user_sub)
66
 
67
  @app.post("/api/inference", summary="Inference", response_model=Inference, tags=["Resource Server"], dependencies=[Depends(JWTBearer())])
68
- async def inference(code_block:str, api_key: str,access_token:str=Depends(JWTBearer())):
69
- print("inference")
70
  user_sub=Auth.get_user_credentials(access_token)
71
 
72
- return ops_inference(code_block,api_key,user_sub)
 
22
 
23
  @app.get("/api/response_check", tags=["Resource Server"])
24
  def api_response_check():
 
25
  response_result = GeneralResponse.get_instance(data={},
26
  status="not_allowed",
27
  message=["Not authenticated"]
 
37
  response_result.message.append(db_msg)
38
 
39
  except Exception as e:
40
+ pass
41
 
42
  return response_result
43
 
44
  @app.post("/auth/signup", summary="Creates new user account", response_model=GeneralResponse, tags=["Auth Server"])
45
  async def signup(response: UserAuth):
 
46
  response_result = GeneralResponse.get_instance(data={},
47
  status="not_allowed",
48
  message=["Not authenticated"]
 
57
 
58
  @app.put("/auth/regenerate_api_key",summary="Forget Password",response_model=APIKey,tags=["Auth Server"],dependencies=[Depends(JWTBearer())])
59
  async def regenerate_api_key(access_token: str = Depends(JWTBearer())):
 
60
  user_sub=Auth.get_user_credentials(access_token)
61
 
62
  return ops_regenerate_api_key(user_sub)
63
 
64
  @app.post("/api/inference", summary="Inference", response_model=Inference, tags=["Resource Server"], dependencies=[Depends(JWTBearer())])
65
+ async def inference(generate: Generate, access_token:str=Depends(JWTBearer())):
 
66
  user_sub=Auth.get_user_credentials(access_token)
67
 
68
+ return ops_inference(generate.code_block,generate.api_key,user_sub)
TechdocsAPI/backend/services/auth/ops.py CHANGED
@@ -3,6 +3,7 @@ from .utils.JWTBearer import *
3
  from backend.models import *
4
  from backend.services.db.utils.DBQueries import DBQueries
5
  from backend.core.Exceptions import *
 
6
  from backend import app
7
 
8
  # import openai
@@ -101,9 +102,7 @@ def ops_inference(source_code:str,api_key:str,username:str):
101
 
102
  llm_response = app.state.llmchain.run({"instruction": source_code_message})
103
 
104
- docstring = Inference(docstr=llm_response)
105
- print(docstring)
106
-
107
 
108
  return docstring
109
 
 
3
  from backend.models import *
4
  from backend.services.db.utils.DBQueries import DBQueries
5
  from backend.core.Exceptions import *
6
+ from backend.core.ExceptionHandlers import *
7
  from backend import app
8
 
9
  # import openai
 
102
 
103
  llm_response = app.state.llmchain.run({"instruction": source_code_message})
104
 
105
+ docstring = Inference(docstr=llm_response)
 
 
106
 
107
  return docstring
108
 
TechdocsAPI/backend/services/db/utils/DBQueries.py CHANGED
@@ -13,7 +13,6 @@ class DBQueries:
13
  f'({",".join(cols)}) '
14
  'VALUES '
15
  ).format(table_name=table_name)
16
- print(data)
17
  if isinstance(data, list):
18
  QUERY+="("+",".join(["%s" for _ in range(len(data[0]))])+")"
19
  cursor.executemany(QUERY, data)
 
13
  f'({",".join(cols)}) '
14
  'VALUES '
15
  ).format(table_name=table_name)
 
16
  if isinstance(data, list):
17
  QUERY+="("+",".join(["%s" for _ in range(len(data[0]))])+")"
18
  cursor.executemany(QUERY, data)
frontend/pages/Code.py CHANGED
@@ -92,7 +92,8 @@ def code_page():
92
  if st.button("🤖 Generate Documentation"):
93
  if code_input:
94
  headers['Authorization'] = f"Bearer {st.session_state.access_token}"
95
- response = query_post(base_url + '/api/inference', headers=headers, params={'code_block':code_input, 'api_key':API_KEY})
 
96
  docstr = response.json()["docstr"]
97
  comment_placeholder.subheader("Generated Documentation:")
98
  comment_placeholder.markdown(f"<pre><code>{docstr}</code></pre>", unsafe_allow_html=True)
 
92
  if st.button("🤖 Generate Documentation"):
93
  if code_input:
94
  headers['Authorization'] = f"Bearer {st.session_state.access_token}"
95
+ response = query_post(base_url + '/api/inference', headers=headers,
96
+ data=json.dumps({'code_block':code_input, 'api_key':API_KEY}))
97
  docstr = response.json()["docstr"]
98
  comment_placeholder.subheader("Generated Documentation:")
99
  comment_placeholder.markdown(f"<pre><code>{docstr}</code></pre>", unsafe_allow_html=True)
techdocs/__init__.py CHANGED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "0.1.0"
techdocs/cli.py CHANGED
@@ -1,36 +1,56 @@
1
- from .utils import parse,functools
2
 
3
- import argparse
4
 
5
- def main():
6
- parser = argparse.ArgumentParser(
7
- description='Code documentation generation',
8
- epilog="Thanks for using Techdocs")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
- parser.add_argument('--api_key','-k',type=str,required=True,help='API key for Techdocs')
11
 
12
- parser.add_argument('--username','-u',type=str,required=True,help='Username for Techdocs')
13
 
14
- parser.add_argument('--password','-p',type=str,required=True,help='Password for Techdocs')
15
 
16
- parser.add_argument('--dir','-d',type=str,required=True,help='Root directory to be documented')
17
 
18
- parser.add_argument('--version','-v',action='version',version="%(prog)s 0.0.1")
19
 
20
- args=parser.parse_args()
21
 
22
- config = {
23
- arg[0]:arg[1] for arg in args._get_kwargs()
24
- }
25
 
26
- data = {
27
- "username":config['username'],
28
- "password":config['password']
29
- }
30
 
31
- config.update({"access_token":functools.get_access_token(data)})
32
 
33
- parse.extract_functions_from_directory(config)
34
 
35
  if __name__ == '__main__':
36
- main()
 
1
+ from .ops import Ops
2
 
 
3
 
4
+ @Ops.configure_and_build_subcommand
5
+ def main(log_info: bool = False):
6
+ if log_info:
7
+ print(
8
+ """
9
+
10
+ 👋 Hi there! Welcome to techdocs. Here are some cool things you can do:
11
+
12
+
13
+ 💫 try out a demo with or new GUI 🚀 and explore how to use the CLI:
14
+
15
+ ➡️ https://techdocs.streamlit.app/
16
+
17
+ 💫 signup here to get an API key 👤:
18
+
19
+ $ techdocs signup -u <username> -p <password> -e <email>
20
+
21
+ 💫 use the line below to issue a new API key 🗝️:
22
+
23
+ $ techdocs apikey -u <username> -p <password>
24
+
25
+ 💫 use the CLI to generate documentation for your project 📚:
26
+
27
+ $ techdocs generate -k <api_key> -u <username> -p <password> -d <directory>
28
+
29
+ """
30
+ )
31
 
32
+ # parser.add_argument('--api_key','-k',type=str,required=True,help='API key for Techdocs')
33
 
34
+ # parser.add_argument('--username','-u',type=str,required=True,help='Username for Techdocs')
35
 
36
+ # parser.add_argument('--password','-p',type=str,required=True,help='Password for Techdocs')
37
 
38
+ # parser.add_argument('--dir','-d',type=str,required=True,help='Root directory to be documented')
39
 
40
+ # # parser.add_argument('--version','-v',action='version',version="%(prog)s 0.0.1")
41
 
42
+ # args=parser.parse_args()
43
 
44
+
 
 
45
 
46
+ # data = {
47
+ # "username":config['username'],
48
+ # "password":config['password']
49
+ # }
50
 
51
+ # config.update({"access_token":functools.get_access_token(data)})
52
 
53
+ # parse.extract_functions_from_directory(config)
54
 
55
  if __name__ == '__main__':
56
+ main()
techdocs/dtypes.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ data_types = {'str': str,
2
+ 'int': int,
3
+ 'float': float,
4
+ 'bool': bool
5
+ }
techdocs/ops.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import json
3
+ from typing import Dict, List, Optional, Any, Callable
4
+
5
+ import techdocs
6
+ from .dtypes import data_types
7
+ from .utils.functools import *
8
+ from .utils.parse import *
9
+
10
+
11
+ parser = argparse.ArgumentParser(
12
+ description='Code documentation generation',
13
+ epilog="Thanks for using Techdocs")
14
+ subparsers = parser.add_subparsers(help='subcommands')
15
+
16
+
17
+ def depends_login(func: Callable):
18
+ def update_config(cls: Any, config: Dict[str, Any]):
19
+ data = {
20
+ "username":config['username'],
21
+ "password":config['password']
22
+ }
23
+
24
+ config.update({"access_token":get_access_token(data)})
25
+ return func(cls, config)
26
+ return update_config
27
+
28
+
29
+ class _SubCommand:
30
+ def __init__(self, name: str, help: str, args_parse: Optional[List[Dict[str, Any]]] = None, pre_compile: bool = False):
31
+ self.name = name
32
+ self.parser = subparsers.add_parser(name, help=help)
33
+ self.parser.set_defaults(subcommand=name)
34
+
35
+ self.pre_compile = pre_compile
36
+
37
+ if args_parse and pre_compile:
38
+ self.build(args_parse)
39
+ else:
40
+ self.arg_parse = args_parse
41
+
42
+ def _run(self):
43
+ raise NotImplementedError()
44
+
45
+ def build(self, args_parse: Optional[List[Dict[str, Any]]] = None):
46
+ if not args_parse:
47
+ args_parse = self.arg_parse
48
+
49
+ if not isinstance(args_parse, list):
50
+ args_parse = list(args_parse)
51
+
52
+ for args_sig in args_parse:
53
+ args_sig['kwargs']['type'] = data_types[args_sig['kwargs']['type']]
54
+ self.parser.add_argument(*args_sig['args'], **args_sig['kwargs'])
55
+
56
+ @property
57
+ def bind(self):
58
+ raise PermissionError('Property bind is not allowed to be accessed')
59
+
60
+ @bind.setter
61
+ def bind(self, func: Callable):
62
+ self._run = func
63
+ self.parser.set_defaults(ops=self._run)
64
+
65
+
66
+
67
+
68
+ class Ops:
69
+ sub_commands: Dict[str, _SubCommand] = {}
70
+ with open('techdocs/utils/subcommand_signatures.json') as f:
71
+ encoded_sub_commands = json.load(f)
72
+
73
+
74
+ if encoded_sub_commands['dynamic signatures']:
75
+ sub_commands.update({sub_command['name']: _SubCommand(**sub_command, pre_compile=False)
76
+ for sub_command in encoded_sub_commands['dynamic signatures']
77
+ })
78
+
79
+ if encoded_sub_commands['pre-compiled signatures']:
80
+ sub_commands.update({sub_command['name']: _SubCommand(**sub_command, pre_compile=True)
81
+ for sub_command in encoded_sub_commands['pre-compiled signatures']
82
+ })
83
+
84
+ @classmethod
85
+ def configure_and_build_subcommand(cls, func):
86
+ config = None
87
+ try:
88
+ args = parser.parse_args()
89
+ sub_command = cls.sub_commands[args.subcommand]
90
+
91
+ if not sub_command.pre_compile:
92
+ sub_command.build()
93
+
94
+
95
+ sub_command.bind = cls.__getattribute__(cls(), args.subcommand)
96
+
97
+ func = sub_command.parser.get_default('ops')
98
+ config = {k: v for k, v in vars(args).items() if k not in ['subcommand', 'ops']}
99
+
100
+ except AttributeError as e:
101
+ config = True
102
+
103
+ def run_subcommand(**kwargs):
104
+ return func(config)
105
+ return run_subcommand
106
+
107
+
108
+ @classmethod
109
+ @depends_login
110
+ def generate(cls, config: Dict[str, Any]):
111
+ extract_functions_from_directory(config)
112
+
113
+ @classmethod
114
+ @depends_login
115
+ def apikey(cls, config: Dict[str, Any]):
116
+ issue_api_key(config)
117
+
118
+ @classmethod
119
+ def signup(cls, config: Dict[str, Any]):
120
+ signup(config)
121
+
122
+ @classmethod
123
+ def version(cls, config: Dict[str, Any]):
124
+ print(f"{techdocs.__version__}")
techdocs/utils/functools.py CHANGED
@@ -1,22 +1,27 @@
1
  import json
2
  import requests
3
 
4
- BASE_URL = "https://caffeinecrew-techdocs.hf.space"
 
5
 
6
 
7
 
8
  def get_access_token(data, return_refresh_token=False):
9
- url = BASE_URL + "/auth/login"
10
- headers = {
11
- "accept": "application/json",
12
- }
13
- data = json.dumps(data)
14
- response = requests.post(url, data=data, headers=headers)
15
- access_token = response.json()['access_token']
16
- if return_refresh_token:
17
- refresh_token = response.json()['refresh_token']
18
- return access_token, refresh_token
19
- return access_token
 
 
 
 
20
 
21
 
22
 
@@ -29,7 +34,7 @@ def request_inference(config, code_block, max_retries=1):
29
  url = BASE_URL+"/api/inference"
30
  headers={"accept":"application/json", "Authorization": f"Bearer {config['access_token']}"}
31
  code_input = code_block
32
- response = requests.post(url=url, headers=headers, params={'code_block':code_input, 'api_key':config['api_key']})
33
  if response.status_code == 200:
34
  return response.json()["docstr"]
35
  else:
@@ -47,4 +52,31 @@ def update_file(file_path, docstr_code):
47
  with open(file_path, "w",errors='ignore') as file:
48
  file.write(docstr_code)
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
 
 
 
 
 
1
  import json
2
  import requests
3
 
4
+ # BASE_URL = "https://caffeinecrew-techdocs.hf.space"
5
+ BASE_URL = "http://127.0.0.1:8000"
6
 
7
 
8
 
9
  def get_access_token(data, return_refresh_token=False):
10
+ try:
11
+ url = BASE_URL + "/auth/login"
12
+ headers = {
13
+ "accept": "application/json",
14
+ }
15
+ data = json.dumps(data)
16
+ response = requests.post(url, data=data, headers=headers)
17
+ access_token = response.json()['access_token']
18
+ if return_refresh_token:
19
+ refresh_token = response.json()['refresh_token']
20
+ return access_token, refresh_token
21
+ return access_token
22
+ except Exception as e:
23
+ print("Invlaid Credentials")
24
+ return None
25
 
26
 
27
 
 
34
  url = BASE_URL+"/api/inference"
35
  headers={"accept":"application/json", "Authorization": f"Bearer {config['access_token']}"}
36
  code_input = code_block
37
+ response = requests.post(url=url, headers=headers, data=json.dumps({'code_block':code_input, 'api_key':config['api_key']}))
38
  if response.status_code == 200:
39
  return response.json()["docstr"]
40
  else:
 
52
  with open(file_path, "w",errors='ignore') as file:
53
  file.write(docstr_code)
54
 
55
+
56
+
57
+ def issue_api_key(config):
58
+ try:
59
+ headers={"accept":"application/json", "Authorization": f"Bearer {config['access_token']}"}
60
+ response = requests.put(url=BASE_URL + "/auth/regenerate_api_key", headers=headers,
61
+ data=json.dumps({"username": config['username']})
62
+ )
63
+ if (response.status_code!=200):
64
+ raise Exception("API Key Generation Failed")
65
+ print(f"$ API_KEY: {response.json()['api_key']}")
66
+ except Exception as e:
67
+ print(f"$ {e}")
68
+
69
+
70
+ def signup(config):
71
+ try:
72
+ headers={"accept":"application/json"}
73
+ response = requests.post(url=BASE_URL + "/auth/signup", headers=headers, data=json.dumps(config))
74
+ if (response.status_code==226):
75
+ raise Exception("username or email already exists")
76
+ elif (response.status_code!=200):
77
+ raise Exception("Something went wrong, please try again later")
78
 
79
+ print("Signed up successfully, please issue a new `API_KEY` to continue")
80
+
81
+ except Exception as e:
82
+ print(e)
techdocs/utils/subcommand_signatures.json ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pre-compiled signatures":
3
+ [
4
+ {
5
+ "name": "generate",
6
+ "help": "Generate Documentation from a given directory root",
7
+ "args_parse":
8
+ [
9
+ {"args": ["--api_key", "-k"], "kwargs": {"type": "str", "required": true, "help": "API key for techdocs"}},
10
+ {"args": ["--username", "-u"], "kwargs": {"type": "str", "required": true, "help": "Username for techdocs"}},
11
+ {"args": ["--password", "-p"], "kwargs": {"type": "str", "required": true, "help": "Password for techdocs"}},
12
+ {"args": ["--dir", "-d"], "kwargs": {"type": "str", "required": true, "help": "Root directory to be documented"}}
13
+ ]
14
+ },
15
+ {
16
+ "name": "apikey",
17
+ "help": "Issue a new API key for techdocs",
18
+ "args_parse":
19
+ [
20
+ {"args": ["-username", "-u"], "kwargs": {"type": "str", "required": true, "help": "Username for techdocs"}},
21
+ {"args": ["-password", "-p"], "kwargs": {"type": "str", "required": true, "help": "Password for techdocs"}}
22
+ ]
23
+ },
24
+ {
25
+ "name": "version",
26
+ "help": "Print the version of the techdocs CLI",
27
+ "args_parse": []
28
+ },
29
+ {
30
+ "name": "signup",
31
+ "help": "Sign up for a new techdocs account",
32
+ "args_parse":
33
+ [
34
+ {"args": ["-username", "-u"], "kwargs": {"type": "str", "required": true, "help": "Username for Techdocs"}},
35
+ {"args": ["-password", "-p"], "kwargs": {"type": "str", "required": true, "help": "Password for Techdocs"}},
36
+ {"args": ["-email", "-e"], "kwargs": {"type": "str", "required": true, "help": "Email for techdocs"}}
37
+ ]
38
+ }
39
+ ],
40
+ "dynamic signatures":
41
+ [
42
+
43
+ ]
44
+ }
45
+
testing/DBQueries.py CHANGED
@@ -9,10 +9,25 @@ class DBQueries:
9
 
10
  @classmethod
11
  def insert_to_database(cls, table_name: str, data: Union[Tuple, List[Tuple]], cols: List[str]=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  con = DBConnection.get_client()
13
  cursor = con.cursor()
14
  QUERY = f"INSERT INTO {{table_name}} ({','.join(cols)}) VALUES ".format(table_name=table_name)
15
- print(data)
16
  if isinstance(data, list):
17
  QUERY += '(' + ','.join(['%s' for _ in range(len(data[0]))]) + ')'
18
  cursor.executemany(QUERY, data)
@@ -23,6 +38,22 @@ class DBQueries:
23
 
24
  @classmethod
25
  def fetch_data_from_database(cls, table_name: str, cols_to_fetch: Union[str, List[str]], where_clause: str=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  con = DBConnection.get_client()
27
  cursor = con.cursor()
28
  if isinstance(cols_to_fetch, str):
@@ -36,6 +67,21 @@ class DBQueries:
36
 
37
  @classmethod
38
  def update_data_in_database(cls, table_name: str, cols_to_update: Union[str, List[str]], where_clause: str=None, new_values: Union[str, List[str]]=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  con = DBConnection.get_client()
40
  cursor = con.cursor()
41
  if isinstance(cols_to_update, str):
 
9
 
10
  @classmethod
11
  def insert_to_database(cls, table_name: str, data: Union[Tuple, List[Tuple]], cols: List[str]=None):
12
+ """
13
+ This method is used to insert data into a specified table in the database.
14
+
15
+ Args:
16
+ table_name (str): The name of the table into which the data will be inserted.
17
+ data (Union[Tuple, List[Tuple]]): The data to be inserted into the table. It can be either a tuple or a list of tuples.
18
+ cols (List[str], optional): A list of column names in the table. If not provided, the method will assume all columns are needed. Defaults to None.
19
+
20
+ Raises:
21
+ Exception: If the data type of 'data' is not a tuple or a list of tuples.
22
+
23
+ Returns:
24
+ None
25
+ """
26
+ "\n This method is used to insert data into a specified table in the database.\n\n Args:\n table_name (str): The name of the table into which the data will be inserted.\n data (Union[Tuple, List[Tuple]]): The data to be inserted into the table. It can be either a tuple or a list of tuples.\n cols (List[str], optional): A list of column names in the table. If not provided, the method will assume all columns are needed. Defaults to None.\n\n Raises:\n Exception: If the data type of 'data' is not a tuple or a list of tuples.\n\n Returns:\n None\n "
27
+ "\n This method is used to insert data into a specified table in the database.\n\n Args:\n table_name (str): The name of the table into which the data will be inserted.\n data (Union[Tuple, List[Tuple]]): The data to be inserted into the table. It can be either a tuple or a list of tuples.\n cols (List[str], optional): A list of column names in the table. If not provided, the method will assume all columns are needed. Defaults to None.\n\n Raises:\n Exception: If the data type of 'data' is not a tuple or a list of tuples.\n\n Returns:\n None\n "
28
  con = DBConnection.get_client()
29
  cursor = con.cursor()
30
  QUERY = f"INSERT INTO {{table_name}} ({','.join(cols)}) VALUES ".format(table_name=table_name)
 
31
  if isinstance(data, list):
32
  QUERY += '(' + ','.join(['%s' for _ in range(len(data[0]))]) + ')'
33
  cursor.executemany(QUERY, data)
 
38
 
39
  @classmethod
40
  def fetch_data_from_database(cls, table_name: str, cols_to_fetch: Union[str, List[str]], where_clause: str=None):
41
+ """
42
+ This method fetches data from a specified table in the database based on the specified column(s) and optional WHERE clause.
43
+
44
+ Args:
45
+ table_name (str): The name of the table from which to fetch data.
46
+ cols_to_fetch (Union[str, List[str]]): The column(s) to fetch from the table. Can be a single string or a list of strings.
47
+ If a single string, it will be treated as a comma-separated list of columns.
48
+ where_clause (str, optional): An optional WHERE clause to filter the data. Defaults to None.
49
+
50
+ Returns:
51
+ List[List[str]]: A list of lists, where each inner list represents a row of data fetched from the database.
52
+ The order of the columns in the inner lists corresponds to the order specified in the cols_to_fetch parameter.
53
+
54
+ Raises:
55
+ None
56
+ """
57
  con = DBConnection.get_client()
58
  cursor = con.cursor()
59
  if isinstance(cols_to_fetch, str):
 
67
 
68
  @classmethod
69
  def update_data_in_database(cls, table_name: str, cols_to_update: Union[str, List[str]], where_clause: str=None, new_values: Union[str, List[str]]=None):
70
+ """
71
+ This method updates the data in the specified table in the database.
72
+
73
+ Args:
74
+ table_name (str): The name of the table to be updated.
75
+ cols_to_update (Union[str, List[str]]): The column(s) to be updated. If a single string, it should end with '=%s'. If a list, it should contain strings representing the column names followed by '=%s'.
76
+ where_clause (str, optional): The WHERE clause to specify the conditions for the update. Defaults to None.
77
+ new_values (Union[str, List[str]], optional): The new values to be updated in the specified columns. If a single string, it should be a list of values. If a list, it should contain the new values for the columns. Defaults to None.
78
+
79
+ Returns:
80
+ bool: Returns True if the update is successful.
81
+
82
+ Raises:
83
+ Exception: Raises an exception if the database connection fails.
84
+ """
85
  con = DBConnection.get_client()
86
  cursor = con.cursor()
87
  if isinstance(cols_to_update, str):
testing/test.py CHANGED
@@ -1,18 +1,107 @@
1
  def add(a, b):
 
 
 
 
 
 
 
 
 
 
 
2
  return a + b
3
 
4
  def multiply(a, b):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  return a * b
6
 
7
  def subtract(a, b):
 
 
 
 
 
 
 
 
 
 
 
8
  return a - b
9
 
10
  def divide(a, b):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  if b == 0:
12
  raise ValueError('Cannot divide by zero')
13
  return a / b
14
 
15
  def func(*args, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def wrapper(*args, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  return func(*args, **kwargs)
18
  return wrapper
 
1
  def add(a, b):
2
+ """
3
+ This function adds two numbers.
4
+
5
+ Arguments:
6
+ a (int): The first number to be added.
7
+ b (int): The second number to be added.
8
+
9
+ Returns:
10
+ int: The sum of the two numbers.
11
+ """
12
+ '\n This function adds two numbers.\n\n Arguments:\n a (int): The first number to be added.\n b (int): The second number to be added.\n\n Returns:\n int: The sum of the two numbers.\n '
13
  return a + b
14
 
15
  def multiply(a, b):
16
+ """
17
+ This function multiplies two numbers.
18
+
19
+ Args:
20
+ a: A number to be multiplied.
21
+ This should be a numeric value (int or float).
22
+ b: Another number to be multiplied.
23
+ This should be a numeric value (int or float).
24
+
25
+ Returns:
26
+ The product of the two numbers.
27
+ This will be a numeric value (int or float), representing the result of the multiplication.
28
+
29
+ Raises:
30
+ None
31
+
32
+ """
33
+ '\n This function multiplies two numbers.\n\n Args:\n a: A number to be multiplied.\n b: Another number to be multiplied.\n\n Returns:\n The product of the two numbers.\n '
34
  return a * b
35
 
36
  def subtract(a, b):
37
+ """
38
+ Subtracts the second number from the first.
39
+
40
+ Args:
41
+ a (int): The first number to be subtracted.
42
+ b (int): The second number to be subtracted from the first.
43
+
44
+ Returns:
45
+ int: The result of the subtraction.
46
+ """
47
+ '\ndef subtract(a, b):\n '
48
  return a - b
49
 
50
  def divide(a, b):
51
+ """
52
+ This function divides the first argument by the second argument.
53
+
54
+ Arguments:
55
+ a (float): The first number to be divided.
56
+ b (float): The second number to be divided.
57
+
58
+ Raises:
59
+ ValueError: If the second argument is zero, it raises a ValueError with the message 'Cannot divide by zero'.
60
+
61
+ Returns:
62
+ float: The result of the division of the first argument by the second argument.
63
+ """
64
+ "\n This function divides the first argument by the second argument.\n\n Arguments:\n a -- The first number to be divided. It should be of type float.\n b -- The second number to be divided. It should be of type float.\n\n Raises:\n ValueError -- If the second argument is zero, it raises a ValueError with the message 'Cannot divide by zero'.\n\n Returns:\n float -- The result of the division of the first argument by the second argument.\n "
65
  if b == 0:
66
  raise ValueError('Cannot divide by zero')
67
  return a / b
68
 
69
  def func(*args, **kwargs):
70
+ """
71
+ Usage: query(input_string, search_terms, search_type='AND')
72
+
73
+ This function searches for specified terms within the input string using a specified search type.
74
+
75
+ Parameters:
76
+ - input_string (str): The string to search within.
77
+ - search_terms (list): A list of strings to search for within the input_string.
78
+ - search_type (str, optional): Specifies how the search_terms should be searched within the input_string.
79
+ Possible values: 'AND' (all search_terms must be present in the input_string), 'OR' (at least one search_term must be present in the input_string). Default is 'AND'.
80
+
81
+ Returns:
82
+ - search_results (list): A list of all occurrences of the search_terms within the input_string.
83
+
84
+ Raises:
85
+ - ValueError: If the search_type is not 'AND' or 'OR'.
86
+ """
87
+ "\nUsage: func(*args, **kwargs)\n\nThis function returns a wrapper function that calls the original function.\n\nParameters:\n- args (tuple): A tuple of non-keyworded arguments to pass to the function.\n- kwargs (dict): A dictionary of keyworded arguments to pass to the function.\n\nReturns:\n- wrapper (function): A new function that calls the original function with the given arguments.\n\nRaises:\n- TypeError: If the arguments passed to the wrapper function do not match the original function's signature.\n"
88
+
89
  def wrapper(*args, **kwargs):
90
+ """
91
+ This function performs a specific operation on the given arguments.
92
+
93
+ Arguments:
94
+ arg1 -- a string argument (default: None)
95
+ arg2 -- an integer argument (default: None)
96
+ arg3 -- a floating point number argument (default: None)
97
+ arg4 -- a boolean argument (default: None)
98
+
99
+ Returns:
100
+ None
101
+
102
+ Raises:
103
+ TypeError -- If any argument is not of the expected type.
104
+ """
105
+ '\n This function acts as a wrapper for another function, allowing it to be called with a variety of arguments.\n\n Arguments:\n *args -- any number of positional arguments (default: None)\n **kwargs -- any number of keyword arguments (default: None)\n\n Returns:\n Whatever the wrapped function returns (default: None)\n\n Raises:\n Whatever exceptions the wrapped function raises (default: None)\n '
106
  return func(*args, **kwargs)
107
  return wrapper