Skip to content

Commit

Permalink
Merge pull request #124 from kookmin-sw/web-main
Browse files Browse the repository at this point in the history
Web main
  • Loading branch information
SangwonYoon authored May 22, 2024
2 parents dcea41c + 1f87f03 commit c6e4886
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 67 deletions.
8 changes: 8 additions & 0 deletions backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
secrets.json
test.ipynb
documents
__pycache__
document.csv
.python-version
.env
.venv
17 changes: 17 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM ubuntu:22.04

RUN apt-get update && apt-get upgrade -y

# install python 3.10
RUN apt-get install -y software-properties-common
RUN add-apt-repository ppa:deadsnakes/ppa -y
RUN apt install python3.10
RUN apt install -y python3-pip

COPY . .

RUN pip3 install -r requirements.txt

WORKDIR /app

EXPOSE 8000
100 changes: 76 additions & 24 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,72 @@
- Default region name : ap-northeast-2 입력
- Default output format : json 입력

### requirments 설치하기
### How to install (without Docker)

- pip install -r requirements.txt
- repository clone

### 서버 실행하기
```shell
git clone https://github.com/kookmin-sw/capstone-2024-05.git
```

- main함수 실행하면 됨.
- app폴더로 이동 후
- uvicorn main:app --reload
- Backend 디렉토리로 이동

```shell
cd backend
```

- Python 가상 환경 설정

```shell
python -m venv .venv
source venv/bin/activate

```

- 필요한 package 설치

```shell
pip install -r requirements.txt
```

- AWS CLI Configure 설정

- 실행

```shell
cd app
uvicorn main:app --host=0.0.0.0 --port=8000
```

### How to install (with Docker)

- repository clone

```shell
git clone https://github.com/kookmin-sw/capstone-2024-05.git
```

- Backend 디렉토리로 이동

```shell
cd backend
```

- Docker 빌드 후 내부 컨테이너 진입

```shell
docker build . -t [image name]
docker run -it -p [host port]:8000 --env-file .env [image name]
```

- AWS CLI Configure 설정

- 실행

```shell
cd app
uvicorn main:app --host=0.0.0.0 --port=8000
```

### ENV

Expand All @@ -40,39 +97,34 @@ OPENAI_APIKEY
### 서버 디렉토리 구조

- /app
- /api : API 코드가 모여있는 폴더입니다.
- /routes : domain별로 구분하여 개발 중입니다.
- /api : Functional APIs
- /routes
- hashtag.py
- templates.py
- users.pu
- main.py
- /db : 데이터베이스 관련 코드가 모여있는 폴더입니다.
- database.py : 현재 운영중인 DB를 연결하는 코드입니다.
- DB의존성 주입을 위한 get_db 메서드가 있습니다.
- 세션 생성, 운영, 종료를 처리해주는 함수입니다.
- DB사용 시에는 이 메서드 사용해주시면 됩니다.
- api 메서드 파라미터에 db: Session = Depends(get_db) 작성해주시고 db 객체 사용해주시면 됩니다.
- router.py
- /db : Database Management
- database.py
- models.py
- /retrieval
- /retrieval : RAG Implementation
- init_vector_db.py
- markdown_splitter.py
- rag_prototype.py
- rag.py
- settings.py
- /static
- /static : Static Files
- /examples
- example-error.json
- example-valid.json
- style.css
- /templates
- item.html
- tmp.json
- /templates : HTML Templates
- main.html
- template-validation-fail.html
- template-validation-success.html
- /utils
- /utils : Utility Modules
- auth.py
- gpt.py
- setup.py
- main.py
- .env
: 데이터베이스 URL을 저장해야합니다. 연락주시면(현승) 별도로 전달드리겠습니다. (DB_URL)
- README.md
- requirements.txt
- Dockerfile
1 change: 0 additions & 1 deletion backend/app/api/routes/hashtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,4 @@ def store_default_to_db(request: Request, db: Session = Depends(get_db)):
db.refresh(isntance)

hashtag = db.query(HashTag).all()
print(hashtag)
return hashtag
49 changes: 23 additions & 26 deletions backend/app/api/routes/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,24 @@

router = APIRouter()

def find_all_type_values(dict_obj):
results = []
def _extract(dict_obj):
if isinstance(dict_obj, dict):
for k, v in dict_obj.items():
if k == "Type":
if v.startswith("AWS::"):
results.append(v.split("::")[1])
if isinstance(v, (dict, list)):
_extract(v)
elif isinstance(dict_obj, list):
for item in dict_obj:
_extract(item)
try:
_extract(dict_obj)
except:
return results
return results

# function to get values of dict
def recursive_value_collect(dict_obj):
Expand All @@ -37,31 +55,9 @@ def recursive_value_collect(dict_obj):
yield value


def parse_prompt_result(result):
template_file, description = [], []
state = False

for l in result.split("\n"):
if "```" in l:
state = not state
continue
if state:
template_file.append(l + "\n")
else:
description.append(l + "\n")

description = "".join(description)
description = description.strip()

template_file = "".join(template_file)
template_file = json.loads(template_file)

return template_file, description


