๐Ÿ”‘ ์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ ํ™˜๊ฒฝ๋ณ€์ˆ˜ OPENAI_API_KEY ์„ค์ •ยถ

1. ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑยถ

์›ํ•˜์‹œ๋Š” ๊ฒฝ๋กœ์— django-webchat-rag ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

2. ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ/ํ™œ์„ฑํ™”ยถ

๋ฐฉ๊ธˆ ์ƒ์„ฑํ•˜์‹  ํ”„๋กœ์ ํŠธ ํด๋”๋กœ ์ด๋™ํ•˜์—ฌ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์ƒ์„ฑ/ํ™œ์„ฑํ™”ํ•ด์ฃผ์„ธ์š”.

python -m venv venv
venv\Scripts\activate
python -m venv venv
source ./venv/bin/activate

ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ํŽธํ•˜์‹  ์—๋””ํ„ฐ/IDE๋กœ ์—ด์–ด์ฃผ์‹œ๊ณ , ์—๋””ํ„ฐ/IDE์— ๊ฐ€์ƒํ™˜๊ฒฝ๋„ ์ง€์ •ํ•ด์ฃผ์„ธ์š”.

3. ์•„๋ž˜ ๋‚ด์—ญ์˜ ํŒŒ์ผ๋“ค์„ ํ•œ ๋ฒˆ์— ์ƒ์„ฑํ•˜๊ธฐยถ

ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ์ตœ์ข… ์ฝ”๋“œ๋Š” https://github.com/pyhub-kr/django-webchat-rag-langcon2025/commit/d6e9c7567263a1eafcb10a454772e676cf573bb1 ์ฃผ์†Œ์˜ ์ปค๋ฐ‹์— ์žˆ์Šต๋‹ˆ๋‹ค.

pyhub-git-commit-apply ๋ช…๋ น์—์„œ ํ•ด๋‹น ์ปค๋ฐ‹ ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•˜์‹œ๋ฉด, ํ•ด๋‹น ์ปค๋ฐ‹์—์„œ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ๋“ค๋งŒ ํ˜„์žฌ ๊ฒฝ๋กœ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. --all ์˜ต์…˜์„ ์ ์šฉํ•˜์‹œ๋ฉด ํ•ด๋‹น ์ปค๋ฐ‹์„ ๊ธฐ์ค€์œผ๋กœ ์ €์žฅ์†Œ์˜ ๋ชจ๋“  ํŒŒ์ผ๋“ค์„ ํ˜„์žฌ ๊ฒฝ๋กœ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋œ ์ƒํƒœ์—์„œ ๋จผ์ € pyhub-git-commit-apply ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•ด์ฃผ์‹œ๊ตฌ์š”.

pip install --upgrade pyhub-git-commit-apply

์•„๋ž˜ ๋ช…๋ น์œผ๋กœ ์ง€์ • ์ปค๋ฐ‹์˜ ๋ชจ๋“  ํŒŒ์ผ๋“ค์„ ํ˜„์žฌ ๊ฒฝ๋กœ๋กœ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

python -m pyhub_git_commit_apply --all https://github.com/pyhub-kr/django-webchat-rag-langcon2025/commit/d6e9c7567263a1eafcb10a454772e676cf573bb1
uv run pyhub-git-commit-apply --all https://github.com/pyhub-kr/django-webchat-rag-langcon2025/commit/d6e9c7567263a1eafcb10a454772e676cf573bb1

์ˆ˜ํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด requirements.txt ํŒŒ์ผ์„ ๋น„๋กฏํ•ด manage.py, mysite, .env.sample ํŒŒ์ผ๋“ค์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

../../_images/pyhub-git-commit-apply.png

