Skip to content

Commit f5dcf42

Browse files
authored
Merge pull request #20 from EmccK/main
feat: Add internationalization support, API KEY settings
2 parents 8eea4d1 + 91e106a commit f5dcf42

File tree

16 files changed

+6056
-249
lines changed

16 files changed

+6056
-249
lines changed

.env.example

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1-
# Server configuration
1+
# TTSFM Environment Configuration
2+
3+
# Server Configuration
24
HOST=0.0.0.0
35
PORT=7000
46

5-
# SSL configuration
7+
# SSL Configuration
68
VERIFY_SSL=true
79

8-
# Flask configuration
10+
# Flask Configuration
911
FLASK_ENV=production
10-
FLASK_APP=app.py
12+
FLASK_APP=app.py
13+
DEBUG=false
14+
15+
# API Key Protection (Optional)
16+
# Set REQUIRE_API_KEY=true to enable API key authentication
17+
REQUIRE_API_KEY=false
18+
19+
# Set your API key here when protection is enabled
20+
# This key will be required for all TTS generation requests
21+
TTSFM_API_KEY=your-secret-api-key-here
22+
23+
# Example usage:
24+
# 1. Set REQUIRE_API_KEY=true
25+
# 2. Set TTSFM_API_KEY to your desired secret key
26+
# 3. Restart the application
27+
# 4. All TTS requests will now require the API key in:
28+
# - Authorization header (Bearer token) - OpenAI compatible
29+
# - X-API-Key header
30+
# - api_key query parameter
31+
# - api_key in JSON body

API_KEY_USAGE.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# 🔐 TTSFM API Key Usage Guide
2+
3+
## Quick Start
4+
5+
### 1. Enable API Key Protection
6+
7+
```bash
8+
# Set environment variables
9+
export REQUIRE_API_KEY=true
10+
export TTSFM_API_KEY=your-secret-api-key
11+
12+
# Run TTSFM with protection
13+
docker run -p 8000:8000 \
14+
-e REQUIRE_API_KEY=true \
15+
-e TTSFM_API_KEY=your-secret-api-key \
16+
ghcr.io/dbccccccc/ttsfm:latest
17+
```
18+
19+
### 2. Use with OpenAI Python Client
20+
21+
```python
22+
from openai import OpenAI
23+
24+
# Configure client with your API key
25+
client = OpenAI(
26+
api_key="your-secret-api-key",
27+
base_url="http://localhost:8000/v1"
28+
)
29+
30+
# Generate speech (exactly like OpenAI)
31+
response = client.audio.speech.create(
32+
model="gpt-4o-mini-tts",
33+
voice="alloy",
34+
input="Hello from TTSFM with API key protection!"
35+
)
36+
37+
response.stream_to_file("protected_speech.mp3")
38+
```
39+
40+
### 3. Use with curl
41+
42+
```bash
43+
# Standard Authorization header (OpenAI compatible)
44+
curl -X POST http://localhost:8000/v1/audio/speech \
45+
-H "Authorization: Bearer your-secret-api-key" \
46+
-H "Content-Type: application/json" \
47+
-d '{
48+
"model": "gpt-4o-mini-tts",
49+
"input": "Hello, world!",
50+
"voice": "alloy",
51+
"response_format": "mp3"
52+
}' \
53+
--output speech.mp3
54+
```
55+
56+
## Authentication Methods
57+
58+
TTSFM accepts API keys in multiple formats (in order of priority):
59+
60+
### 1. Authorization Header (Recommended)
61+
```bash
62+
Authorization: Bearer your-api-key
63+
```
64+
65+
### 2. X-API-Key Header
66+
```bash
67+
X-API-Key: your-api-key
68+
```
69+
70+
### 3. Query Parameter
71+
```bash
72+
?api_key=your-api-key
73+
```
74+
75+
### 4. JSON Body
76+
```json
77+
{"api_key": "your-api-key", ...}
78+
```
79+
80+
## Environment Variables
81+
82+
| Variable | Default | Description |
83+
|----------|---------|-------------|
84+
| `REQUIRE_API_KEY` | `false` | Enable/disable API key protection |
85+
| `TTSFM_API_KEY` | `None` | Your secret API key |
86+
87+
## Protected vs Public Endpoints
88+
89+
### Protected (Require API Key)
90+
- `POST /v1/audio/speech`
91+
- `POST /api/generate`
92+
- `POST /api/generate-combined`
93+
94+
### Public (Always Accessible)
95+
- `GET /` - Web interface
96+
- `GET /playground` - Interactive playground
97+
- `GET /api/health` - Health check
98+
- `GET /api/voices` - Available voices
99+
- `GET /api/formats` - Supported formats
100+
- `GET /api/auth-status` - Authentication status
101+
102+
## Error Responses
103+
104+
When API key is invalid or missing:
105+
106+
```json
107+
{
108+
"error": {
109+
"message": "Invalid API key provided",
110+
"type": "invalid_request_error",
111+
"code": "invalid_api_key"
112+
}
113+
}
114+
```
115+
116+
## Security Best Practices
117+
118+
1. **Use HTTPS in production**
119+
2. **Keep API keys secret** - never commit to version control
120+
3. **Use environment variables** for configuration
121+
4. **Rotate keys regularly**
122+
5. **Monitor access logs** for suspicious activity
123+
124+
## Disable Protection
125+
126+
To disable API key protection:
127+
128+
```bash
129+
export REQUIRE_API_KEY=false
130+
# or remove the environment variable entirely
131+
```
132+
133+
Then restart the application.

