Chore(#4): FastAPI 초기 개발 환경 구축 및 Docker 설정 - #5
Conversation
… for local develop settings (#4)
📝 WalkthroughWalkthroughAdds a configurable FastAPI application with a generic response model, ChangesFastAPI service foundation
Repository workflow metadata
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant FastAPIApp
participant AnalyzeRouter
participant ApiResponse
Client->>FastAPIApp: POST /api/v1/analyze
FastAPIApp->>AnalyzeRouter: Forward request payload
AnalyzeRouter->>ApiResponse: Create success response
ApiResponse-->>Client: Return analysis result
Possibly related issues
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
requirements.txt (1)
1-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake dependency resolution reproducible.
Lower bounds alone allow every image build to install a different dependency set. Commit a lock/constraints file, or pin versions that are tested together with Python 3.11 and update them deliberately.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@requirements.txt` around lines 1 - 5, Make dependency resolution reproducible for the listed runtime packages by adding a committed lock or constraints file, or replacing lower-bound-only requirements with exact versions tested together on Python 3.11; ensure future dependency updates are deliberate and keep the primary requirements aligned with the chosen pins.app/router/analyze.py (1)
1-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider typing the request payload instead of raw
dict.
app/dto/is intended to standardize the Spring-backend contract, butpayload: dictandApiResponse[dict]leave both request and response schemas undocumented in Swagger and unvalidated by FastAPI. A dedicated request DTO would fit the same pattern asApiResponse.♻️ Example refactor
# app/dto/request.py from pydantic import BaseModel class AnalyzeRequest(BaseModel): message: str url: str | None = None-from fastapi import APIRouter -from app.dto.response import ApiResponse +from fastapi import APIRouter +from app.dto.response import ApiResponse +from app.dto.request import AnalyzeRequest router = APIRouter(prefix="/analyze", tags=["Analyze"]) `@router.post`("", response_model=ApiResponse[dict]) -async def analyze_smishing(payload: dict): +async def analyze_smishing(payload: AnalyzeRequest):🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/router/analyze.py` around lines 1 - 21, Replace the untyped payload and response dictionary in analyze_smishing with dedicated Pydantic DTOs under app.dto, defining AnalyzeRequest with the required message and optional url fields and a response model for the analysis result. Update the endpoint annotation and ApiResponse generic to use these DTOs so FastAPI validates requests and documents the Spring contract in Swagger.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.gitignore:
- Around line 4-5: Prevent local environment files from entering Docker images
by adding a .dockerignore file that excludes .env, and ensure the required
environment value is supplied at container runtime rather than copied during the
build.
In `@app/core/config.py`:
- Line 7: Replace the placeholder default in VIRUSTOTAL_API_KEY with a required
setting or an optional None value, then validate it at the VirusTotal
integration boundary before making outbound requests and fail clearly when it is
missing.
In `@Dockerfile`:
- Line 1: Add a dedicated non-root user in the Dockerfile, ensure the
application files and required directories are owned or accessible by that user,
then add a USER directive immediately before the existing CMD so Uvicorn runs
without root privileges.
---
Nitpick comments:
In `@app/router/analyze.py`:
- Around line 1-21: Replace the untyped payload and response dictionary in
analyze_smishing with dedicated Pydantic DTOs under app.dto, defining
AnalyzeRequest with the required message and optional url fields and a response
model for the analysis result. Update the endpoint annotation and ApiResponse
generic to use these DTOs so FastAPI validates requests and documents the Spring
contract in Swagger.
In `@requirements.txt`:
- Around line 1-5: Make dependency resolution reproducible for the listed
runtime packages by adding a committed lock or constraints file, or replacing
lower-bound-only requirements with exact versions tested together on Python
3.11; ensure future dependency updates are deliberate and keep the primary
requirements aligned with the chosen pins.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 73239c66-88c4-4ac6-bf50-16dca768a527
⛔ Files ignored due to path filters (14)
data_science/Data/CallData/metadata_clean.csvis excluded by!**/*.csvdata_science/Data/SMSData/phishing_total_dataset_2705.csvis excluded by!**/*.csvdata_science/SMSModel/feature_importance.pngis excluded by!**/*.pngdata_science/SMSModel/feature_scores_full.csvis excluded by!**/*.csvdata_science/SMSModel/phishing_model_artifact.pklis excluded by!**/*.pkldata_science/SMSModel/phishing_vectorizer.pklis excluded by!**/*.pkldata_science/SMSModel/risk_distribution_fig1.pngis excluded by!**/*.pngdata_science/SMSModel/risk_distribution_fig2.pngis excluded by!**/*.pngdata_science/VoiceModel/feature_importance.pngis excluded by!**/*.pngdata_science/VoiceModel/feature_scores_full.csvis excluded by!**/*.csvdata_science/VoiceModel/risk_distribution_fig1.pngis excluded by!**/*.pngdata_science/VoiceModel/risk_distribution_fig2.pngis excluded by!**/*.pngdata_science/VoiceModel/voice_model_artifact.pklis excluded by!**/*.pkldata_science/VoiceModel/voice_vectorizer.pklis excluded by!**/*.pkl
📒 Files selected for processing (16)
.github/ISSUE_TEMPLATE/feature_request.md.gitignoreDockerfileREADME.mdapp/core/config.pyapp/dto/response.pyapp/main.pyapp/router/analyze.pydata_science/Data/CallData/CallDataMd.mddata_science/Data/SMSData/SMSDataMd.mddata_science/SMSModel/SMSDataModel.ipynbdata_science/SMSModel/train_sms.pydata_science/VoiceModel/VoiceDataModel.ipynbdata_science/VoiceModel/train_voice.pydocker-compose.ymlrequirements.txt
| .claude/settings.local.json | ||
| .env No newline at end of file |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Also exclude .env from the Docker build context.
.gitignore does not affect docker build; with COPY . ., a developer’s local .env can be baked into the image. Add a .dockerignore containing .env and pass the key at runtime instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.gitignore around lines 4 - 5, Prevent local environment files from entering
Docker images by adding a .dockerignore file that excludes .env, and ensure the
required environment value is supplied at container runtime rather than copied
during the build.
| PROJECT_NAME: str = "SafeFam-AI" | ||
| VERSION: str = "1.0.0" | ||
| API_V1_STR: str = "/api/v1" | ||
| VIRUSTOTAL_API_KEY: str = "default_key_here" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Do not use a fake API-key default.
A missing .env currently produces a non-empty credential, masking deployment misconfiguration and allowing future outbound calls to proceed with an invalid key. Make this setting required, or use None and validate it at the VirusTotal integration boundary.
🔐 Proposed fix
- VIRUSTOTAL_API_KEY: str = "default_key_here"
+ VIRUSTOTAL_API_KEY: str | None = None📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| VIRUSTOTAL_API_KEY: str = "default_key_here" | |
| VIRUSTOTAL_API_KEY: str | None = None |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/core/config.py` at line 7, Replace the placeholder default in
VIRUSTOTAL_API_KEY with a required setting or an optional None value, then
validate it at the VirusTotal integration boundary before making outbound
requests and fail clearly when it is missing.
| @@ -0,0 +1,17 @@ | |||
| FROM python:3.11-slim | |||
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Run the application as a non-root user.
The container currently launches Uvicorn as root. Add a dedicated user and switch to it before CMD.
🛡️ Proposed fix
FROM python:3.11-slim
+
+RUN groupadd --system app && useradd --system --gid app app
...
EXPOSE 8000
+
+USER app
+
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]Also applies to: 16-17
🧰 Tools
🪛 Trivy (0.69.3)
[error] 1-1: Image user should not be 'root'
Specify at least 1 USER command in Dockerfile with non-root user as argument
Rule: DS-0002
(IaC/Dockerfile)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@Dockerfile` at line 1, Add a dedicated non-root user in the Dockerfile,
ensure the application files and required directories are owned or accessible by
that user, then add a USER directive immediately before the existing CMD so
Uvicorn runs without root privileges.
Source: Linters/SAST tools
📝 개요
AI 및 URL 연산 백엔드 서버의 기반이 되는 FastAPI 글로벌 공통 개발 환경을 구축하고 패키지 의존성 관리 및 메인 엔드포인트 구조를 초기 설정합니다
추가로 향후 클라우드 배포 인프라의 확장을 고려하여 Docker 및 Docker Compose 기반의 개발 환경을 구축하고 README 문서를 상세화합니다.
🔗 관련 이슈
🎯 주요 변경 사항
1. FastAPI 초기 환경 및 메인 진입점 구축
fastapi,uvicorn,pydantic-settings등) 작성 및 가상환경 세팅 완료.env연동 기반 마련)2. 아키텍처 구조화 및 스프링 연동 규격화
3. 인프라 고도화 및 README 문서 추가 작성 (이슈 외 추가 작업 항목)
Docker,docker-compose.yml생성data_science/하위로 모음📸 사진
✅ PR 체크리스트
uvicorn구동 또는 테스트 코드)를 통과했습니다.Summary by CodeRabbit
New Features
Documentation
Chores