์•„๋ž˜ ๋‚ด์šฉ ์ฐธ๊ณ ํ•ด์„œ, ๋‹ค์Œ 5๊ฐ€์ง€๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. pip install --upgrade -r requirements.txt ๋ช…๋ น์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ (์ด๋ฏธ ์„ค์น˜ํ•˜์…จ๋‹ค๋ฉด PASS)

  2. .env.sample ํŒŒ์ผ์„ ๋ณต์‚ฌํ•ด์„œ .env ํŒŒ์ผ ์ƒ์„ฑํ•˜๊ธฐ

    • OPENAI_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •ํ•˜๊ธฐ

    • postgres๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •ํ•˜๊ธฐ

  3. python manage.py shell -c "from django.conf import settings; print(settings.DATABASES); print(settings.OPENAI_API_KEY);" ๋ช…๋ น์œผ๋กœ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์ด ์ •ํ™•ํžˆ ์ ์šฉ๋˜์—ˆ๋Š” ์ง€ ํ™•์ธ

  4. python manage.py showmigrations ๋ช…๋ น์œผ๋กœ ๋นˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ธ์ง€ ์—ฌ๋ถ€ ํ™•์ธ

  5. python manage.py migrate ๋ช…๋ น์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ” ์ƒ์„ฑ

4. ์—๋””ํ„ฐ๋กœ ์—ด๊ธฐยถ

VSCode์—์„œ๋Š” ํ…œํ”Œ๋ฆฟ ํŽธ์ง‘ ์‹œ์— prettier ํฌ๋งทํ„ฐ๋กœ ์ธํ•ด ํ…œํ”Œ๋ฆฟ ๋ฌธ๋ฒ•์ด ๋ง๊ฐ€์ง€๊ณค ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์šฐ์„ ํ•ด์•ผํ•˜๋Š” ํ™•์žฅ/์„ค์ •์€ Glavin001.unibeautify-vscode ํ™•์žฅ์ž…๋‹ˆ๋‹ค. ์žฅ๊ณ ๋ฅผ ์œ„ํ•œ VSCode ์„ค์ • ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ™•์žฅ์„ ์„ค์น˜ํ•˜์‹œ๊ณ , django-html ํƒ€์ž…์— ๋Œ€ํ•ด ๋””ํดํŠธ ํฌ๋งทํ„ฐ๋กœ Glavin001.unibeautify-vscode๋ฅผ ์ง€์ •ํ•ด์ฃผ์„ธ์š”.

ํŒ

์œˆ๋„์šฐ์—์„œ๋Š” ๊ธฐ๋ณธ ๋ช…๋ นํ”„๋กฌํ”„ํŠธ/ํŒŒ์›Œ์‰˜์„ ์“ฐ์‹œ๊ธฐ๋ณด๋‹ค, ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ์˜ ํŒŒ์›Œ์‰˜ ์ฝ”์–ด 7์„ ์“ฐ์‹œ๋ฉด, ์‚ฌ์šฉ์„ฑ์ด ๋”์šฑ ์ข‹์Šต๋‹ˆ๋‹ค. ์œˆ๋„์šฐ ๊ธฐ๋ณธ ํŒŒ์›Œ์‰˜์€ ๋ฒ„์ „ 5์ž…๋‹ˆ๋‹ค. (์ฐธ๊ณ : ์œˆ๋„์šฐ ํ„ฐ๋ฏธ๋„)

VSCode์—์„œ๋Š” ๋ช…๋ น ํŒ”๋ ˆํŠธ์—์„œ Python: Select Interpreter ๋ช…๋ น์œผ๋กœ ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•  ๊ฐ€์ƒํ™˜๊ฒฝ์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”. ๊ทธ ํ›„์— Terminal: Create New Terminal ๋ช…๋ น์œผ๋กœ ์ƒˆ๋กœ์šด ํ„ฐ๋ฏธ๋„์„ ์—ฌ์‹œ๋ฉด ์ž๋™์œผ๋กœ ์ง€์ • ๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™”ํ•œ ํ›„์—, ํŒŒ์›Œ์‰˜์—์„œ๋Š” Get-Command python | Select-Object Source ๋ช…๋ น์œผ๋กœ ํ˜„์žฌ python ๋ช…๋ น์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํŒŒ์ด์ฌ ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. django-webchat-rag\venv ๊ฒฝ๋กœ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

../../_images/verify-python-path-windows-powershell.png

๋ช…๋ น ํ”„๋กฌํ”„ํŠธ์—์„œ๋Š” where python ๋ช…๋ น์œผ๋กœ ํ˜„์žฌ python ๋ช…๋ น์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํŒŒ์ด์ฌ ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. django-webchat-rag\venv ๊ฒฝ๋กœ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

../../_images/verify-python-path-windows-cmd.png

๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™”ํ•œ ํ›„์—, macOS ์‰˜์—์„œ๋Š” which python ๋ช…๋ น์œผ๋กœ ํ˜„์žฌ python ๋ช…๋ น์„ ํ†ตํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํŒŒ์ด์ฌ ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. django-webchat-rag/venv ๊ฒฝ๋กœ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉด ๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

../../_images/verify-python-path-macos.png

ํŒ

ํ˜น์‹œ VSCode/PyCharm ํ„ฐ๋ฏธ๋„์—์„œ ์ž๋™์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ์ด ํ™œ์„ฑํ™”๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ˆ˜๋™์œผ๋กœ ๊ฐ€์ƒํ™˜๊ฒฝ์„ ํ™œ์„ฑํ™”ํ•ด์ฃผ์‹œ๊ณ , ์‰ฌ๋Š” ์‹œ๊ฐ„์— ๋”ฐ๋กœ ์งˆ๋ฌธ์ฃผ์‹œ๋ฉด ์ •ํ™•ํžˆ ํ•ด๊ฒฐํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

5. .gitignore ํŒŒ์ผ ์ƒ์„ฑยถ

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .gitignore ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

.gitignoreยถ
.env
__pycache__
*.sqlite3
.vscode
.idea
.DS_Store
/staticfiles
/mediafiles
/venv
/.venv

6. .env ํŒŒ์ผ ์ƒ์„ฑยถ

์†Œ์Šค์ฝ”๋“œ ํŽธ์ง‘๊ธฐ๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— ๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

  • DATABASE_URL : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด

    • ๊ฐ์ž SQLite/Postgres ํ™˜๊ฒฝ์— ๋งž๊ฒŒ DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.

  • OPENAI_API_KEY : OpenAI API ํ‚ค

    • OPENAI_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” ๋ณธ์ธ์˜ OpenAI API ํ‚ค๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”. OpenAI API Key๋Š” https://platform.openai.com/api-keys ํŽ˜์ด์ง€์—์„œ ๋ฐœ๊ธ‰๋ฐ›์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ๋ณธ์ธ์˜ OpenAI API Key ์ƒ์„ฑ์ด ์–ด๋ ค์šฐ์‹  ๋ถ„์€ ํ•ธ์ฆˆ์˜จ๋žฉ ์‹œ๊ฐ„ ๋™์•ˆ์—๋งŒ ์‚ฌ์šฉํ•˜์‹ค Key๋ฅผ ์ œ๊ณตํ•ด๋“œ๋ฆฝ๋‹ˆ๋‹ค.

../../_images/dot-env.png

sqlite ์—์„œ๋Š” DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” ์ง€์ •ํ•˜์ง€ ์•Š๊ณ , ์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ๋””ํดํŠธ ๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•ด์„œ ํ™œ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

OPENAI_API_KEY=sk-...
DATABASE_URL=postgresql://postgres.euvmdqdkpiseywirljvs:์•”ํ˜ธ@aws-0-ap-northeast-2.pooler.supabase.com:5432/postgres
OPENAI_API_KEY=sk-...

๊ฒฝ๊ณ 

  • ๋ฉ”๋ชจ์žฅ์„ ํ†ตํ•ด ์ƒ์„ฑํ•˜์‹ค ๊ฒฝ์šฐ, ํ™•์žฅ์ž๊ฐ€ .txt ๋กœ์„œ .env.txt ํŒŒ์ผ๋ช…์œผ๋กœ ์ƒ์„ฑ๋˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋“œ์‹œ ํ™•์žฅ์ž์—†์ด .env ํŒŒ์ผ๋ช…์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

  • .env ํŒŒ์ผ์€ key=value ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•˜์‹œ๋˜, ๋“ฑํ˜ธ ์–‘์ชฝ์— ๊ณต๋ฐฑ์ด ์žˆ์œผ๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค. ๊ณต๋ฐฑ์ด ์žˆ์œผ๋ฉด ํ•ด๋‹น ์„ค์ •์€ ๋ฌด์‹œ๋˜๋‹ˆ ์ฃผ์˜ํ•ด์ฃผ์„ธ์š”.

7. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์น˜ยถ

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๊ฒฝ๋กœ์— requirements.txt ํŒŒ์ผ์„ ์•„๋ž˜ ๋‚ด์šฉ์œผ๋กœ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.

ํŒŒ์ด์ฌ์—์„œ๋Š” sqlite ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๊ธฐ๋ณธ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

requirements.txtยถ
django-pyhub-rag
django-environ
django-debug-toolbar
django-extensions
django-lifecycle
openai

sqlite-vec
numpy

ipython

psycopg2-binary ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

requirements.txtยถ
django-pyhub-rag
django-environ
django-debug-toolbar
django-extensions
django-lifecycle
openai

psycopg2-binary
pgvector

ipython

๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ์— ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

python -m pip install --upgrade -r requirements.txt
../../_images/requirements-txt.png

์ฐธ๊ณ 

  • django-pyhub-rag : pgvector/sqlite-vec ๋ฒกํ„ฐ์Šคํ† ์–ด๋ฅผ ๋™์ผํ•œ ๋ชจ๋ธ ์ฝ”๋“œ๋กœ ์ง€์›

  • django-environ : .env ํŒŒ์ผ ๋กœ๋”ฉ ๋ฐ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’ ํŒŒ์‹ฑ

  • django-debug-toolbar : ์žฅ๊ณ  ๋””๋ฒ„๊ทธ ํˆด๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • django-extensions : ๋‹ค์–‘ํ•œ ์žฅ๊ณ  ํ™•์žฅ ํŽธ์˜ ๊ธฐ๋Šฅ ์ œ๊ณต

  • django-lifecycle : ์žฅ๊ณ  ๋ชจ๋ธ ๋ ˆ์ฝ”๋“œ ์ƒ์„ฑ/์ˆ˜์ •/์‚ญ์ œ ์‹œ์— ํ˜ธ์ถœํ•  ํ•จ์ˆ˜๋ฅผ ์ง๊ด€์ ์œผ๋กœ ์ž‘์„ฑ

  • openai : OpenAI API ๋ผ์ด๋ธŒ๋Ÿด

  • sqlite-vec : SQLite ๋ฒกํ„ฐ์Šคํ† ์–ด ํ™•์žฅ

  • numpy : ๋ฒกํ„ฐ ๋ฐฐ์—ด ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜์— ํ™œ์šฉ

  • psycopg2-binary : PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋“œ๋ผ์ด๋ฒ„

  • pgvector : PostgreSQL ๋ฒกํ„ฐ์Šคํ† ์–ด ํ™•์žฅ

  • ipython : ํ–ฅ์ƒ๋œ ํŒŒ์ด์ฌ ์‰˜

8. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑยถ

์žฅ๊ณ ์—์„œ๋Š” django-admin startproject ๋ช…๋ น์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉฐ, python -m django startproject ๋ช…๋ น์œผ๋กœ๋„ ๋™์ผํ•˜๊ฒŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

python -m django startproject mysite .

์ฐธ๊ณ 

๋ช…๋ น ๋์— .๊นŒ์ง€ ๊ผญ ํฌํ•จํ•ด์ฃผ์„ธ์š”. ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

../../_images/startproject.png

9. mysite/settings.py ํŒŒ์ผ ์ˆ˜์ •ยถ

django-environ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์ •ยถ

.env ํŒŒ์ผ ๋กœ๋”ฉ์„ ์œ„ํ•ด django-environ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .env ํŒŒ์ผ์ด ์žˆ๋‹ค๋ฉด ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ์„œ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

mysite/settings.pyยถ
 1from pathlib import Path
 2from environ import Env
 3
 4BASE_DIR = Path(__file__).resolve().parent.parent
 5
 6env = Env()
 7ENV_PATH = BASE_DIR / ".env"
 8if ENV_PATH.is_file():
 9    # ์ง€์ • ๊ฒฝ๋กœ์˜ ํŒŒ์ผ ์ฝ๊ธฐ์— ์‹คํŒจํ•ด๋„, ์˜ˆ์™ธ ๋ฐœ์ƒ์—†์ด ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.
10    env.read_env(ENV_PATH, overwrite=True)
11
12# ...

"django_extensions" ์•ฑ๊ณผ "pyhub.rag" ์•ฑ์„ ํ™œ์„ฑํ™”ํ•ด์ฃผ์„ธ์š”.

