Skip to content
Merged

Prod #11

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0ccdef1
prod: deploy to vercel (WIP)
khaledsAlshibani Mar 22, 2025
c10a887
prod(vercel): fix CORS issues
khaledsAlshibani Mar 23, 2025
70e2730
feat: add support for Fast-Whisper as an option and integrate with th…
Muneeb-Almoliky Mar 24, 2025
5aae38e
feat: add support for Gemini model for summarization
Muneeb-Almoliky Mar 24, 2025
c14da72
feat: enhance API key guard to allow API users of Gemini and Fast-Whi…
Muneeb-Almoliky Mar 24, 2025
4c9cd9a
refactor: switch back to yt-dlp-exec from ytdl-mp3
Muneeb-Almoliky Mar 24, 2025
7f4442f
feat: use text language for summary if 'lang' is default or missing
Muneeb-Almoliky Mar 25, 2025
0336c5f
refactor: change default language from 'english' to 'default'
Muneeb-Almoliky Mar 25, 2025
0f9291c
fix: added referer and user-agent headers to ytDlpExec to avoid reque…
Muneeb-Almoliky Mar 25, 2025
a3aacba
fix: improve error handling for summarization APIs
Muneeb-Almoliky Mar 26, 2025
e7a333b
ci(deploy): add workflow for auto deploy on prod branch
khaledsAlshibani Mar 26, 2025
df27c38
chore: test auto deployment
Muneeb-Almoliky Mar 26, 2025
42cd129
ci(prod): update dir path
khaledsAlshibani Mar 26, 2025
d28b352
Merge branch 'prod' of github.com:LetsSummary/lets-summarize-api into…
khaledsAlshibani Mar 26, 2025
ed8d036
ci(prod): update dir path
khaledsAlshibani Mar 26, 2025
76d95fc
refactor(video): switch to youtubei.js for transcript fetching
Muneeb-Almoliky Mar 27, 2025
1361d6b
chore: test auto deployment
Muneeb-Almoliky Mar 27, 2025
09c2e53
fix(download): force generic extractor to bypass YouTube restrictions
Muneeb-Almoliky Mar 27, 2025
f95f77e
fix: authenticate yt-dlp with GVS using PO token
Muneeb-Almoliky Mar 27, 2025
89f8d39
fix: add YouTube session cookies for authentication
Muneeb-Almoliky Mar 28, 2025
172a497
feat: add abillity to add multible allowed origins
khaledsAlshibani Mar 28, 2025
2dccf49
refactor: reuse CORS_ORIGINS constans for CORS config
khaledsAlshibani Mar 28, 2025
b18041a
chore(package.json): add prestart script
khaledsAlshibani Mar 28, 2025
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
11 changes: 7 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ OPENAI_API_KEY=your_openai_api_key_here
# DeepSeek API Key for summarization
DEEPSEEK_API_KEY=

# Origin that is allowed to use the `OPENAI_API_KEY` & `DEEPSEEK_API_KEY` provided by the API
# instead of needing to provide them as `Authorization` in each request from client
ALLOWED_ORIGIN=http://localhost:3001
# Origins that are allowed to use the AI models keys provided by the API, seperate them using a comma
# instead of need to provide them as Authorization in each request from client
ALLOWED_ORIGINS=http://localhost:3001

# Max Tokens (Limit the response length)
OPENAI_MAX_TOKENS=500
Expand All @@ -22,4 +22,7 @@ AWS_S3_BUCKET=your-bucket-name
USE_S3=false


MAX_TRANSCRIPT_TOKENS=
MAX_TRANSCRIPT_TOKENS=

FASTAPI_URL=
GEMENI_API_KEY=
31 changes: 31 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Deploy API

on:
push:
branches:
- prod

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.PROD_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.PROD_HOST }} >> ~/.ssh/known_hosts

- name: Deploy via SSH
run: |
ssh ${{ secrets.PROD_USER }}@${{ secrets.PROD_HOST }} << 'EOF'
cd ~/api
git pull origin prod
pnpm install
pnpm build
pm2 restart letssummarize-api
EOF
18 changes: 9 additions & 9 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
The Summarization API uses **API Key authentication** to control access.
There are two ways to provide an API key:

1. **Environment Variables (`.env`)** – The API owner can set `OPENAI_API_KEY` and `DEEPSEEK_API_KEY` to allow authorized access without requiring clients to provide API keys. However this only works if the **origin** is same as the value of `ALLOWED_ORIGIN`.
1. **Environment Variables (`.env`)** – The API owner can set `OPENAI_API_KEY` and `DEEPSEEK_API_KEY` to allow authorized access without requiring clients to provide API keys. However this only works if the **origin** is a value in `ALLOWED_ORIGINS`.
2. **Request Headers** – Clients can include an API key in the `Authorization` header for each request.

> When there is both a `.env` key and a request header key, the request header key will be used.
Expand Down Expand Up @@ -45,15 +45,15 @@ Authorization: Bearer YOUR_API_KEY

## 2. Allowed Origin Configuration

The API restricts access to the default keys to specific **frontend applications** by defining `ALLOWED_ORIGIN`.
The API restricts access to the default keys to specific **frontend applications** by defining `ALLOWED_ORIGINS`.
If an origin is **not** allowed, then the api key must be provided in the request headers.

```ini
ALLOWED_ORIGIN=http://localhost:3001
ALLOWED_ORIGINS=http://localhost:3001,http://localhost:3000
```

- If a frontend **matches `ALLOWED_ORIGIN`**, it **does not** need to send API keys.
- If a frontend **is not listed in `ALLOWED_ORIGIN`**, it must include API keys in request headers.
- If a frontend **is listed in `ALLOWED_ORIGINS`**, it **does not** need to send API keys.
- If a frontend **is not listed in `ALLOWED_ORIGINS`**, it must include API keys in request headers.

