SOY NV AI
commited on
Commit
ยท
9f9640b
1
Parent(s):
9c8de54
Add PostgreSQL support and update database configuration for data persistence in Hugging Face Spaces
Browse files- DATA_PERSISTENCE_SOLUTION.md +156 -0
- HUGGINGFACE_DEPLOY.md +9 -2
- README.md +7 -1
- app/core/config.py +11 -4
- requirements.txt +2 -0
DATA_PERSISTENCE_SOLUTION.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Hugging Face Spaces ๋ฐ์ดํฐ ์์์ฑ ํด๊ฒฐ ๋ฐฉ๋ฒ
|
| 2 |
+
|
| 3 |
+
## ๋ฌธ์ ์์ธ
|
| 4 |
+
|
| 5 |
+
Hugging Face Spaces๋ Docker ์ปจํ
์ด๋ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ฏ๋ก, **์ปจํ
์ด๋๊ฐ ์ฌ์์๋๊ฑฐ๋ ์
๋ฐ์ดํธ๋๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง๋๋ค.**
|
| 6 |
+
|
| 7 |
+
ํ์ฌ ์ ์ฅ๋๋ ๋ฐ์ดํฐ:
|
| 8 |
+
- ๋ฐ์ดํฐ๋ฒ ์ด์ค: `instance/finance_analysis.db`
|
| 9 |
+
- ์
๋ก๋ ํ์ผ: `uploads/` ํด๋
|
| 10 |
+
- ๋ฒกํฐ DB: `vector_db/` ํด๋
|
| 11 |
+
- ๋ก๊ทธ: `logs/` ํด๋
|
| 12 |
+
|
| 13 |
+
## ํด๊ฒฐ ๋ฐฉ๋ฒ
|
| 14 |
+
|
| 15 |
+
### ๋ฐฉ๋ฒ 1: ์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (๊ถ์ฅ)
|
| 16 |
+
|
| 17 |
+
PostgreSQL, MySQL ๋ฑ ์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์๊ตฌ์ ์ผ๋ก ๋ณด์กด๋ฉ๋๋ค.
|
| 18 |
+
|
| 19 |
+
#### PostgreSQL ์ฌ์ฉ ์์
|
| 20 |
+
|
| 21 |
+
1. **Supabase, Neon, ๋๋ Railway์์ ๋ฌด๋ฃ PostgreSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑ**
|
| 22 |
+
|
| 23 |
+
2. **ํ๊ฒฝ ๋ณ์ ์ค์ ** (Hugging Face Spaces Settings > Repository secrets):
|
| 24 |
+
```
|
| 25 |
+
DATABASE_URL=postgresql://user:password@host:port/database
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
3. **requirements.txt์ PostgreSQL ๋๋ผ์ด๋ฒ ์ถ๊ฐ**:
|
| 29 |
+
```
|
| 30 |
+
psycopg2-binary
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
4. **์ฝ๋ ์์ ** (`app/core/config.py`):
|
| 34 |
+
```python
|
| 35 |
+
SQLALCHEMY_DATABASE_URI: str = os.getenv(
|
| 36 |
+
'DATABASE_URL',
|
| 37 |
+
f'sqlite:///{PROJECT_ROOT / "instance" / "finance_analysis.db"}'
|
| 38 |
+
)
|
| 39 |
+
```
|
| 40 |
+
์ด๋ฏธ ํ๊ฒฝ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก, `DATABASE_URL`๋ง ์ค์ ํ๋ฉด ์๋์ผ๋ก PostgreSQL์ ์ฌ์ฉํฉ๋๋ค.
|
| 41 |
+
|
| 42 |
+
### ๋ฐฉ๋ฒ 2: ์ธ๋ถ ์คํ ๋ฆฌ์ง ์ฌ์ฉ (ํ์ผ ์ ์ฅ์ฉ)
|
| 43 |
+
|
| 44 |
+
์
๋ก๋๋ ํ์ผ๊ณผ ๋ฒกํฐ DB๋ฅผ ์ธ๋ถ ์คํ ๋ฆฌ์ง์ ์ ์ฅํฉ๋๋ค.
|
| 45 |
+
|
| 46 |
+
#### AWS S3 ์ฌ์ฉ ์์
|
| 47 |
+
|
| 48 |
+
1. **boto3 ์ค์น**:
|
| 49 |
+
```
|
| 50 |
+
pip install boto3
|
| 51 |
+
```
|
| 52 |
+
|
| 53 |
+
2. **ํ๊ฒฝ ๋ณ์ ์ค์ **:
|
| 54 |
+
```
|
| 55 |
+
AWS_ACCESS_KEY_ID=your_access_key
|
| 56 |
+
AWS_SECRET_ACCESS_KEY=your_secret_key
|
| 57 |
+
AWS_S3_BUCKET=your_bucket_name
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
3. **์ฝ๋ ์์ **: ํ์ผ ์
๋ก๋/๋ค์ด๋ก๋ ๋ก์ง์ S3๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ
|
| 61 |
+
|
| 62 |
+
#### Google Cloud Storage ์ฌ์ฉ ์์
|
| 63 |
+
|
| 64 |
+
1. **google-cloud-storage ์ค์น**:
|
| 65 |
+
```
|
| 66 |
+
pip install google-cloud-storage
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
2. **ํ๊ฒฝ ๋ณ์ ์ค์ **:
|
| 70 |
+
```
|
| 71 |
+
GCS_BUCKET_NAME=your_bucket_name
|
| 72 |
+
GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
### ๋ฐฉ๋ฒ 3: Hugging Face Dataset ์ฌ์ฉ (๊ฐ๋จํ ๋ฐฉ๋ฒ)
|
| 76 |
+
|
| 77 |
+
Hugging Face์ Dataset API๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
|
| 78 |
+
|
| 79 |
+
1. **datasets ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น**:
|
| 80 |
+
```
|
| 81 |
+
pip install datasets
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
2. **์ฝ๋ ์์**:
|
| 85 |
+
```python
|
| 86 |
+
from datasets import Dataset
|
| 87 |
+
import json
|
| 88 |
+
|
| 89 |
+
# ๋ฐ์ดํฐ ์ ์ฅ
|
| 90 |
+
def save_to_hf_dataset(data, dataset_name):
|
| 91 |
+
dataset = Dataset.from_dict(data)
|
| 92 |
+
dataset.push_to_hub(dataset_name, token=HF_TOKEN)
|
| 93 |
+
|
| 94 |
+
# ๋ฐ์ดํฐ ๋ก๋
|
| 95 |
+
def load_from_hf_dataset(dataset_name):
|
| 96 |
+
dataset = Dataset.from_hub(dataset_name, token=HF_TOKEN)
|
| 97 |
+
return dataset.to_dict()
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
### ๋ฐฉ๋ฒ 4: ์ ๊ธฐ์ ์ธ ๋ฐฑ์
์์คํ
|
| 101 |
+
|
| 102 |
+
์ค์ผ์ค๋ฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ ๊ธฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฐฑ์
ํฉ๋๋ค.
|
| 103 |
+
|
| 104 |
+
1. **๋ฐฑ์
์คํฌ๋ฆฝํธ ์์ฑ** (`backup_data.py`):
|
| 105 |
+
```python
|
| 106 |
+
import shutil
|
| 107 |
+
import os
|
| 108 |
+
from datetime import datetime
|
| 109 |
+
from huggingface_hub import HfApi
|
| 110 |
+
|
| 111 |
+
def backup_to_hf():
|
| 112 |
+
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
|
| 113 |
+
if os.path.exists('instance/finance_analysis.db'):
|
| 114 |
+
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
| 115 |
+
backup_name = f'backup_{timestamp}.db'
|
| 116 |
+
shutil.copy('instance/finance_analysis.db', backup_name)
|
| 117 |
+
|
| 118 |
+
# Hugging Face Hub์ ์
๋ก๋
|
| 119 |
+
api = HfApi()
|
| 120 |
+
api.upload_file(
|
| 121 |
+
path_or_fileobj=backup_name,
|
| 122 |
+
path_in_repo=f'backups/{backup_name}',
|
| 123 |
+
repo_id='your-username/your-repo',
|
| 124 |
+
token=os.getenv('HF_TOKEN')
|
| 125 |
+
)
|
| 126 |
+
```
|
| 127 |
+
|
| 128 |
+
2. **์ค์ผ์ค๋ฌ ์ค์ **: GitHub Actions ๋๋ ์ธ๋ถ ์ค์ผ์ค๋ฌ ์ฌ์ฉ
|
| 129 |
+
|
| 130 |
+
## ์ฆ์ ์ ์ฉ ๊ฐ๋ฅํ ์์ ํด๊ฒฐ์ฑ
|
| 131 |
+
|
| 132 |
+
### ํ๊ฒฝ ๋ณ์๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฒฝ๋ก ๋ณ๊ฒฝ
|
| 133 |
+
|
| 134 |
+
Hugging Face Spaces์ ์์์ฑ ์คํ ๋ฆฌ์ง(์๋ ๊ฒฝ์ฐ)๋ฅผ ์ฌ์ฉ:
|
| 135 |
+
|
| 136 |
+
```python
|
| 137 |
+
# app/core/config.py ์์
|
| 138 |
+
SQLALCHEMY_DATABASE_URI: str = os.getenv(
|
| 139 |
+
'DATABASE_URL',
|
| 140 |
+
f'sqlite:///{os.getenv("HF_HOME", str(PROJECT_ROOT / "instance"))}/finance_analysis.db'
|
| 141 |
+
)
|
| 142 |
+
```
|
| 143 |
+
|
| 144 |
+
## ๊ถ์ฅ ์ฌํญ
|
| 145 |
+
|
| 146 |
+
1. **ํ๋ก๋์
ํ๊ฒฝ**: ๋ฐฉ๋ฒ 1 (์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค) + ๋ฐฉ๋ฒ 2 (์ธ๋ถ ์คํ ๋ฆฌ์ง)
|
| 147 |
+
2. **๊ฐ๋ฐ/ํ
์คํธ ํ๊ฒฝ**: ๋ฐฉ๋ฒ 3 (Hugging Face Dataset) ๋๋ ๋ฐฉ๋ฒ 4 (์ ๊ธฐ ๋ฐฑ์
)
|
| 148 |
+
3. **์ค์ํ ๋ฐ์ดํฐ**: ํญ์ ์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ
|
| 149 |
+
|
| 150 |
+
## ์ฐธ๊ณ
|
| 151 |
+
|
| 152 |
+
- [Hugging Face Spaces ๋ฌธ์](https://huggingface.co/docs/hub/spaces)
|
| 153 |
+
- [Supabase (๋ฌด๋ฃ PostgreSQL)](https://supabase.com/)
|
| 154 |
+
- [Neon (์๋ฒ๋ฆฌ์ค PostgreSQL)](https://neon.tech/)
|
| 155 |
+
- [Railway (PostgreSQL)](https://railway.app/)
|
| 156 |
+
|
HUGGINGFACE_DEPLOY.md
CHANGED
|
@@ -43,10 +43,17 @@ Hugging Face Spaces์ Settings > Repository secrets์์ ๋ค์ ํ๊ฒฝ ๋ณ์
|
|
| 43 |
|
| 44 |
#### ํ์ ํ๊ฒฝ ๋ณ์
|
| 45 |
- `SECRET_KEY`: Flask ์ํฌ๋ฆฟ ํค (๋๋ค ๋ฌธ์์ด ์์ฑ)
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
#### ์ ํ์ ํ๊ฒฝ ๋ณ์
|
| 49 |
-
- `
|
| 50 |
- `OLLAMA_BASE_URL`: Ollama ์๋ฒ URL (๊ธฐ๋ณธ๊ฐ: http://localhost:11434)
|
| 51 |
- `EMBEDDING_MODEL_NAME`: ์๋ฒ ๋ฉ ๋ชจ๋ธ ์ด๋ฆ
|
| 52 |
- `RERANKER_MODEL_NAME`: ๋ฆฌ๋ญ์ปค ๋ชจ๋ธ ์ด๋ฆ
|
|
|
|
| 43 |
|
| 44 |
#### ํ์ ํ๊ฒฝ ๋ณ์
|
| 45 |
- `SECRET_KEY`: Flask ์ํฌ๋ฆฟ ํค (๋๋ค ๋ฌธ์์ด ์์ฑ)
|
| 46 |
+
|
| 47 |
+
#### ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๊ฒฝ ๋ณ์ (๊ถ์ฅ: ์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค)
|
| 48 |
+
- `DATABASE_URL`: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ URL
|
| 49 |
+
- **PostgreSQL (๊ถ์ฅ)**: `postgresql://user:password@host:port/database`
|
| 50 |
+
- ๋ฌด๋ฃ PostgreSQL ์ ๊ณต ์๋น์ค: [Supabase](https://supabase.com/), [Neon](https://neon.tech/), [Railway](https://railway.app/)
|
| 51 |
+
- **SQLite (๊ธฐ๋ณธ๊ฐ)**: ์ค์ ํ์ง ์์ผ๋ฉด ์๋์ผ๋ก SQLite ์ฌ์ฉ
|
| 52 |
+
- โ ๏ธ **์ฃผ์**: Hugging Face Spaces๋ ์ปจํ
์ด๋ ๊ธฐ๋ฐ์ด๋ฏ๋ก SQLite ์ฌ์ฉ ์ ์ฌ์์ ์ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง๋๋ค.
|
| 53 |
+
- ์๊ตฌ ์ ์ฅ์ด ํ์ํ๋ฉด ๋ฐ๋์ ์ธ๋ถ PostgreSQL์ ์ฌ์ฉํ์ธ์.
|
| 54 |
|
| 55 |
#### ์ ํ์ ํ๊ฒฝ ๋ณ์
|
| 56 |
+
- `GEMINI_API_KEY`: Google Gemini API ํค (Gemini ์ฌ์ฉ ์)
|
| 57 |
- `OLLAMA_BASE_URL`: Ollama ์๋ฒ URL (๊ธฐ๋ณธ๊ฐ: http://localhost:11434)
|
| 58 |
- `EMBEDDING_MODEL_NAME`: ์๋ฒ ๋ฉ ๋ชจ๋ธ ์ด๋ฆ
|
| 59 |
- `RERANKER_MODEL_NAME`: ๋ฆฌ๋ญ์ปค ๋ชจ๋ธ ์ด๋ฆ
|
README.md
CHANGED
|
@@ -35,9 +35,15 @@ Settings > Repository secrets์์ ๋ค์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ์ธ์:
|
|
| 35 |
### ํ์
|
| 36 |
- `SECRET_KEY`: Flask ์ํฌ๋ฆฟ ํค (๋๋ค ๋ฌธ์์ด)
|
| 37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
### ์ ํ์ฌํญ
|
| 39 |
- `GEMINI_API_KEY`: Google Gemini API ํค
|
| 40 |
-
- `DATABASE_URL`: ๋ฐ์ดํฐ๋ฒ ์ด์ค URL (๊ธฐ๋ณธ: SQLite)
|
| 41 |
- `OLLAMA_BASE_URL`: Ollama ์๋ฒ URL
|
| 42 |
- `HUGGINGFACE_HUB_TOKEN`: Hugging Face ํ ํฐ
|
| 43 |
|
|
|
|
| 35 |
### ํ์
|
| 36 |
- `SECRET_KEY`: Flask ์ํฌ๋ฆฟ ํค (๋๋ค ๋ฌธ์์ด)
|
| 37 |
|
| 38 |
+
### ๋ฐ์ดํฐ๋ฒ ์ด์ค (๊ถ์ฅ: ์ธ๋ถ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ)
|
| 39 |
+
- `DATABASE_URL`: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ URL
|
| 40 |
+
- **PostgreSQL (๊ถ์ฅ)**: `postgresql://user:password@host:port/database`
|
| 41 |
+
- ๋ฌด๋ฃ PostgreSQL ์ ๊ณต ์๋น์ค: [Supabase](https://supabase.com/), [Neon](https://neon.tech/), [Railway](https://railway.app/)
|
| 42 |
+
- **SQLite (๊ธฐ๋ณธ๊ฐ)**: ์ค์ ํ์ง ์์ผ๋ฉด ์๋์ผ๋ก SQLite ์ฌ์ฉ (โ ๏ธ ๋ฐ์ดํฐ๊ฐ ์๊ตฌ ์ ์ฅ๋์ง ์์)
|
| 43 |
+
- **MySQL**: `mysql://user:password@host:port/database`
|
| 44 |
+
|
| 45 |
### ์ ํ์ฌํญ
|
| 46 |
- `GEMINI_API_KEY`: Google Gemini API ํค
|
|
|
|
| 47 |
- `OLLAMA_BASE_URL`: Ollama ์๋ฒ URL
|
| 48 |
- `HUGGINGFACE_HUB_TOKEN`: Hugging Face ํ ํฐ
|
| 49 |
|
app/core/config.py
CHANGED
|
@@ -19,10 +19,17 @@ class Config:
|
|
| 19 |
|
| 20 |
# Flask ์ค์
|
| 21 |
SECRET_KEY: str = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production')
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
SQLALCHEMY_TRACK_MODIFICATIONS: bool = False
|
| 27 |
MAX_CONTENT_LENGTH: int = 100 * 1024 * 1024 # 100MB
|
| 28 |
|
|
|
|
| 19 |
|
| 20 |
# Flask ์ค์
|
| 21 |
SECRET_KEY: str = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production')
|
| 22 |
+
|
| 23 |
+
# ๋ฐ์ดํฐ๋ฒ ์ด์ค URI ์ค์
|
| 24 |
+
# PostgreSQL: postgresql://user:password@host:port/database
|
| 25 |
+
# SQLite (๊ธฐ๋ณธ๊ฐ): sqlite:///instance/finance_analysis.db
|
| 26 |
+
_database_url = os.getenv('DATABASE_URL', '')
|
| 27 |
+
if _database_url:
|
| 28 |
+
# DATABASE_URL์ด ์ ๊ณต๋๋ฉด ์ฌ์ฉ (PostgreSQL, MySQL ๋ฑ)
|
| 29 |
+
SQLALCHEMY_DATABASE_URI: str = _database_url
|
| 30 |
+
else:
|
| 31 |
+
# ๊ธฐ๋ณธ๊ฐ: SQLite ์ฌ์ฉ
|
| 32 |
+
SQLALCHEMY_DATABASE_URI: str = f'sqlite:///{PROJECT_ROOT / "instance" / "finance_analysis.db"}'
|
| 33 |
SQLALCHEMY_TRACK_MODIFICATIONS: bool = False
|
| 34 |
MAX_CONTENT_LENGTH: int = 100 * 1024 * 1024 # 100MB
|
| 35 |
|
requirements.txt
CHANGED
|
@@ -10,6 +10,8 @@ numpy==1.24.3
|
|
| 10 |
google-generativeai==0.3.2
|
| 11 |
pydantic==2.5.0
|
| 12 |
pydantic-settings==2.1.0
|
|
|
|
|
|
|
| 13 |
# Ollama์ ํ์ด์ฌ์ ์ฐ๊ฒฐํ๋ ค๋ฉด ์๋ ํจํค์ง๊ฐ ๋ณดํต ํ์ํฉ๋๋ค.
|
| 14 |
ollama
|
| 15 |
|
|
|
|
| 10 |
google-generativeai==0.3.2
|
| 11 |
pydantic==2.5.0
|
| 12 |
pydantic-settings==2.1.0
|
| 13 |
+
# Database drivers
|
| 14 |
+
psycopg2-binary # PostgreSQL support for external database
|
| 15 |
# Ollama์ ํ์ด์ฌ์ ์ฐ๊ฒฐํ๋ ค๋ฉด ์๋ ํจํค์ง๊ฐ ๋ณดํต ํ์ํฉ๋๋ค.
|
| 16 |
ollama
|
| 17 |
|