README.md

Lines changed: 127 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# TTSFM - Text-to-Speech API Client
22

3+
> **Language / 语言**: [English](README.md) | [中文](README.zh.md)
4+
35
[![Docker Pulls](https://img.shields.io/docker/pulls/dbcccc/ttsfm?style=flat-square&logo=docker)](https://hub.docker.com/r/dbcccc/ttsfm)
46
[![GitHub Stars](https://img.shields.io/github/stars/dbccccccc/ttsfm?style=social)](https://github.com/dbccccccc/ttsfm)
57
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
@@ -26,6 +28,7 @@ TTSFM provides both synchronous and asynchronous Python clients for text-to-spee
2628
- 🛡️ **Error Handling** - Comprehensive exception hierarchy with retry logic
2729
-**Auto-Combine** - Automatically handles long text with seamless audio combining
2830
- 📊 **Text Validation** - Automatic text length validation and splitting
31+
- 🔐 **API Key Protection** - Optional OpenAI-compatible authentication for secure deployments
2932

3033
## 📦 Installation
3134

@@ -162,9 +165,15 @@ print(f"Generated {len(responses)} audio files from long text")
162165
```python
163166
from openai import OpenAI
164167

165-
# Point to TTSFM Docker container
168+
# Point to TTSFM Docker container (no API key required by default)
166169
client = OpenAI(
167-
api_key="not-needed", # TTSFM is free
170+
api_key="not-needed", # TTSFM is free by default
171+
base_url="http://localhost:8000/v1"
172+
)
173+
174+
# When API key protection is enabled
175+
client_with_auth = OpenAI(
176+
api_key="your-secret-api-key", # Your TTSFM API key
168177
base_url="http://localhost:8000/v1"
169178
)
170179

@@ -241,12 +250,24 @@ ttsfm --help
241250

242251
## ⚙️ Configuration
243252

244-
TTSFM automatically uses the free openai.fm service - **no configuration or API keys required!**
253+
TTSFM automatically uses the free openai.fm service - **no configuration or API keys required by default!**
254+
255+
### Environment Variables
256+
257+
| Variable | Default | Description |
258+
|----------|---------|-------------|
259+
| `REQUIRE_API_KEY` | `false` | Enable API key protection |
260+
| `TTSFM_API_KEY` | `None` | Your secret API key |
261+
| `HOST` | `localhost` | Server host |
262+
| `PORT` | `8000` | Server port |
263+
| `DEBUG` | `false` | Debug mode |
264+
265+
### Python Client Configuration
245266

246267
```python
247268
from ttsfm import TTSClient
248269

249-
# Default client (uses openai.fm)
270+
# Default client (uses openai.fm, no API key needed)
250271
client = TTSClient()
251272

252273
# Custom configuration
@@ -257,7 +278,13 @@ client = TTSClient(
257278
verify_ssl=True # SSL verification
258279
)
259280

260-
# For custom TTS services
281+
# For TTSFM server with API key protection
282+
protected_client = TTSClient(
283+
base_url="http://localhost:8000",
284+
api_key="your-ttsfm-api-key"
285+
)
286+
287+
# For other custom TTS services
261288
custom_client = TTSClient(
262289
base_url="http://your-tts-service.com",
263290
api_key="your-api-key-if-needed"
@@ -408,7 +435,7 @@ When running the Docker container, these endpoints are available:
408435
### OpenAI-Compatible API
409436

410437
```bash
411-
# Generate speech (short text)
438+
# Generate speech (short text) - no API key required by default
412439
curl -X POST http://localhost:8000/v1/audio/speech \
413440
-H "Content-Type: application/json" \
414441
-d '{
@@ -419,6 +446,18 @@ curl -X POST http://localhost:8000/v1/audio/speech \
419446
}' \
420447
--output speech.mp3
421448

449+
# Generate speech with API key (when protection is enabled)
450+
curl -X POST http://localhost:8000/v1/audio/speech \
451+
-H "Content-Type: application/json" \
452+
-H "Authorization: Bearer your-secret-api-key" \
453+
-d '{
454+
"model": "gpt-4o-mini-tts",
455+
"input": "Hello, this is a test!",
456+
"voice": "alloy",
457+
"response_format": "mp3"
458+
}' \
459+
--output speech.mp3
460+
422461
# Generate speech from long text with auto-combine (default behavior)
423462
curl -X POST http://localhost:8000/v1/audio/speech \
424463
-H "Content-Type: application/json" \
@@ -464,9 +503,15 @@ TTSFM extends the OpenAI API with an optional `auto_combine` parameter:
464503
### Quick Start
465504

466505
```bash
467-
# Run with default settings
506+
# Run with default settings (no API key required)
468507
docker run -p 8000:8000 ghcr.io/dbccccccc/ttsfm:latest
469508

509+
# Run with API key protection enabled
510+
docker run -p 8000:8000 \
511+
-e REQUIRE_API_KEY=true \
512+
-e TTSFM_API_KEY=your-secret-api-key \
513+
ghcr.io/dbccccccc/ttsfm:latest
514+
470515
# Run with custom port
471516
docker run -p 3000:8000 ghcr.io/dbccccccc/ttsfm:latest
472517

@@ -485,6 +530,9 @@ services:
485530
- "8000:8000"
486531
environment:
487532
- PORT=8000
533+
# Optional: Enable API key protection
534+
- REQUIRE_API_KEY=false
535+
- TTSFM_API_KEY=your-secret-api-key-here
488536
restart: unless-stopped
489537
healthcheck:
490538
test: ["CMD", "curl", "-f", "http://localhost:8000/api/health"]
@@ -620,9 +668,71 @@ for text in texts:
620668
response = client.generate_speech(text) # Reuses connection
621669
```
622670

671+
## 🔐 API Key Protection (Optional)
672+
673+
TTSFM supports **OpenAI-compatible API key authentication** for secure deployments:
674+
675+
### Quick Setup
676+
677+
```bash
678+
# Enable API key protection
679+
export REQUIRE_API_KEY=true
680+
export TTSFM_API_KEY=your-secret-api-key
681+
682+
# Run with protection enabled
683+
docker run -p 8000:8000 \
684+
-e REQUIRE_API_KEY=true \
685+
-e TTSFM_API_KEY=your-secret-api-key \
686+
ghcr.io/dbccccccc/ttsfm:latest
687+
```
688+
689+
### Authentication Methods
690+
691+
API keys are accepted in **OpenAI-compatible format**:
692+
693+
```python
694+
from openai import OpenAI
695+
696+
# Standard OpenAI format
697+
client = OpenAI(
698+
api_key="your-secret-api-key",
699+
base_url="http://localhost:8000/v1"
700+
)
701+
702+
# Or using curl
703+
curl -X POST http://localhost:8000/v1/audio/speech \
704+
-H "Authorization: Bearer your-secret-api-key" \
705+
-H "Content-Type: application/json" \
706+
-d '{"model":"gpt-4o-mini-tts","input":"Hello!","voice":"alloy"}'
707+
```
708+
709+
### Features
710+
711+
- 🔑 **OpenAI-Compatible**: Uses standard `Authorization: Bearer` header
712+
- 🛡️ **Multiple Auth Methods**: Header, query param, or JSON body
713+
- 🎛️ **Configurable**: Easy enable/disable via environment variables
714+
- 📊 **Security Logging**: Tracks invalid access attempts
715+
- 🌐 **Web Interface**: Automatic API key field detection
716+
717+
### Protected Endpoints
718+
719+
When enabled, these endpoints require authentication:
720+
- `POST /v1/audio/speech` - Speech generation
721+
- `POST /api/generate` - Legacy speech generation
722+
- `POST /api/generate-combined` - Combined speech generation
723+
724+
### Public Endpoints
725+
726+
These remain accessible without authentication:
727+
- `GET /` - Web interface
728+
- `GET /playground` - Interactive playground
729+
- `GET /api/health` - Health check
730+
- `GET /api/voices` - Available voices
731+
- `GET /api/formats` - Supported formats
732+
623733
## 🔒 Security & Privacy
624734

625-
- **No API Keys Required**: Uses free openai.fm service
735+
- **Optional API Keys**: Free by default, secure when needed
626736
- **No Data Storage**: Audio is generated on-demand, not stored
627737
- **HTTPS Support**: Secure connections to TTS service
628738
- **No Tracking**: TTSFM doesn't collect or store user data
@@ -642,6 +752,8 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
642752
- 🧹 **Streamlined Web Interface**: Removed legacy batch processing for cleaner user experience
643753
- 📖 **Simplified Documentation**: Web docs emphasize modern auto-combine approach
644754
- 🎮 **Enhanced Playground**: Clean interface focused on auto-combine functionality
755+
- 🔐 **API Key Protection**: Optional OpenAI-compatible authentication for secure deployments
756+
- 🛡️ **Security Features**: Comprehensive access control with detailed logging
645757

646758
## 🤝 Support & Community
647759

@@ -670,6 +782,13 @@ MIT License - see [LICENSE](LICENSE) file for details.
670782
[![PyPI](https://img.shields.io/badge/PyPI-ttsfm-blue?style=flat-square&logo=pypi)](https://pypi.org/project/ttsfm/)
671783
[![Docker](https://img.shields.io/badge/Docker-dbcccc/ttsfm-blue?style=flat-square&logo=docker)](https://hub.docker.com/r/dbcccc/ttsfm)
672784

785+
---
786+
787+
## 📖 Documentation
788+
789+
- 🇺🇸 **English**: [README.md](README.md)
790+
- 🇨🇳 **中文**: [README.zh.md](README.zh.md)
791+
673792
Made with ❤️ by [@dbcccc](https://github.com/dbccccccc)
674793

675794
</div>

0 commit comments

Comments
 (0)