# 해시태그 추가함수
def add_hashtag(template):
hashtags = template.hashtags
hashtags = template.hashtag
hashtags = list(map(lambda x: x.tag, hashtags))
if hashtags:
# dictionary로 변환
Expand Down Expand Up @@ -199,6 +195,9 @@ async def create_template(
filtered_keywords = [
k for k in keywords if k not in ["AWS", "Amazon"] and len(k) > 2
]
type_res = find_all_type_values(template_file)
filtered_keywords += type_res
filtered_keywords = list(set(filtered_keywords))

if not filtered_keywords:
# 사전 정의된 키워드 기반이라 키워드가 없는 경우가 존재함
Expand Down Expand Up @@ -277,9 +276,7 @@ def upload_template(
def validate(params: Template):
try:
is_valid, error_message = validate_template(params.template)
message = (
"유효한 template 입니다." if is_valid else error_message
)
message = "유효한 template 입니다." if is_valid else error_message
return {
"isValid": is_valid,
"message": message,
Expand Down
4 changes: 1 addition & 3 deletions backend/app/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ class PromptAns(Base):
user = relationship("User", back_populates="promptAnses")

# 다대다 관계 설정
hashtags = relationship(
"HashTag", secondary=PromptAns_HashTag, backref="prompt_ans"
)
hashtag = relationship("HashTag", secondary=PromptAns_HashTag, backref="prompt_ans")


class HashTag(Base):
Expand Down
2 changes: 1 addition & 1 deletion backend/app/templates/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<body>
<h1>
<img src="{{ url_for('static', path='stackorderflow-logo-whiteBG.png') }}" alt="StackOrderFlow Logo" width="400">
<img src="{{ url_for('static', path='./stackorderflow-logo-whiteBG.png') }}" alt="StackOrderFlow Logo" width="400">
</h1>
<h2>Back-end Server</h2>
<h3><a href="./docs">-> See API Documnets</a></h3>
Expand Down
4 changes: 0 additions & 4 deletions backend/app/utils/gpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ def validate_template(template: dict):
# 254 명령이 성공적으로 구문 분석되고 지정된 서비스에 요청이 전송되었지만, 서비스에서 오류가 반환되었습니다. 일반적으로 이는 잘못된 API 사용 또는 기타 서비스 특정 문제를 나타냅니다.
# 255 일반적인 캐치올 오류입니다. 명령은 구문 분석이 올바르게 되었을 수 있지만, 명령을 실행하는 동안 명시되지 않은 런타임 오류가 발생했습니다. 이는 일반적인 오류 코드이기 때문에 오류가 255에서 더 구체적인 반환 코드로 변경될 수 있습니다. 255의 반환 코드는 특정한 오류 사례를 결정하기 위해 의존되어서는 안 됩니다.

print(f"{result.returncode=}")
print(f"{result.stderr=}")

is_valid = result.returncode == 0
error_message = "" if is_valid else result.stderr
Expand Down Expand Up @@ -95,7 +93,6 @@ def gpt_genereate(instruction: str, retrieved_doc: List[dict]):
response = completion.choices[0].message.content
template, description = parse_prompt_result(response)
is_valid, error_message = validate_template(template)
print(f"execution_cnt=1, {completion.usage.total_tokens=}")
if is_valid:
doc_title_list = list(set([doc["title"] for doc in retrieved_doc]))
return template, description, doc_title_list, 1
Expand Down Expand Up @@ -164,7 +161,6 @@ def gpt_generate_retry(instruction, retrieved_doc, error_message, wrong_template
response = completion.choices[0].message.content
template, description = parse_prompt_result(response)
is_valid, error_message = validate_template(template)
print(f"{execution_cnt=}, {completion.usage.total_tokens=}")
if is_valid:
doc_title_list = list(set([doc["title"] for doc in retrieved_doc]))
return template, description, doc_title_list, execution_cnt
Expand Down
6 changes: 3 additions & 3 deletions frontend/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function RootLayout({
<body
// className={inter.className}>
>
<MantineProvider theme={theme}>
<MantineProvider theme={theme} defaultColorScheme="light">
<NavigationProgress />
<Header />
{children}
Expand Down
11 changes: 8 additions & 3 deletions frontend/components/TemplateHub/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import Link from 'next/link';
import classes from './TemplateHub.module.css';
import { IconSearch } from '@tabler/icons-react';

import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import HubItems from './HubItems';

interface IHub {
Expand All @@ -36,13 +36,18 @@ export default function TemplateHub({ templates }: IHub) {
const [searchResults, setSearchResults] = useState<string[]>([]);
const [filteredTemplates, setFilteredTemplates] = useState<any[]>([]);

useEffect(() => {
filterTemplates();
}, [searchResults || []]);

const filterTemplates = () => {
const results = templates.filter((template) =>
searchResults.every((tag) => template.hashtag.includes(tag)),
const results = templates.filter(template =>
searchResults.every(tag => template.hashtag && template.hashtag.includes(tag))
);
setFilteredTemplates(results);
};


const handleIconClick = () => {
if (value.length > 0) {
setShowResults(true);
Expand Down
2 changes: 1 addition & 1 deletion frontend/components/UsePage/UserInput/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function UserInput({
</Text>
<Text size="sm" c="dimmed" lh={1.6}>
{`여러분이 원하는 템플릿의 기능과 구성 요소에 대해 가능한 한 구체적으로
설명해 주세요. {<br />}예를 들어, "EC2 인스턴스를 생성하고 싶어요"
설명해 주세요. 예를 들어, "EC2 인스턴스를 생성하고 싶어요"
보다는 "t2.micro 타입의 EC2 인스턴스를 2개 생성하고, 각 인스턴스에
10GB의 EBS 볼륨을 연결하고 싶어요"가 더 도움이 됩니다.`}
</Text>
Expand Down

0 comments on commit c6e4886

Please sign in to comment.