Skip to content

Commit 3bd4017

Browse files
committed
initial setup
0 parents  commit 3bd4017

File tree

10 files changed

+327
-0
lines changed

10 files changed

+327
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.env
2+
__pycache__
3+
code
4+
.venv

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"scripts": {
3+
"start": "",
4+
"clean": "rm -R .venv",
5+
"setup": "python -m venv .venv",
6+
"install": "pip install -r requirements.txt"
7+
}
8+
}

lazydev/__init__.py

Whitespace-only changes.

lazydev/develop.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
3+
import os
4+
from dotenv import load_dotenv
5+
6+
from lazydev.modules.prompts import PrompBook
7+
from .modules.developer import Developer
8+
9+
10+
11+
def parse_args():
12+
# putting import inside so that code can be moved to saperate files and we dont keep the import at top of this file
13+
import argparse
14+
# Create the argument parser
15+
parser = argparse.ArgumentParser(description='Lazy Dev Argguments')
16+
17+
# Add the "--requirements" argument with the "-r" shortcut
18+
parser.add_argument('--requirement', '-r', required=True, type=str, help='The initial requirement')
19+
20+
# Add the "--directory" argument with the "-d" shortcut
21+
parser.add_argument('--directory', '-d', default="./code", type=str, help='The directory path to put generated files')
22+
23+
24+
args = parser.parse_args()
25+
26+
return args
27+
28+
if __name__ == "__main__":
29+
# print(PrompBook.design_folder_structure("","",""))
30+
args=parse_args()
31+
requirement = args.requirement
32+
directory= args.directory
33+
load_dotenv()
34+
api_key = os.environ.get('OPENAI_API_KEY')
35+
developer =Developer(requirement=requirement,root_dir=directory,openai_api_key=api_key)
36+
developer.develop()

lazydev/modules/__init__.py

Whitespace-only changes.

lazydev/modules/developer.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
from typing import List
3+
from .prompts import PrompBook
4+
from langchain.llms import OpenAI
5+
import json
6+
7+
from .utils import Utilities
8+
9+
class Developer():
10+
def __init__(self, requirement:str,root_dir:str, openai_api_key:str):
11+
self.requirement=requirement
12+
self.root_dir=root_dir
13+
self.api_key=openai_api_key
14+
self.brain = OpenAI(
15+
model_name="gpt-3.5-turbo",
16+
openai_api_key=self.api_key,
17+
temperature=0,
18+
streaming=False
19+
)
20+
21+
def clear_doubts(self):
22+
prompt=PrompBook.expand_requirements(self.requirement)
23+
doubts:str=self.brain(prompt)
24+
doubt_list:List[str]=doubts.split("\n")
25+
doubt_list=[doubt.strip() for doubt in doubt_list if doubt.strip()!=""]
26+
print("""
27+
Hey there! 😄 It's Lazy Dev, your friendly neighborhood programmer, here to make your API service dreams come true! 🎉
28+
But before I dive into coding magic, I have a few fun and important questions for you.
29+
So, grab a cup of coffee ☕️, sit back, and let's clarify some details, shall we? Here we go! 🚀
30+
""")
31+
answer_list=[]
32+
for doubt in doubt_list:
33+
answer = input(f"{doubt}\n>>")
34+
answer_list.append(answer)
35+
36+
print("""
37+
Thats all I need! 😄
38+
39+
Sit back and relax while I work my coding magic for you! ✨✨✨
40+
41+
🚀 I've got this! 🎉
42+
43+
Cheers! 👨‍💻
44+
""")
45+
return doubt_list,answer_list
46+
47+
def plan_project(self):
48+
prompt=PrompBook.plan_project(self.requirement,self.clarifications)
49+
plannings:str=self.brain(prompt)
50+
return plannings
51+
52+
def generate_folder_structure(self):
53+
prompt=PrompBook.design_folder_structure(
54+
question=self.requirement,
55+
plan=self.plannings,
56+
clarifications=self.clarifications
57+
)
58+
folder_tree_str:str=self.brain(prompt)
59+
folder_tree:dict=json.loads(folder_tree_str)
60+
Utilities.generate_files_and_folders(structure=folder_tree,root_dir=self.root_dir)
61+
62+
63+
def develop(self):
64+
# clearing all doubts
65+
doubts,answers=self.clear_doubts()
66+
self.clarifications:str=""
67+
for i in range(len(doubts)):
68+
self.clarifications=f"{self.clarifications}\n\n{i+1}. {doubts[i]}\n Ans: {answers[i]}"
69+
70+
# planning the project
71+
print("Planning...")
72+
self.plannings=self.plan_project()
73+
# creating files and folders for the project
74+
print("Creating files...")
75+
self.generate_folder_structure()
76+
77+
78+
79+

