-
Notifications
You must be signed in to change notification settings - Fork 0
[HCR-226] analysis-server-v0.0.5 #25
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
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
dbbbf70
[HSC-226] fix: μνΈμ½λΌμ μ€λ³΅ count λ°©μ§
YeongHyeonHeo 12141b5
[HSC-226] feat: νμ κΈ°μ€ λΆμ κ²°κ³Ό μ§κ³κΈ°(aggregator.py) ꡬν
YeongHyeonHeo 334ba85
[HSC-226] test: E2E ν
μ€νΈ μΆκ°
YeongHyeonHeo b9b65de
[HSC-226] refactor: λλ²κΉ
print μ£Όμμ²λ¦¬
YeongHyeonHeo 80f7ccb
[HSC-228] feat: Kafka μλΉ κΈ°λ° SQL λΆμ νμ΄νλΌμΈ ꡬμΆ
tkv00 bd9e040
[HSC-228] refactor: REST API λ° EFS κΈ°λ° λ κ±°μ κ²½λ‘ μ κ±°
tkv00 d51b10c
Merge pull request #14 from one-year-gap/feat/HSC-226
tkv00 9c9cca4
[HSC-235] chore: μ€μ νμΌ
rettooo d5d3bb1
[HSC-235] feat: μΆμ² κΈ°λ₯ api
rettooo c01b78e
[HSC-235] feat: μν μλ² λ© μ€ν¬λ¦½νΈ
rettooo 7198454
Merge branch 'dev' of https://github.com/one-year-gap/counseling-analβ¦
tkv00 f4c3ebb
Merge pull request #16 from one-year-gap/feat/HSC-228
tkv00 12e743e
[HSC-235] fix: λ²μ λͺ
μ λ°, μλ² λ© λ°°μΉ λ¦¬ν©ν λ§
rettooo 04a54e7
Merge branch 'dev' into feat/HSC-235, resolve conflicts
rettooo eddb690
Merge pull request #20 from one-year-gap/feat/HSC-235
tkv00 299cc0d
[HSC-244] refactor: split realtime api entrypoint
tkv00 7045396
[HSC-244] feat: add batch runtime and postgres env resolution
tkv00 b0e9533
[HSC-244] build: support realtime and batch docker modes
tkv00 7246f07
[HSC-244] fix: kafka message log μ€μ μΆκ°
tkv00 2eaf5f9
Merge pull request #22 from one-year-gap/refactor/HSC-244
tkv00 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,8 @@ __pycache__ | |
| .env | ||
| tests | ||
| README.md | ||
| node_modules | ||
| package-lock.json | ||
| pnpm-lock.yaml | ||
| e2e_test_efs | ||
| e2e_test_efs_agg | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # Runtime | ||
| APP_ENV=local | ||
| APP_NAME=recommendation-server | ||
| APP_MODE=realtime | ||
| APP_PORT=8000 | ||
| LOG_LEVEL=INFO | ||
|
|
||
| # Database (Java λ ν¬μ λμΌ DB) | ||
| # 1) λͺ μ URL (κΆμ₯: λ‘컬 κ°λ°) | ||
| DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/holliverse | ||
| # DB_URLλ λμΌ μλ―Έλ‘ μ¬μ© κ°λ₯ | ||
|
|
||
| # 2) ECS/Secrets Manager λΆν΄ μ£Όμ (POSTGRES_DSN λ―Έμ€μ μ μλ μ‘°ν©) | ||
| # - Secret JSON key(username/password)λ₯Ό POSTGRES_USER/POSTGRES_PASSWORDλ‘ λ§€νν΄ μ£Όμ | ||
| # - host/port/dbλ μΌλ° envλ‘ μ£Όμ | ||
| # POSTGRES_HOST=your-instance.xxxxx.ap-northeast-2.rds.amazonaws.com | ||
| # POSTGRES_PORT=5432 | ||
| # POSTGRES_DB=holliverse | ||
| # POSTGRES_USER=holliverse | ||
| # POSTGRES_PASSWORD=***** | ||
| # POSTGRES_SSLMODE=require | ||
|
|
||
| # 3) λ°°μΉμ© raw DSN (asyncpg) | ||
| # POSTGRES_DSN=postgresql://USER:PASSWORD@HOST:5432/DBNAME?sslmode=require | ||
|
|
||
| # RDS μ°κ²° μ SSL νμνλ©΄ true (κΈ°λ³Έ false) | ||
| DATABASE_SSL=false | ||
|
|
||
| # OpenAI | ||
| OPENAI_API_KEY=your_openai_api_key | ||
| OPENAI_CHAT_MODEL=gpt-4o-mini | ||
| OPENAI_EMBEDDING_MODEL=text-embedding-3-small | ||
|
|
||
| # Recommendation | ||
| RECOMMEND_TOP_K=3 | ||
| CACHE_TTL_DAYS=7 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,29 @@ | ||
| # IDE | ||
| .idea | ||
| .venv | ||
| .env | ||
|
|
||
| # Python | ||
| __pycache__/ | ||
| *.pyc | ||
| *.pyo | ||
| *.pyd | ||
| dist/ | ||
| build/ | ||
| *.egg-info/ | ||
| .eggs/ | ||
|
|
||
| # Environment | ||
| .venv | ||
| .env | ||
|
|
||
| # Logs | ||
| *.log | ||
| logs/ | ||
|
|
||
| # Node | ||
| node_modules/ | ||
|
|
||
| # OS | ||
| .DS_Store | ||
|
|
||
| # E2E test data (keep out of git) | ||
| e2e_test_efs/** |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| pnpm test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,49 @@ | ||
| FROM python:3.11-slim | ||
| FROM python:3.11-slim AS builder | ||
|
|
||
| WORKDIR /app | ||
| WORKDIR /build | ||
|
|
||
| ENV PYTHONDONTWRITEBYTECODE=1 \ | ||
| PYTHONUNBUFFERED=1 | ||
| PYTHONUNBUFFERED=1 \ | ||
| PIP_DISABLE_PIP_VERSION_CHECK=1 \ | ||
| PIP_NO_CACHE_DIR=1 | ||
|
|
||
| COPY requirements.txt ./ | ||
| RUN pip install --no-cache-dir -r requirements.txt | ||
|
|
||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends build-essential python3-dev \ | ||
| && pip wheel --wheel-dir /wheels -r requirements.txt \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
|
|
||
| FROM python:3.11-slim AS runtime | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| ENV PYTHONDONTWRITEBYTECODE=1 \ | ||
| PYTHONUNBUFFERED=1 \ | ||
| PIP_DISABLE_PIP_VERSION_CHECK=1 \ | ||
| PIP_NO_CACHE_DIR=1 \ | ||
| APP_MODE=realtime \ | ||
| APP_HOST=0.0.0.0 \ | ||
| APP_PORT=8000 | ||
|
|
||
| RUN addgroup --system appgroup \ | ||
| && adduser --system --ingroup appgroup --home /app appuser | ||
|
|
||
| COPY --from=builder /wheels /wheels | ||
| RUN pip install --no-cache-dir /wheels/* \ | ||
| && python -m spacy download ko_core_news_sm \ | ||
| && rm -rf /wheels | ||
|
|
||
| COPY app ./app | ||
| COPY scripts ./scripts | ||
| COPY docker-entrypoint.sh ./docker-entrypoint.sh | ||
|
|
||
| RUN chmod +x /app/docker-entrypoint.sh \ | ||
| && chown -R appuser:appgroup /app | ||
|
|
||
| USER appuser | ||
|
|
||
| EXPOSE 8000 | ||
| CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] | ||
|
|
||
| ENTRYPOINT ["/app/docker-entrypoint.sh"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| """One-off Kafka batch entrypoint for keyword mapping/extraction.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import asyncio | ||
| import json | ||
| import logging | ||
|
|
||
| from aiokafka import AIOKafkaConsumer | ||
|
|
||
| from app.core.config import get_settings | ||
| from app.core.logging import configure_logging | ||
| from app.infra.postgres.analysis_repository import AnalysisRepository | ||
| from app.infra.postgres.client import create_postgres_pool | ||
| from app.infra.postgres.dispatch_outbox_repository import DispatchOutboxRepository | ||
| from app.schemas.analysis_request_message import AnalysisRequestMessage | ||
| from app.services.kafka_analysis_consumer_service import KafkaAnalysisConsumerService | ||
| from app.services.sql_keyword_analysis_service import SqlKeywordAnalysisService | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| async def run_once() -> int: | ||
| settings = get_settings() | ||
| configure_logging(settings.debug) | ||
|
|
||
| service = KafkaAnalysisConsumerService(settings) | ||
| service._db_pool = await create_postgres_pool(settings) # noqa: SLF001 | ||
| service._analysis_repository = AnalysisRepository(service._db_pool) # noqa: SLF001 | ||
| service._outbox_repository = DispatchOutboxRepository(service._db_pool) # noqa: SLF001 | ||
| service._analysis_service = SqlKeywordAnalysisService() # noqa: SLF001 | ||
|
|
||
| consumer = AIOKafkaConsumer( | ||
| settings.kafka_analysis_request_topic, | ||
| bootstrap_servers=[s.strip() for s in settings.kafka_bootstrap_servers.split(",") if s.strip()], | ||
| group_id=settings.kafka_consumer_group_id, | ||
| auto_offset_reset=settings.kafka_auto_offset_reset, | ||
| enable_auto_commit=False, | ||
| value_deserializer=lambda value: json.loads(value.decode("utf-8")), | ||
| ) | ||
|
|
||
| processed_count = 0 | ||
| received_count = 0 | ||
| dropped_count = 0 | ||
| try: | ||
| await consumer.start() | ||
| polled = await consumer.getmany( | ||
| timeout_ms=settings.kafka_poll_timeout_ms, | ||
| max_records=settings.kafka_batch_size, | ||
| ) | ||
|
|
||
| messages: list[AnalysisRequestMessage] = [] | ||
| for _, records in polled.items(): | ||
| for record in records: | ||
| received_count += 1 | ||
| parsed = service._parse_message(record.value) # noqa: SLF001 | ||
| if parsed is None: | ||
| dropped_count += 1 | ||
| continue | ||
| messages.append(parsed) | ||
|
|
||
| if messages: | ||
| for chunk in service._chunk(messages, settings.kafka_batch_size): # noqa: SLF001 | ||
| await service._process_batch(chunk) # noqa: SLF001 | ||
| processed_count += len(chunk) | ||
| await consumer.commit() | ||
| elif received_count > 0 and dropped_count == received_count: | ||
| await consumer.commit() | ||
|
|
||
| logger.info( | ||
| "Keyword batch run finished once. received=%d dropped=%d processed=%d", | ||
| received_count, | ||
| dropped_count, | ||
| processed_count, | ||
| ) | ||
| return processed_count | ||
| finally: | ||
| await consumer.stop() | ||
| if service._db_pool is not None: # noqa: SLF001 | ||
| await service._db_pool.close() # noqa: SLF001 | ||
|
|
||
|
|
||
| def main() -> None: | ||
| asyncio.run(run_once()) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KafkaAnalysisConsumerServiceμ μμ‘΄μ±μ μ£Όμ νκΈ° μν΄_db_poolκ³Ό κ°μ 보νΈλ(protected) λ©€λ²μ μ§μ μ κ·Όνκ³ μμ΅λλ€. μ΄λ μΊ‘μνλ₯Ό μλ°νλ©° μ½λμ μ μ§λ³΄μμ±μ λ¨μ΄λ¨λ¦½λλ€.noqa: SLF001μ£Όμμ΄ μ΄λ₯Ό μμνκ³ μμ΅λλ€.KafkaAnalysisConsumerServiceμ__init__λ©μλλ₯Ό ν΅ν΄ μμ‘΄μ±μ λͺ μμ μΌλ‘ μ£Όμ νλλ‘ λ¦¬ν©ν°λ§νλ κ²μ μ μν©λλ€. μ΄λ κ² νλ©΄ ν΄λμ€μ μν κ³Ό μ± μμ΄ λ λͺ νν΄μ§κ³ ν μ€νΈνκΈ° μ¬μ΄ κ΅¬μ‘°κ° λ©λλ€.