Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 코드 품질 향상 도구 세팅 #7

Merged
merged 22 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# 개발 환경
.env
app/backend/.env
.env.*
!.env.example

#sonarqube
app/backend/.scannerwork

# 의존성
/node_modules
/.pnp
Expand Down Expand Up @@ -89,7 +92,7 @@ celerybeat.pid
*.sage.py

# dotenv
.env
app/backend/.env

# virtualenv
.venv
Expand Down
22 changes: 22 additions & 0 deletions app/backend/.flake8
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[flake8]
show-source = true
extend-ignore = E203, E266, E501, W503, F403, F401, E402, E711, F405, F811, F841, W291, W293, B008, B907, B904, B950
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
exclude =
# No need to traverse our git directory
.git,
# There's no value in checking cache directories
__pycache__,
# The conf file is mostly autogenerated, ignore it
docs/source/conf.py,
# The old directory contains Flake8 2.0
old,
# This contains our built documentation
build,
# This contains builds of flake8 that we don't want to check
dist
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
max-complexity = 18
max-line-length = 88
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
select = B,C,E,F,W,T4,B9
per-file-ignores =
__init__.py:F401
app/utils/prompts.py:W291,W293
26 changes: 26 additions & 0 deletions app/backend/.pre-commit-config.yaml
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 24.8.0
hooks:
- id: black
language_version: python3.10
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
args: [
"--max-line-length=88",
"--extend-ignore=E203,E266,E501,W503,F403,F401,E402,E711,F405,F811,F841,W291,W293,B950,B008,B904,B907",
"--max-complexity=18",
"--select=B,C,E,F,W,T4,B9",
"--exclude=.git,__pycache__,docs/source/conf.py,old,build,dist"
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
]
5 changes: 3 additions & 2 deletions app/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# 개발 및 프로덕션 환경을 위한 Dockerfile
FROM python:3.9-slim
FROM python:3.10-slim

WORKDIR /app
WORKDIR /app/backend

# 시스템 의존성 설치
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# 파이썬 의존성 파일 복사 및 설치
Expand Down
35 changes: 32 additions & 3 deletions app/backend/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ version: '3.8'
services:
backend:
build:
context: ./backend
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/neonadeuli
volumes:
- ./backend:/app
- .:/app/backend
depends_on:
- db


db:
image: postgres:13
environment:
Expand All @@ -23,5 +24,33 @@ services:
volumes:
- postgres_data:/var/lib/postgresql/data

sonarqube:
image: sonarqube:latest
ports:
- "9000:9000"
environment:
- SONAR_JDBC_URL=jdbc:postgresql://sonarqube_db:5432/sonar
- SONAR_JDBC_USERNAME=sonar
- SONAR_JDBC_PASSWORD=sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
depends_on:
- sonarqube_db

sonarqube_db:
image: postgres:13
environment:
- POSTGRES_DB=sonar
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
volumes:
- sonarqube_db_data:/var/lib/postgresql/data

volumes:
postgres_data:
postgres_data:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
sonarqube_db_data:
40 changes: 22 additions & 18 deletions app/backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
from src.main.core.exceptions import BaseCustomException, custom_exception_handler
from src.main.middleware.auth import auth_middleware


def custom_generate_unique_id(route: APIRoute) -> str:
if route.tags:
return f"{route.tags[0]}-{route.name}"
return route.name


@asynccontextmanager
async def app_lifespan(app: FastAPI):
# 애플리케이션 시작 시 실행될 로직
Expand All @@ -28,37 +30,39 @@ async def app_lifespan(app: FastAPI):
yield
# 애플리케이션 종료 시 실행될 로직 (필요한 경우)


def create_application() -> FastAPI:
app = FastAPI(
lifespan= app_lifespan,
lifespan=app_lifespan,
# 배포 시 swagger UI, Redoc 비활성화
# docs_url= None,
# redoc_url= None,
title = settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json",
generate_unique_id_function=custom_generate_unique_id
title=settings.PROJECT_NAME,
# openapi_url=f"{settings.API_V1_STR}/openapi.json",
generate_unique_id_function=custom_generate_unique_id,
)

app.add_exception_handler(BaseCustomException, custom_exception_handler)

app.add_middleware(SessionMiddleware, secret_key=settings.BACKEND_SESSION_SECRET_KEY)
# app.add_middleware(SessionMiddleware, secret_key=settings.BACKEND_SESSION_SECRET_KEY)
app.middleware("http")(auth_middleware)
# Base.metadata.create_all(bind=engine)