lazydev/modules/prompts.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
2+
class PrompBook:
3+
@staticmethod
4+
def expand_requirements(question:str)->str:
5+
return f"""
6+
you are a senior programmer below is what your client have asked you to do:
7+
---
8+
{question}
9+
---
10+
11+
your current task is to list down all the clarifications you need from the client:
12+
dont ask anything like budget or timelines and other business related stuff.
13+
14+
As your response will go to an automated parser, things to keep in mind all the time:
15+
* write one questions per line
16+
* don't write anything other than the questions.
17+
* use emojis in the question to make them fun.
18+
* Remember the client is a non technical person so ask question accordingly
19+
20+
Begin!
21+
"""
22+
@staticmethod
23+
def plan_project(question:str, clarification:str)->str:
24+
return f"""
25+
you are a senior programmer below is what your client have asked you to do:
26+
---
27+
{question}
28+
---
29+
here are some clarrification on the requirements
30+
---
31+
{clarification}
32+
---
33+
your current task is to design the folder and and files structure for this project
34+
you should follow the below format to answer this question
35+
36+
Plan : <your plan here> //tell us a very detailed, verbose plan or thought on how you want to proceed before writing the files for example which framework you are going to use
37+
38+
As your response will go to an automated parser, things to keep in mind all the time:
39+
* follow the exact format provided above without fail
40+
* the folder and files structure should be complete, means means no additional files will be required to create to run the program, for example if its nodejs project add package.json if its a python project add requirements.txt etc..
41+
* do not write the contents of the files that will be done by the next devepoler
42+
Begin!
43+
"""
44+
@staticmethod
45+
def design_folder_structure(question:str,plan:str,clarifications:str)->str:
46+
return f"""
47+
you are a senior programmer below is what your client have asked you to do:
48+
---
49+
{question}
50+
---
51+
here are some clarrification on the requirements
52+
---
53+
{clarifications}
54+
---
55+
below is the what you have already planed what to do:
56+
---
57+
{plan}
58+
---
59+
Now based on this write a json object to design file tree.
60+
61+
```
62+
{{
63+
"root_dir_name": "name of the project",
64+
"files": [
65+
{{
66+
"name": "name of the file",
67+
"type":"file/directory",
68+
"files": [...] //repeat the same pattern if its a directory
69+
}}
70+
]
71+
}}
72+
```
73+
As your response will go to an automated parser, things to keep in mind all the time:
74+
* follow the exact format provided above without fail
75+
* only write the json nothing else, no expiation, no pretext
76+
* do not write the contents of the files that will be done by the next developer
77+
Begin!
78+
"""
79+

lazydev/modules/utils.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import os
2+
from typing import List, Dict
3+
4+
class Utilities:
5+
@staticmethod
6+
def touch(path):
7+
with open(path, 'a'):
8+
os.utime(path, None)
9+
10+
@staticmethod
11+
def generate_files_recursively(files:List[Dict],cur_dir:str):
12+
for file in files:
13+
name=file['name']
14+
type=file['type']
15+
item_path=os.path.join(cur_dir,name)
16+
if type=="file":
17+
Utilities.touch(item_path)
18+
print(f"Created File: {item_path}")
19+
else:
20+
if not os.path.exists(item_path):
21+
os.makedirs(item_path)
22+
print(f"Created Directory: {item_path}")
23+
subfiles:List[Dict]=file['files']
24+
Utilities.generate_files_recursively(subfiles,item_path)
25+
26+
@staticmethod
27+
def generate_files_and_folders(structure:dict,root_dir:str):
28+
root_dir_name=structure['root_dir_name']
29+
cur_dir=os.path.join(root_dir,root_dir_name)
30+
if not os.path.exists(cur_dir):
31+
os.makedirs(cur_dir)
32+
print(f"Created Directory: {cur_dir}")
33+
files:List[Dict]=structure['files']
34+
Utilities.generate_files_recursively(files=files,cur_dir=cur_dir)

manage.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import subprocess
2+
3+
def read_config():
4+
import json
5+
# Opening JSON file
6+
f = open('./config.json')
7+
8+
# returns JSON object as
9+
# a dictionary
10+
data = json.load(f)
11+
12+
f.close()
13+
return data
14+
15+
16+
def parse_args():
17+
# putting import inside so that code can be moved to saperate files and we dont keep the import at top of this file
18+
import argparse
19+
# Create the argument parser
20+
parser = argparse.ArgumentParser(description='Lazy Dev Argguments')
21+
22+
# Add the "--task" argument with the "-t" shortcut
23+
parser.add_argument('--run', '-r', type=str, help='The script to run')
24+
25+
args = parser.parse_args()
26+
27+
return args
28+
29+
30+
def execute_config_script(script_name:str,config:dict):
31+
scripts:dict=config['scripts']
32+
command:str=scripts[script_name]
33+
34+
# Execute the command
35+
result = subprocess.run(command, shell=True, capture_output=True, text=True)
36+
37+
# Check the return code
38+
if result.returncode == 0:
39+
# Command was successful
40+
print("Command executed successfully.")
41+
# Print the command output
42+
print("Command output:")
43+
print(result.stdout)
44+
else:
45+
# Command failed
46+
print("Command failed with return code:", result.returncode)
47+
# Print the error message
48+
print("Error message:")
49+
print(result.stderr)
50+
51+
52+
if __name__ == "__main__":
53+
args=parse_args()
54+
command = args.run
55+
config=read_config()
56+
execute_config_script(command,config)
57+
58+

requirements.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
aiohttp==3.8.4
2+
aiosignal==1.3.1
3+
async-timeout==4.0.2
4+
attrs==23.1.0
5+
certifi==2023.5.7
6+
charset-normalizer==3.1.0
7+
dataclasses-json==0.5.7
8+
frozenlist==1.3.3
9+
idna==3.4
10+
langchain==0.0.188
11+
marshmallow==3.19.0
12+
marshmallow-enum==1.5.1
13+
multidict==6.0.4
14+
mypy-extensions==1.0.0
15+
numexpr==2.8.4
16+
numpy==1.24.3
17+
openai==0.27.7
18+
openapi-schema-pydantic==1.2.4
19+
packaging==23.1
20+
pydantic==1.10.8
21+
PyYAML==6.0
22+
requests==2.31.0
23+
SQLAlchemy==2.0.15
24+
tenacity==8.2.2
25+
tqdm==4.65.0
26+
typing-inspect==0.9.0
27+
typing_extensions==4.6.2
28+
urllib3==2.0.2
29+
yarl==1.9.2

0 commit comments

Comments
 (0)