mysite/settings.pyยถ
INSTALLED_APPS = [
    # ...
    "django_extensions",  # ํ•˜์ดํ”ˆ(-)์ด ์•„๋‹Œ ์–ธ๋”๋ฐ”(_)์ž„์— ์œ ์˜
    "pyhub.rag",
]

DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •ยถ

DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์„ ์ฝ์–ด default ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. DATABASE_URL ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์˜ db.sqlite3 ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

sqlite-vec ํ™•์žฅ์€ ๊ฐ€์ƒ ํ…Œ์ด๋ธ” (CREATE VIRTUAL TABLE ...) ๋ฐฉ์‹์œผ๋กœ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์ƒ ํ…Œ์ด๋ธ”์€ ์žฅ๊ณ  ๊ธฐ๋ณธ์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ์—, ๊ฐ€์ƒ ํ…Œ์ด๋ธ” ์ง€์›์„ ์œ„ํ•ด pyhub.db.backends.sqlite3 ์—”์ง„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

mysite/settings.pyยถ
DATABASES = {
    "default": env.db("DATABASE_URL", default=f"sqlite:///{BASE_DIR / 'db.sqlite3'}"),
}
if DATABASES["default"]["ENGINE"] == "django.db.backends.sqlite3":
    DATABASES["default"]["ENGINE"] = "pyhub.db.backends.sqlite3"

๋กœ๊น… ์„ค์ •ยถ

pyhub.rag ์•ฑ์˜ ๋กœ๊น… ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜์—ฌ, ๋””๋ฒ„๊ทธ ๋ชจ๋“œ์—์„œ๋งŒ ๋กœ๊น…์ด ํ™œ์„ฑํ™”๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. pyhub.rag ์•ฑ ๋‚ด์—์„œ๋Š” sqlite-vec extension loaded์™€ ๊ฐ™์€ ๋””๋ฒ„๊ทธ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

mysite/settings.pyยถ
# https://docs.djangoproject.com/en/5.1/topics/logging/
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "filters": {
        "require_debug_true": {
            "()": "django.utils.log.RequireDebugTrue",
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "filters": ["require_debug_true"],
        },
    },
    "loggers": {
        "pyhub": {
            "handlers": ["console"],
            "level": "DEBUG",
        },
    },
}

django-debug-toolbar ์•ฑ ์„ค์ •ยถ

django-debug-toolbar ์•ฑ์€ ๊ฐœ๋ฐœ๋ชจ๋“œ(DEBUG=True)์—์„œ๋งŒ ํ™œ์„ฑํ™”๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

mysite/settings.pyยถ
# https://django-debug-toolbar.readthedocs.io
if DEBUG:
    INSTALLED_APPS += [
        "debug_toolbar",
    ]

    # ๋ฏธ๋“ค์›จ์–ด ์ฒ˜์Œ์— ์œ„์น˜ํ•ด์•ผ๋งŒ, ๋‹ค๋ฅธ ๋ฏธ๋“ค์›จ์–ด/View ๋‹จ์—์„œ ์ˆ˜ํ–‰๋œ ๋‚ด์—ญ์„ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    MIDDLEWARE = [
        "debug_toolbar.middleware.DebugToolbarMiddleware",
    ] + MIDDLEWARE

    # ์žฅ๊ณ  ๋””๋ฒ„๊ทธ ํˆด๋ฐ”๋ฅผ ๋ณด์—ฌ์ค„ ์ฃผ์†Œ๋ฅผ ์ง€์ •
    # ํ˜น์€ ์ง์ ‘ ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•˜์—ฌ ํŠน์ • ์กฐ๊ฑด์—์„œ๋งŒ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
    INTERNAL_IPS = env.list("INTERNAL_IPS", default=["127.0.0.1"])
mysite/urls.py ๋ฎ์–ด์“ฐ๊ธฐยถ
 1from django.apps import apps
 2from django.contrib import admin
 3from django.urls import include, path
 4
 5urlpatterns = [
 6    path("admin/", admin.site.urls),
 7]
 8
 9if apps.is_installed("debug_toolbar"):
