Skip to content

Commit d864009

Browse files
committed
Reliability and security improvements
1 parent b71b54c commit d864009

File tree

8 files changed

+690
-56
lines changed

8 files changed

+690
-56
lines changed

.gitignore

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,100 @@
1-
**/*.DS_Store
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
pip-wheel-metadata/
20+
share/python-wheels/
21+
*.egg-info/
22+
.installed.cfg
23+
*.egg
24+
MANIFEST
25+
26+
# PyInstaller
27+
*.manifest
28+
*.spec
29+
30+
# Unit test / coverage reports
31+
htmlcov/
32+
.tox/
33+
.nox/
34+
.coverage
35+
.coverage.*
36+
.cache
37+
nosetests.xml
38+
coverage.xml
39+
*.cover
40+
*.py,cover
41+
.hypothesis/
42+
.pytest_cache/
43+
44+
# Virtual environments
45+
.env
46+
.venv
47+
env/
48+
venv/
49+
ENV/
50+
env.bak/
51+
venv.bak/
52+
53+
# IDEs
54+
.vscode/
55+
.idea/
56+
*.swp
57+
*.swo
58+
*~
59+
60+
# OS generated files
61+
.DS_Store
62+
.DS_Store?
63+
._*
64+
.Spotlight-V100
65+
.Trashes
66+
ehthumbs.db
67+
Thumbs.db
68+
69+
# Logs
70+
*.log
71+
logs/
72+
73+
# Database
74+
*.db
75+
*.sqlite
76+
*.sqlite3
77+
78+
# Configuration files with sensitive data
79+
config.ini
80+
.env.local
81+
.env.production
82+
83+
# Temporary files
84+
*.tmp
85+
*.temp
86+
temp/
87+
tmp/
88+
89+
# Docker
90+
.dockerignore
91+
92+
# Local data and cookies
93+
src/data/cookies.json
94+
src/data/proxies.json
95+
src/data/*.db
96+
97+
# Test artifacts
98+
.coverage
99+
.pytest_cache/
100+
test-results/

README.md

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
Self-hosted web API that exposes free, unlimited access to modern LLM providers through a single, simple HTTP interface. It includes an optional web GUI for configuration and supports running via Python or Docker.
1010

11-
- Free to use
12-
- Unlimited requests
13-
- Simple HTTP interface (returns plain text)
14-
- Optional Web GUI
15-
- Docker image available
11+
## Key Features
12+
13+
- **Free to use** - No API keys or subscriptions required
14+
- **Unlimited requests** - No rate limiting
15+
- **Simple HTTP interface** - Returns plain text responses
16+
- **Optional Web GUI** - Easy configuration through browser
17+
- **Docker support** - Ready-to-use container available
18+
- **Smart timeout handling** - Automatic retry with optimized timeouts
1619

1720
Note: The demo server, when available, can be overloaded and may not always respond.
1821

@@ -43,13 +46,6 @@ Note: The demo server, when available, can be overloaded and may not always resp
4346

4447
---
4548

46-
## Features
47-
48-
- Self-hosted DeepSeek-R1 and GPT-4o API
49-
- Unlimited usage
50-
- Free of cost
51-
- User-friendly GUI
52-
5349
## Screenshots
5450

5551
<img src="./img/login.png" style="width:100%; max-width:500px; min-width:200px; aspect-ratio: 4/3" />
@@ -112,8 +108,15 @@ pip install -r requirements.txt
112108
```
113109

114110
3. Start the server (basic)
111+
```bash
112+
python3 src/FreeGPT4_Server.py
115113
```
116-
python3 FreeGPT4_Server.py
114+
115+
### Security Note
116+
117+
When using the Web GUI, always set a secure password:
118+
```bash
119+
python3 src/FreeGPT4_Server.py --enable-gui --password your_secure_password
117120
```
118121

119122
---
@@ -170,12 +173,12 @@ From the GUI you can configure common options (e.g., model, provider, keyword, h
170173
## Command-line options
171174

172175
Show help:
173-
```
174-
python3 FreeGPT4_Server.py [-h] [--remove-sources] [--enable-gui]
175-
[--private-mode] [--enable-history] [--password PASSWORD]
176-
[--cookie-file COOKIE_FILE] [--file-input] [--port PORT]
177-
[--model MODEL] [--provider PROVIDER] [--keyword KEYWORD]
178-
[--system-prompt SYSTEM_PROMPT] [--enable-proxies] [--enable-virtual-users]
176+
```bash
177+
python3 src/FreeGPT4_Server.py [-h] [--remove-sources] [--enable-gui]
178+
[--private-mode] [--enable-history] [--password PASSWORD]
179+
[--cookie-file COOKIE_FILE] [--file-input] [--port PORT]
180+
[--model MODEL] [--provider PROVIDER] [--keyword KEYWORD]
181+
[--system-prompt SYSTEM_PROMPT] [--enable-proxies] [--enable-virtual-users]
179182
```
180183

181184
Options:
@@ -219,20 +222,34 @@ Enable proxies to mitigate blocks:
219222

220223
### Models and providers
221224

222-
- Models: includes gpt-4 (and variants such as GPT-4o) and DeepSeek-R1
223-
- Default model: `gpt-4`
224-
- Default provider: `Bing`
225-
- Change via flags or in the GUI:
226-
```
225+
- **Models**: gpt-4, gpt-4o, deepseek-r1, and other modern LLMs
226+
- **Default model**: `gpt-4`
227+
- **Default provider**: `DuckDuckGo` (reliable fallback)
228+
- **Provider Fallback**: Automatic switching between Bing, DuckDuckGo, and other providers
229+
- **Health Monitoring**: Real-time provider status tracking
230+
231+
Change via flags or in the GUI:
232+
```bash
227233
--model gpt-4o --provider Bing
228234
```
229235

236+
### Reliability Features
237+
238+
- **Smart Timeout Handling**: Optimized 30-second timeouts with automatic retry
239+
- **Provider Fallback**: Automatic switching when primary provider fails
240+
- **Health Monitoring**: Continuous provider status tracking
241+
- **Blacklist System**: Automatic exclusion of problematic providers
242+
230243
### Private mode and password
231244

232245
- `--private-mode` requires a private token to access the API
233-
- `--password` protects the settings page (mandatory in some Docker setups)
246+
- `--password` protects the settings page (**mandatory in Docker setups**)
247+
- **Security Enhancement**: Authentication system hardened against bypass attacks
248+
- **Logging**: All authentication attempts are logged for security monitoring
234249
- Use a strong password if you expose the API beyond localhost
235250

251+
**Important**: Always set a password when using the Web GUI to prevent unauthorized access.
252+
236253
---
237254

238255
## Siri integration
@@ -250,13 +267,34 @@ Say “GPT Mode” to Siri and ask your question when prompted.
250267

251268
## Requirements
252269

253-
- Python 3
270+
- Python 3.8+
254271
- Flask[async]
255272
- g4f (from https://github.com/xtekky/gpt4free)
256273
- aiohttp
257274
- aiohttp_socks
258-
- auth
259275
- Werkzeug
276+
- requests (for enhanced HTTP handling)
277+
278+
For development and testing:
279+
- pytest
280+
- pytest-asyncio
281+
282+
## Troubleshooting
283+
284+
### Common Issues
285+
286+
1. **Timeout Errors**: The system now automatically retries with fallback providers
287+
2. **Provider Blocks**: Health monitoring automatically switches to working providers
288+
3. **Authentication Issues**: Ensure you set a strong password and check logs for failed attempts
289+
4. **Docker Permission Issues**: Use read-only mounts for sensitive files like cookies.json
290+
291+
### Getting Help
292+
293+
If you encounter issues:
294+
1. Check the application logs for detailed error information
295+
2. Verify your provider configuration in the Web GUI
296+
3. Ensure cookies are properly formatted (if using)
297+
4. Try different providers through the fallback system
260298

261299
---
262300

@@ -270,9 +308,6 @@ Say “GPT Mode” to Siri and ask your question when prompted.
270308

271309
Contributions are welcome! Feel free to open issues and pull requests to improve features, docs, or reliability.
272310

273-
Credits:
274-
- Some examples and tips credited to community members, including @git-malik and @ayoubelmhamdi.
275-
276311
---
277312

278313
## License

src/FreeGPT4_Server.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,16 @@ def setup_password(self):
252252

253253
try:
254254
settings = db_manager.get_settings()
255+
current_password = settings.get("password", "")
255256

256257
if self.args.password:
257258
# Password provided via command line
258259
password = self.args.password
259260
confirm_password = password
260-
elif not settings.get("password"):
261+
logger.info("Using password provided via command line argument")
262+
elif not current_password:
261263
# No password set, prompt for new one
264+
logger.info("No admin password configured. Setting up new password...")
262265
password = getpass.getpass("Settings page password:\n > ")
263266
confirm_password = getpass.getpass("Confirm password:\n > ")
264267
else:
@@ -275,10 +278,22 @@ def setup_password(self):
275278
logger.error("Passwords don't match")
276279
exit(1)
277280

278-
# Save password
281+
# Additional password strength validation
282+
if len(password) < config.security.password_min_length:
283+
logger.error(f"Password must be at least {config.security.password_min_length} characters long")
284+
exit(1)
285+
286+
# Save password (will be hashed automatically in update_settings)
279287
db_manager.update_settings({"password": password})
280288
logger.info("Admin password configured successfully")
281289

290+
# Verify the password was saved correctly
291+
if not db_manager.verify_admin_password(password):
292+
logger.error("Password verification failed after setup")
293+
exit(1)
294+
295+
logger.info("Password verification successful")
296+
282297
except Exception as e:
283298
logger.error(f"Failed to setup password: {e}")
284299
exit(1)
@@ -405,6 +420,12 @@ def settings():
405420
is_admin = False
406421
if username == "admin":
407422
is_admin = auth_service.authenticate_admin(username, password)
423+
if not is_admin:
424+
return render_template(
425+
"login.html",
426+
virtual_users=server_manager.args.enable_virtual_users,
427+
error="Invalid admin credentials"
428+
)
408429
else:
409430
is_admin = False
410431
if not auth_service.authenticate_user(username, password):
@@ -432,8 +453,8 @@ def settings():
432453
"generic_models": config.generic_models
433454
}
434455

435-
if is_admin or username == "admin":
436-
# Admin settings
456+
if is_admin:
457+
# Admin settings (only if properly authenticated)
437458
template_data["data"] = db_manager.get_settings()
438459

439460
# Load proxies

0 commit comments

Comments
 (0)