# Set All CORS enabled origins
if settings.BACKEND_CORS_ORIGINS:
app.add_middleware(
CORSMiddleware,
allow_origins=[
str(origin).strip("/") for origin in settings.BACKEND_CORS_ORIGINS
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)

app.include_router(api_router, prefix=settings.API_V1_STR)
# if settings.BACKEND_CORS_ORIGINS:
# app.add_middleware(
# CORSMiddleware,
# allow_origins=[
# str(origin).strip("/") for origin in settings.BACKEND_CORS_ORIGINS
# ],
# allow_credentials=True,
# allow_methods=["*"],
# allow_headers=["*"]
# )

# app.include_router(api_router, prefix=settings.API_V1_STR)

return app

app = create_application()

app = create_application()
23 changes: 22 additions & 1 deletion app/backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,25 @@ pre-commit = "^3.4.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry.core.masonry.api"

[tool.black]
line-length = 88
keem-hyun marked this conversation as resolved.
Show resolved Hide resolved
target-version = ['py37', 'py38']
include = '\.pyi?$'
extend-exclude = '''
/(
# The following are specific to Black, you probably don't want those.
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
| blib2to3
| tests/data
| profiling
)/
'''
11 changes: 6 additions & 5 deletions app/backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
fastapi
uvicorn
sqlalchemy[asyncio]>=2.0.0
pymysql==1.1.1
pydantic
passlib
bcrypt
aiomysql
greenlet
python-dotenv
alembic
pytest
cryptography
mysqlclient
alembic
aiohttp
python-jose
boto3
haversine
aiofiles
asyncpg
asyncpg
flake8
black
itsdangerous
pydantic-settings
pre-commit
52 changes: 26 additions & 26 deletions app/backend/src/main/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ class Settings(BaseSettings):
env_file=".env", env_ignore_empty=True, extra="ignore"
)

API_V1_STR: str

BACKEND_CORS_ORIGINS: Annotated[
list[AnyUrl] | str, BeforeValidator(parse_cors)
]
BACKEND_SESSION_SECRET_KEY : str
# API_V1_STR: str
#
# BACKEND_CORS_ORIGINS: Annotated[
# list[AnyUrl] | str, BeforeValidator(parse_cors)
# ]
# BACKEND_SESSION_SECRET_KEY : str

PROJECT_NAME : str

DATABASE_URL : str
# DATABASE_URL : str

# PostgreSQL 설정
POSTGRES_USER: str
Expand All @@ -49,32 +49,32 @@ class Settings(BaseSettings):
POSTGRES_DB: str

# 클로바 스튜디오 API
CLOVA_API_KEY : str
CLOVA_API_KEY_PRIMARY_VAL : str
CLOVA_SLIDING_API_HOST : str
CLOVA_COMPLETION_API_HOST : str
MAX_TOKEN : int
# CLOVA_API_KEY : str
# CLOVA_API_KEY_PRIMARY_VAL : str
# CLOVA_SLIDING_API_HOST : str
# CLOVA_COMPLETION_API_HOST : str
# MAX_TOKEN : int

# 네이버 클라우드 클로바 보이스 API
CLOVA_VOICE_URL : str
CLOVA_VOICE_CLIENT_ID : str
CLOVA_VOICE_CLIENT_SECRET : str
# CLOVA_VOICE_URL : str
# CLOVA_VOICE_CLIENT_ID : str
# CLOVA_VOICE_CLIENT_SECRET : str

# 네이버 클라우드 서버 및 이미지
NCP_ACCESS_KEY : str
NCP_SECRET_KEY : str
NCP_REGION : str
NCP_ENDPOINT : str
BUCKET_NAME : str
CDN_DOMAIN : str
# NCP_ACCESS_KEY : str
# NCP_SECRET_KEY : str
# NCP_REGION : str
# NCP_ENDPOINT : str
# BUCKET_NAME : str
# CDN_DOMAIN : str

# 로그인 보안 관리
SECRET_KEY : str
ALGORITHM : str
ACCESS_TOKEN_EXPIRE_MINUTES : int
# SECRET_KEY : str
# ALGORITHM : str
# ACCESS_TOKEN_EXPIRE_MINUTES : int

# 기본 이미지 URL
DEFAULT_IMAGE_URL : str
# DEFAULT_IMAGE_URL : str

@computed_field
@property
Expand All @@ -85,7 +85,7 @@ def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn:
password=self.POSTGRES_PASSWORD,
host=self.POSTGRES_SERVER,
port=self.POSTGRES_PORT,
path=f"/{self.POSTGRES_DB}",
path=f"{self.POSTGRES_DB}",
)

settings = Settings()
12 changes: 6 additions & 6 deletions app/backend/src/main/domains/user/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ class UserRepository:
def get_user(self, db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()

def create_user(self, db: Session, user: schemas.UserCreate):
db_user = models.User(email=user.email, hashed_password=user.password) # 실제로는 비밀번호를 해시화해야 합니다
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
# def create_user(self, db: Session, user: schemas.UserCreate):
# db_user = models.User(email=user.email, hashed_password=user.password) # 실제로는 비밀번호를 해시화해야 합니다
# db.add(db_user)
# db.commit()
# db.refresh(db_user)
# return db_user