10    urlpatterns = [
11        path("__debug__/", include("debug_toolbar.urls")),
12    ] + urlpatterns

OpenAI API Key ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •ยถ

์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ OpenAI API Key ์ฐธ์กฐ๋ฅผ ์œ„ํ•ด OPENAI_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์„ ์ฝ์–ด OPENAI_API_KEY ์„ค์ •์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒŒ์‹ฑ์€ settings.py ๋‚ด์—์„œ๋งŒ ์ˆ˜ํ–‰ํ•˜๊ณ , ์žฅ๊ณ  ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฐธ์กฐ์—†์ด settings ๊ฐ’ ์ฐธ์กฐ๋ฅผ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

mysite/settings.pyยถ
# OpenAI API Key
# default ๊ฐ’์„ ์ง€์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ์— ์ง€์ • ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด
# ImproperlyConfigured: Set the OPENAI_API_KEY environment variable ์˜ˆ์™ธ ๋ฐœ์ƒ
# ์˜ˆ์™ธ๋ฅผ ํ†ตํ•ด ํ•„์ˆ˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋กœ๋”ฉ ์—ฌ๋ถ€๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# ํ•„์ˆ˜ ์„ค์ •์ด ๋ˆ„๋ฝ๋˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ๋™๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
OPENAI_API_KEY = env.str("OPENAI_API_KEY")

settings ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ ์šฉ ํ˜„ํ™ฉ ํ™•์ธยถ

๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์žฅ๊ณ  settings ๋‚ด์—์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์„ settings ์„ค์ •์— ์ •ํ™•ํžˆ ๋ฐ˜์˜๋˜์—ˆ๋Š” ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

  • print(settings.DATABASES) : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด ํ™•์ธ

  • print(settings.OPENAI_API_KEY) : OpenAI API Key ํ™•์ธ

python manage.py shell -c "from django.conf import settings; print(settings.DATABASES); print(settings.OPENAI_API_KEY);"

๊ฒฝ๊ณ 

ํ˜„์žฌ ์žฅ๊ณ  ํ”„๋กœ์„ธ์Šค์—์„œ OPENAI_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์—†๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ImproperlyConfigured ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์‹ ๋‹ค๋ฉด .env ํŒŒ์ผ์—์„œ OPENAI_API_KEY ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ง€์ •์„ ํ™•์ธํ•ด์ฃผ์‹œ๊ณ , ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ช… ์˜คํƒ€๋„ ํ™•์ธํ•ด์ฃผ์„ธ์š”. ๊ทธ๋ž˜๋„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด .env ํŒŒ์ผ ๊ฒฝ๋กœ๊ฐ€ ์ •ํ™•ํ•œ์ง€ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

../../_images/improperly-configured-openai-api-key.png

sqlite์˜ ๊ฒฝ์šฐ ENGINE ์„ค์ •์€ ๋ฐ˜๋“œ์‹œ django.db.backends.sqlite3๊ฐ€ ์•„๋‹Œ pyhub.db.backends.sqlite3 ์—”์ง„์œผ๋กœ ์„ค์ •๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

../../_images/initial-project-print-settings-sqlite.png

showmigrations ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•ด๋ณด์‹œ๋ฉด sqlite-vec extension loaded ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋‹ค์Œ 2๊ฐ€์ง€๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

  1. settings.DATABASES ์„ค์ •์— ENGINE ์„ค์ •์ด pyhub.db.backends.sqlite3 ์—”์ง„์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ

  2. settings.INSTALLED_APPS ์„ค์ •์— pyhub.rag ์•ฑ์ด ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ

../../_images/initial-project-showmigrations-empty-sqlite.png

postgres์˜ ๊ฒฝ์šฐ HOST, PORT, USER, PASSWORD, NAME ์„ค์ •์„ ๊ผญ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

../../_images/initial-project-print-settings-postgres.png
../../_images/initial-project-showmigrations-empty-postgres.png

10. ๊ธฐ๋ณธ ํ…Œ์ด๋ธ” ์ƒ์„ฑยถ

ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์— ๋“ฑ๋ก๋œ ์žฅ๊ณ  ์•ฑ์— ๋Œ€ํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์ˆ˜ํ–‰ํ•˜์—ฌ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.

python manage.py migrate
../../_images/migrate.png