---

Expand All @@ -65,9 +65,9 @@ The API uses a **security guard (`ApiKeyGuard`)** to verify API keys before proc

| **Scenario** | **What Happens?** | **Notes** |
| ---------------------------------------------- | -------------------------------------------- | -------------------------------------------- |
| **Valid API Key in Request Header** | ✅ Request is allowed | Does not require origin to be provided in `ALLOWED_ORIGIN` |
| **Valid API Key in `.env` but not in request** | ✅ Request is allowed (uses `.env` key) | Requires origin to be provided in `ALLOWED_ORIGIN` |
| **Valid API Key in `.env` and in request** | ✅ Request is allowed (uses request api key) | ✅Even if the origin is same as the valud of `ALLOWED_ORIGIN`, api key in the request will be used |
| **Valid API Key in Request Header** | ✅ Request is allowed | Does not require origin to be provided in `ALLOWED_ORIGINS` |
| **Valid API Key in `.env` but not in request** | ✅ Request is allowed (uses `.env` key) | Requires origin to be provided in `ALLOWED_ORIGINS` |
| **Valid API Key in `.env` and in request** | ✅ Request is allowed (uses request api key) | ✅Even if the origin is provided in `ALLOWED_ORIGINS`, api key in the request will be used |
| **No API Key provided in request or `.env`** | ❌ Request is rejected | |

---
Expand All @@ -81,7 +81,7 @@ curl -X POST http://localhost:3000/summarize/text \
-d '{ "content": { "text": "This is a test." }, "options": {} }'
```

This will be valid only if the `ALLOWED_ORIGIN` is `http://localhost:3001`.
This will be valid only if the `ALLOWED_ORIGINS` contains `http://localhost:3001`.

---

Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ OPENAI_API_KEY=
# DeepSeek API Key for summarization (Optional if provided in request headers)
DEEPSEEK_API_KEY=

# Origin that is allowed to use the `OPENAI_API_KEY` & `DEEPSEEK_API_KEY` provided by the API
# instead of needing to provide them as `Authorization` in each request from client
ALLOWED_ORIGIN=http://localhost:3001
# Origins that are allowed to use the AI models keys provided by the API, seperate them using a comma
# instead of need to provide them as Authorization in each request from client
ALLOWED_ORIGINS=http://localhost:3001,http://localhost:3000

# Max Tokens (Limit the response length)
OPENAI_MAX_TOKENS=500
Expand All @@ -87,9 +87,9 @@ Below is a breakdown of the `.env` variables and their functions:
| **Variable** | **Description** | **Required?** | **Default Value** |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------------------- |
| `NODE_ENV` | Node.js environment (development, production, etc.) | ❌ No | None |
| `OPENAI_API_KEY` | API key for using OpenAI GPT-4o, Whisper, and TTS-1 models. Only works if the origin matches the value of `ALLOWED_ORIGIN`. _(can be provided in request headers instead)_ | ❌ No | None |
| `DEEPSEEK_API_KEY` | API key for using DeepSeek Chat (DeepSeek-V3). Only works if the origin matches the value of `ALLOWED_ORIGIN`. _(can be provided in request headers instead)_ | ❌ No | None |
| `ALLOWED_ORIGIN` | Specifies the allowed frontend origin that can access API-provided keys | ❌ No | `http://localhost:3001` |
| `OPENAI_API_KEY` | API key for using OpenAI GPT-4o, Whisper, and TTS-1 models. Only works if the origin is listed in the `ALLOWED_ORIGINS`. _(can be provided in request headers instead)_ | ❌ No | None |
| `DEEPSEEK_API_KEY` | API key for using DeepSeek Chat (DeepSeek-V3). Only works if the origin is listed in the `ALLOWED_ORIGINS`. _(can be provided in request headers instead)_ | ❌ No | None |
| `ALLOWED_ORIGINS` | Specifies the allowed frontend origins that can access API-provided keys | ❌ No | `http://localhost:3001` |
| `OPENAI_MAX_TOKENS` | Maximum token limit for OpenAI-generated responses | ❌ No | `500` |
| `DEEPSEEK_MAX_TOKENS` | Maximum token limit for DeepSeek-generated responses | ❌ No | `1000` |
| `AWS_ACCESS_KEY_ID` | AWS Access Key for S3 storage (for text-to-speech audio files) | ⚠️ Required only if `USE_S3` is `true` | None |
Expand Down
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"prestart": "pnpm run build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
Expand All @@ -21,23 +22,29 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.758.0",
"@google/genai": "^0.6.0",
"@nestjs/axios": "^4.0.0",
"@nestjs/common": "^11.0.1",
"@nestjs/core": "^11.0.1",
"@nestjs/platform-express": "^11.0.1",
"@nestjs/schedule": "^5.0.1",
"@nestjs/serve-static": "^5.0.3",
"aws-sdk": "^2.1692.0",
"axios": "^1.8.4",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"dotenv": "^16.4.7",
"fluent-ffmpeg": "^2.1.3",
"form-data": "^4.0.2",
"mammoth": "^1.9.0",
"multer": "1.4.5-lts.1",
"openai": "^4.87.3",
"pdf-parse": "^1.1.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"youtube-transcript": "^1.2.1",
"youtubei.js": "^13.3.0",
"yt-dlp-exec": "^1.0.2",
"ytdl-mp3": "^5.2.2"
},
"devDependencies": {
Expand Down Expand Up @@ -92,7 +99,8 @@
"pnpm": {
"onlyBuiltDependencies": [
"ffmpeg-static",
"ytdl-mp3"
"ytdl-mp3",
"yt-dlp-exec"
]
}
}
Loading