Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
26 changes: 12 additions & 14 deletions .github/workflows/ci-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ name: CI (Python/FastAPI)

on:
push:
branches:
- feature/onnx
tags:
- 'pre-processing-v*'
pull_request:
Expand Down Expand Up @@ -60,17 +58,17 @@ jobs:
- name: Run Formatter Check (Black)
run: poetry run black --check .

test:
name: Run Tests
runs-on: ubuntu-latest
needs: lint
defaults:
run:
working-directory: apps/pre-processing-service
steps:
- name: Checkout repository
uses: actions/checkout@v4

# test:
# name: Run Tests
# runs-on: ubuntu-latest
# needs: lint
# defaults:
# run:
# working-directory: apps/pre-processing-service
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
#
# - name: Set up Python 3.11
# uses: actions/setup-python@v5
# with:
Expand Down Expand Up @@ -123,7 +121,7 @@ jobs:
name: Build Docker Image and push
runs-on: ubuntu-latest
needs:
- test
# - test
- set-image-tag
if: startsWith(github.ref, 'refs/tags/pre-processing-v')

Expand Down
148 changes: 148 additions & 0 deletions .github/workflows/deploy-fastapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Deploy FastAPI
on:
push:
branches:
- fix/**
workflow_run:
workflows: ["CI (Python/FastAPI)"]
types: [completed]

jobs:
deploy:
name: Deploy to AWS FastAPI EC2
runs-on: ubuntu-latest
if: |
github.event.workflow_run.conclusion == 'success' &&
startsWith(github.event.workflow_run.head_branch, 'pre-processing-v')

steps:
- uses: actions/checkout@v4
- name: Create env file
run: |
echo "DB_HOST=${{ secrets.DB_HOST }}" > .env.prod
echo "DB_PORT=${{ secrets.DB_PORT }}" >> .env.prod
echo "DB_USER=${{ secrets.DB_USER }}" >> .env.prod
echo "DB_PASS=${{ secrets.DB_PASS }}" >> .env.prod
echo "DB_NAME=${{ secrets.DB_NAME }}" >> .env.prod
echo "LOKI_HOST=${{ secrets.LOKI_HOST }}" >> .env.prod
echo "LOKI_USERNAME=${{ secrets.LOKI_USERNAME }}" >> .env.prod
echo "LOKI_PASSWORD=${{ secrets.LOKI_PASSWORD }}" >> .env.prod
echo "ENV_NAME=${{ secrets.ENV_NAME }}" >> .env.prod
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> .env.prod

- name: Set repo lowercase
run: echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV

- name: Copy docker compose files to FastAPI EC2
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.FASTAPI_SERVER_HOST }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
source: "docker/production-fastapi/docker-compose.yml"
target: "~/app"

- name: Copy .env.prod file to FastAPI EC2
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.FASTAPI_SERVER_HOST }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
source: ".env.prod"
target: "~/app/docker/production/"
overwrite: true

- name: Copy promtail-config to FastAPI EC2
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.FASTAPI_SERVER_HOST }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
source: "docker/production-fastapi/promtail-config.yml"
target: "~/app/docker/production/"
overwrite: true

- name: Check ONNX model on FastAPI EC2
id: check-onnx
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.FASTAPI_SERVER_HOST }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
if [ -f "~/app/models/klue_bert.onnx" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi

- name: Copy ONNX to FastAPI EC2
if: steps.check-onnx.outputs.exists == 'false'
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.FASTAPI_SERVER_HOST }}
username: ubuntu
key: ${{ secrets.SERVER_SSH_KEY }}
source: "apps/pre-processing-service/klue_bert.onnx"
target: "~/app/models/"
overwrite: false

- name: Deploy on EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{secrets.FASTAPI_SERVER_HOST}}
username: ubuntu
key: ${{secrets.SERVER_SSH_KEY}}
script: |
cd ~/app/docker/production

echo "${{secrets.GITHUB_TOKEN}}" | docker login ghcr.io -u ${{github.actor}} --password-stdin

docker-compose pull

docker-compose down

docker-compose up -d

sleep 5
docker-compose ps

echo "Waiting for containers to become healthy..."
for i in {1..30}; do
unhealthy=$(docker ps --filter "health=unhealthy" --format "{{.Names}}")
starting=$(docker ps --filter "health=starting" --format "{{.Names}}")
if [ -z "$unhealthy" ] && [ -z "$starting" ]; then
echo "All containers are healthy!"
break
fi
echo "Waiting... ($i/30)"
sleep 2
done

docker image prune -f

- name: Send Discord notification - Success
if: success()
uses: Ilshidur/action-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
with:
args: |
**배포 성곡**
**Repository:** ${{ env.REPO_LC }}
**Tag:** ${{ github.ref_name }}
**Server:** ${{ secrets.FASTAPI_SERVER_HOST }}
**Status:** Success!

- name: Send Discord notification - Failure
if: failure()
uses: Ilshidur/action-discord@master
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }}
with:
args: |
**배포 μ‹€νŒ¨**
**Repository:** ${{ env.REPO_LC }}
**Tag:** ${{ github.ref_name }}
**Error:** 배포 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
**Check:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
16 changes: 7 additions & 9 deletions .github/workflows/deploy-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches:
- fix/**
workflow_run:
workflows: ["CI (Java)", "CI (Python/FastAPI)"]
workflows: ["CI (Java)"]
types: [completed]


Expand All @@ -15,9 +15,7 @@ jobs:
runs-on: ubuntu-latest
if: |
github.event.workflow_run.conclusion == 'success' &&
(startsWith(github.event.workflow_run.head_branch, 'user-service-v') ||
startsWith(github.event.workflow_run.head_branch, 'pre-processing-v'))

startsWith(github.event.workflow_run.head_branch, 'user-service-v')

steps:
- uses: actions/checkout@v4
Expand All @@ -28,10 +26,11 @@ jobs:
echo "DB_USER=${{ secrets.DB_USER }}" >> .env.prod
echo "DB_PASS=${{ secrets.DB_PASS }}" >> .env.prod
echo "DB_NAME=${{ secrets.DB_NAME }}" >> .env.prod
echo "ENV_NAME=${{ secrets.LOKI_URL }}" >> .env.prod
echo "ENV_NAME=${{ secrets.LOKI_USERNAME }}" >> .env.prod
echo "ENV_NAME=${{ secrets.LOKI_PASSWORD }}" >> .env.prod
echo "LOKI_HOST=${{ secrets.LOKI_HOST }}" >> .env.prod
echo "LOKI_USERNAME=${{ secrets.LOKI_USERNAME }}" >> .env.prod
echo "LOKI_PASSWORD=${{ secrets.LOKI_PASSWORD }}" >> .env.prod
echo "ENV_NAME=${{ secrets.ENV_NAME }}" >> .env.prod
echo "FASTAPI_SERVER_HOST=${{ secrets.FASTAPI_SERVER_HOST }}" >> .env.prod

- name: Set repo lowercase
run: echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
Expand Down Expand Up @@ -75,7 +74,6 @@ jobs:
target: "~/app/docker/production/"
overwrite: true


- name: Deploy on EC2
uses: appleboy/ssh-action@v1.0.3
with:
Expand Down Expand Up @@ -140,4 +138,4 @@ jobs:
**Repository:** ${{ env.REPO_LC }}
**Tag:** ${{ github.ref_name }}
**Error:** 배포 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
**Check:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
**Check:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.idea
logs
*.log
*.env*
*.env*
__pycache__

*.onnx
77 changes: 47 additions & 30 deletions apps/pre-processing-service/app/api/endpoints/test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# app/api/endpoints/embedding.py
from time import sleep

import loguru
from fastapi import APIRouter
from sqlalchemy import text
Expand All @@ -8,14 +10,17 @@
from fastapi import APIRouter
from typing import Mapping, Any, Dict
from ...model.schemas import *
from ...service.blog.blog_create_service import BlogContentService
from ...service.blog.naver_blog_post_service import NaverBlogPostService
from ...service.blog.tistory_blog_post_service import TistoryBlogPostService
from ...service.crawl_service import CrawlService
from ...service.keyword_service import keyword_search
from ...service.match_service import MatchService
from ...service.search_service import SearchService

# from ...service.similarity_service import SimilarityService
from ...db.db_connecter import engine # βœ… μš°λ¦¬κ°€ λ§Œλ“  DB μœ ν‹Έ μž„ν¬νŠΈ
from ...service.similarity_service import SimilarityService

# 이 파일만의 독립적인 λΌμš°ν„°λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
router = APIRouter()
Expand Down Expand Up @@ -62,54 +67,66 @@ def with_meta(data: Mapping[str, Any], meta: Mapping[str, Any]) -> Dict[str, Any

@router.get("/tester", response_model=None)
async def processing_tester():
request_dict = {
"tag": "naver",
"category": "50000000",
"start_date": "2025-09-01",
"end_date": "2025-09-02",
}
# 넀이버 ν‚€μ›Œλ“œ 검색
naver_request = RequestNaverSearch(**with_meta(request_dict))
naver_request = RequestNaverSearch(tag="naver")
response_data = await keyword_search(naver_request)
keyword = response_data.get("keyword")
keyword = response_data["data"].get("keyword")
loguru.logger.info(keyword)

keyword = {
"keyword": keyword,
}

# 싸닀ꡬ μƒν’ˆ 검색
sadagu_request = RequestSadaguSearch(**with_meta(keyword))
search_service = SearchService()
keyword_result = await search_service.search_products(sadagu_request)
sadagu_request = RequestSadaguSearch(keyword=keyword)
searchservice = SearchService()
keyword_result = await searchservice.search_products(sadagu_request)
loguru.logger.info(keyword_result)

# 싸닀ꡬ μƒν’ˆ 맀치
keyword["search_results"] = keyword_result.get("search_results")
keyword_match_request = RequestSadaguMatch(**with_meta(keyword))

data = keyword_result["data"]
keyword_match_request = RequestSadaguMatch(
keyword=data.get("keyword"), search_results=data.get("search_results")
)
match_service = MatchService()
keyword_match_response = match_service.match_products(keyword_match_request)
loguru.logger.info(keyword_match_response)

# 싸닀ꡬ μƒν’ˆ μœ μ‚¬λ„ 뢄석
keyword["matched_products"] = keyword_match_response.get("matched_products")
keyword_similarity_request = RequestSadaguSimilarity(**with_meta(keyword))
# similarity_service = SimilarityService()
# keyword_similarity_response = similarity_service.select_product_by_similarity(
# keyword_similarity_request
# )
# loguru.logger.info(keyword_similarity_response)

data = keyword_match_response["data"]
keyword_similarity_request = RequestSadaguSimilarity(
keyword=data.get("keyword"), matched_products=data.get("matched_products")
)
similarity_service = SimilarityService()
keyword_similarity_response = similarity_service.select_product_by_similarity(
keyword_similarity_request
)
loguru.logger.info(keyword_similarity_response)
sleep(5)
# 싸닀ꡬ μƒν’ˆ 크둀링
a = RequestSadaguCrawl(
product_url=keyword_similarity_response["data"]["selected_product"].get("url")
)
crawl = CrawlService()
crawl_response = await crawl.crawl_product_detail(a)
loguru.logger.info(crawl_response)

sleep(5)
# λΈ”λ‘œκ·Έ 생성
data = crawl_response
rag = RequestBlogCreate(product_info=data.get("product_detail"), target_length=500)
blog_service = BlogContentService()
rag_data = blog_service.generate_blog_content(rag)
loguru.logger.info(rag_data)

sleep(15)
# λΈ”λ‘œκ·Έ 배포
tistory_service = TistoryBlogPostService()
result = tistory_service.post_content(
title="μ•ˆλ…•ν•˜μ‚΄λ²•",
content="μ•ˆλ…•ν•˜μ‚΄λ²• λ°›μ•„μΉ˜κΈ°λŸ¬κΈ° μ½”λ“œ λ°›μ•„μΉ˜κΈ°",
tags=["퉁퉁퉁사후λ₯΄", "짜라짜라"],
data = rag_data
# tistory_service = TistoryBlogPostService()
naverblogPostService = NaverBlogPostService()
result = naverblogPostService.post_content(
# blog_id="wtecho331",
# blog_pw="wt505033@#",
title=data.get("title"),
content=data.get("content"),
tags=data.get("tags"),
)
loguru.logger.info(result)

Expand Down
5 changes: 5 additions & 0 deletions apps/pre-processing-service/app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ class BaseSettingsConfig(BaseSettings):
db_pass: str
db_name: str
env_name: str
app_name: str

# MeCab 사전 경둜 (μžλ™ 감지)
mecab_path: Optional[str] = None

# Loki μ„€μ •
loki_host: str = "localhost"
loki_port: int = 3100

# ν…ŒμŠ€νŠΈ/μΆ”κ°€μš© ν•„λ“œ
openai_api_key: Optional[str] = None # << 이 λΆ€λΆ„ μΆ”κ°€

Expand Down
Loading
Loading