Spaces:
Sleeping
Sleeping
Add auth login
Browse files- app.py +28 -5
- requirements.txt +2 -0
- tts_app/__init__.py +2 -0
- tts_app/admin/__init__.py +1 -0
- tts_app/admin/views.py +9 -0
- tts_app/auth/__init__.py +1 -0
- tts_app/auth/forms.py +8 -0
- tts_app/auth/models.py +19 -0
- tts_app/auth/views.py +29 -0
- {static → tts_app/static}/css/bootstrap.min.css +0 -0
- tts_app/static/css/login.css +33 -0
- {static → tts_app/static}/css/style.css +0 -0
- {static → tts_app/static}/js/bootstrap.bundle.min.js +0 -0
- {static → tts_app/static}/js/jquery.slim.min.js +0 -0
- {templates → tts_app/templates}/index.html +4 -4
- tts_app/templates/login.html +25 -0
- tts_app/{auth.py → voice_api/auth.py} +0 -0
- tts_app/voice_api/views.py +1 -1
app.py
CHANGED
|
@@ -1,20 +1,43 @@
|
|
|
|
|
|
|
|
| 1 |
from flask import Flask
|
| 2 |
from flask_apscheduler import APScheduler
|
|
|
|
|
|
|
| 3 |
|
| 4 |
-
from tts_app import frontend, voice_api
|
| 5 |
-
|
| 6 |
-
app = Flask(__name__)
|
| 7 |
|
| 8 |
-
app
|
| 9 |
-
|
| 10 |
|
| 11 |
app.config.from_pyfile("config.py")
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
# Initialize scheduler
|
| 14 |
scheduler = APScheduler()
|
| 15 |
scheduler.init_app(app)
|
| 16 |
if app.config.get("CLEAN_INTERVAL_SECONDS", 3600) > 0:
|
| 17 |
scheduler.start()
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
if __name__ == '__main__':
|
| 20 |
app.run(host='0.0.0.0', port=app.config.get("PORT", 23456), debug=app.config.get("DEBUG", False))
|
|
|
|
| 1 |
+
import os.path
|
| 2 |
+
|
| 3 |
from flask import Flask
|
| 4 |
from flask_apscheduler import APScheduler
|
| 5 |
+
from flask_login import LoginManager
|
| 6 |
+
from flask_wtf import CSRFProtect
|
| 7 |
|
| 8 |
+
from tts_app import frontend, voice_api, auth, admin
|
| 9 |
+
from tts_app.auth.models import users
|
|
|
|
| 10 |
|
| 11 |
+
app = Flask(__name__, template_folder=os.path.join(os.path.dirname(__file__), 'tts_app', 'templates'),
|
| 12 |
+
static_folder=os.path.join(os.path.dirname(__file__), 'tts_app', 'static'))
|
| 13 |
|
| 14 |
app.config.from_pyfile("config.py")
|
| 15 |
|
| 16 |
+
login_manager = LoginManager()
|
| 17 |
+
login_manager.init_app(app)
|
| 18 |
+
login_manager.login_view = 'auth.login'
|
| 19 |
+
|
| 20 |
+
csrf = CSRFProtect(app)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@login_manager.user_loader
|
| 24 |
+
def load_user(user_id):
|
| 25 |
+
for user in users.values():
|
| 26 |
+
if user.get_id() == user_id:
|
| 27 |
+
return user
|
| 28 |
+
return None
|
| 29 |
+
|
| 30 |
+
|
| 31 |
# Initialize scheduler
|
| 32 |
scheduler = APScheduler()
|
| 33 |
scheduler.init_app(app)
|
| 34 |
if app.config.get("CLEAN_INTERVAL_SECONDS", 3600) > 0:
|
| 35 |
scheduler.start()
|
| 36 |
|
| 37 |
+
app.register_blueprint(frontend, url_prefix='/')
|
| 38 |
+
app.register_blueprint(voice_api, url_prefix='/voice')
|
| 39 |
+
app.register_blueprint(auth, url_prefix='/auth')
|
| 40 |
+
app.register_blueprint(admin, url_prefix='/admin')
|
| 41 |
+
|
| 42 |
if __name__ == '__main__':
|
| 43 |
app.run(host='0.0.0.0', port=app.config.get("PORT", 23456), debug=app.config.get("DEBUG", False))
|
requirements.txt
CHANGED
|
@@ -40,6 +40,8 @@ flask==2.2.3
|
|
| 40 |
flask_apscheduler
|
| 41 |
pydantic==2.3.0
|
| 42 |
werkzeug==2.3.6
|
|
|
|
|
|
|
| 43 |
|
| 44 |
# Compression and Decompression
|
| 45 |
py7zr
|
|
|
|
| 40 |
flask_apscheduler
|
| 41 |
pydantic==2.3.0
|
| 42 |
werkzeug==2.3.6
|
| 43 |
+
flask_login
|
| 44 |
+
flask_wtf
|
| 45 |
|
| 46 |
# Compression and Decompression
|
| 47 |
py7zr
|
tts_app/__init__.py
CHANGED
|
@@ -1,2 +1,4 @@
|
|
| 1 |
from tts_app.frontend import frontend
|
| 2 |
from tts_app.voice_api import voice_api
|
|
|
|
|
|
|
|
|
| 1 |
from tts_app.frontend import frontend
|
| 2 |
from tts_app.voice_api import voice_api
|
| 3 |
+
from tts_app.auth import auth
|
| 4 |
+
from tts_app.admin import admin
|
tts_app/admin/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from tts_app.admin.views import admin
|
tts_app/admin/views.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Blueprint
|
| 2 |
+
from flask_login import login_required
|
| 3 |
+
|
| 4 |
+
admin = Blueprint('admin', __name__)
|
| 5 |
+
|
| 6 |
+
@admin.route('/')
|
| 7 |
+
@login_required
|
| 8 |
+
def setting():
|
| 9 |
+
return "Hello Admin!"
|
tts_app/auth/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from tts_app.auth.views import auth
|
tts_app/auth/forms.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask_wtf import FlaskForm
|
| 2 |
+
from wtforms import StringField, PasswordField, SubmitField
|
| 3 |
+
from wtforms.validators import DataRequired, Length
|
| 4 |
+
|
| 5 |
+
class LoginForm(FlaskForm):
|
| 6 |
+
username = StringField('Username', validators=[DataRequired(), Length(1, 64)])
|
| 7 |
+
password = PasswordField('Password', validators=[DataRequired()])
|
| 8 |
+
submit = SubmitField('Login')
|
tts_app/auth/models.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class User:
|
| 2 |
+
def __init__(self, id, username, password):
|
| 3 |
+
self.id = id
|
| 4 |
+
self.username = username
|
| 5 |
+
self.password = password
|
| 6 |
+
|
| 7 |
+
def is_authenticated(self):
|
| 8 |
+
return True
|
| 9 |
+
|
| 10 |
+
def is_active(self):
|
| 11 |
+
return True
|
| 12 |
+
|
| 13 |
+
def is_anonymous(self):
|
| 14 |
+
return False
|
| 15 |
+
|
| 16 |
+
def get_id(self):
|
| 17 |
+
return str(self.id)
|
| 18 |
+
|
| 19 |
+
users = {'admin': User(1, 'admin', 'password')}
|
tts_app/auth/views.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import render_template, redirect, url_for, flash, Blueprint
|
| 2 |
+
from flask_login import login_user, logout_user, login_required
|
| 3 |
+
|
| 4 |
+
from tts_app.auth.forms import LoginForm
|
| 5 |
+
from tts_app.auth.models import users
|
| 6 |
+
|
| 7 |
+
auth = Blueprint('auth', __name__)
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
@auth.route('/login', methods=['GET', 'POST'])
|
| 11 |
+
def login():
|
| 12 |
+
form = LoginForm()
|
| 13 |
+
if form.validate_on_submit():
|
| 14 |
+
user = users.get(form.username.data)
|
| 15 |
+
if user and user.password == form.password.data:
|
| 16 |
+
login_user(user)
|
| 17 |
+
flash('Logged in successfully.')
|
| 18 |
+
return redirect(url_for('admin.setting'))
|
| 19 |
+
flash('Wrong username or password.')
|
| 20 |
+
return render_template('login.html', form=form)
|
| 21 |
+
|
| 22 |
+
@auth.route('/logout')
|
| 23 |
+
@login_required
|
| 24 |
+
def logout():
|
| 25 |
+
logout_user()
|
| 26 |
+
flash('You have been logged out.')
|
| 27 |
+
return redirect(url_for('auth.login'))
|
| 28 |
+
|
| 29 |
+
|
{static → tts_app/static}/css/bootstrap.min.css
RENAMED
|
File without changes
|
tts_app/static/css/login.css
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
body {
|
| 2 |
+
font-family: Arial, sans-serif;
|
| 3 |
+
margin: 50px;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
.container {
|
| 7 |
+
max-width: 300px;
|
| 8 |
+
margin: 0 auto;
|
| 9 |
+
padding: 20px;
|
| 10 |
+
border: 1px solid #ccc;
|
| 11 |
+
border-radius: 5px;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
label, input {
|
| 15 |
+
width: 100%;
|
| 16 |
+
padding: 8px;
|
| 17 |
+
margin-bottom: 10px;
|
| 18 |
+
box-sizing: border-box;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
button {
|
| 22 |
+
width: 100%;
|
| 23 |
+
padding: 10px;
|
| 24 |
+
background-color: #007BFF;
|
| 25 |
+
color: #fff;
|
| 26 |
+
border: none;
|
| 27 |
+
border-radius: 3px;
|
| 28 |
+
cursor: pointer;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
button:hover {
|
| 32 |
+
background-color: #0056b3;
|
| 33 |
+
}
|
{static → tts_app/static}/css/style.css
RENAMED
|
File without changes
|
{static → tts_app/static}/js/bootstrap.bundle.min.js
RENAMED
|
File without changes
|
{static → tts_app/static}/js/jquery.slim.min.js
RENAMED
|
File without changes
|
{templates → tts_app/templates}/index.html
RENAMED
|
@@ -4,8 +4,8 @@
|
|
| 4 |
<meta charset="UTF-8"/>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
| 6 |
<title>vits-simple-api</title>
|
| 7 |
-
<link rel="stylesheet" href="
|
| 8 |
-
<link rel="stylesheet" href="
|
| 9 |
</head>
|
| 10 |
<body>
|
| 11 |
<main class="main-container">
|
|
@@ -323,8 +323,8 @@
|
|
| 323 |
|
| 324 |
</main>
|
| 325 |
|
| 326 |
-
<script src="
|
| 327 |
-
<script src="
|
| 328 |
|
| 329 |
<script>
|
| 330 |
$(function () {
|
|
|
|
| 4 |
<meta charset="UTF-8"/>
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
| 6 |
<title>vits-simple-api</title>
|
| 7 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
| 8 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
|
| 9 |
</head>
|
| 10 |
<body>
|
| 11 |
<main class="main-container">
|
|
|
|
| 323 |
|
| 324 |
</main>
|
| 325 |
|
| 326 |
+
<script src="{{ url_for('static', filename='js/jquery.slim.min.js') }}"></script>
|
| 327 |
+
<script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script>
|
| 328 |
|
| 329 |
<script>
|
| 330 |
$(function () {
|
tts_app/templates/login.html
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Login</title>
|
| 7 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/login.css') }}">
|
| 8 |
+
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
|
| 9 |
+
</head>
|
| 10 |
+
<body>
|
| 11 |
+
<div class="container">
|
| 12 |
+
<h2>Login</h2>
|
| 13 |
+
<form action="{{ url_for('auth.login') }}" method="post">
|
| 14 |
+
{{ form.hidden_tag() }}
|
| 15 |
+
<label for="username">Username:</label>
|
| 16 |
+
<input type="text" id="username" name="username" required>
|
| 17 |
+
|
| 18 |
+
<label for="password">Password:</label>
|
| 19 |
+
<input type="password" id="password" name="password" required>
|
| 20 |
+
|
| 21 |
+
<button type="submit">Login</button>
|
| 22 |
+
</form>
|
| 23 |
+
</div>
|
| 24 |
+
</body>
|
| 25 |
+
</html>
|
tts_app/{auth.py → voice_api/auth.py}
RENAMED
|
File without changes
|
tts_app/voice_api/views.py
CHANGED
|
@@ -7,7 +7,7 @@ from werkzeug.utils import secure_filename
|
|
| 7 |
|
| 8 |
from logger import logger
|
| 9 |
from contants import ModelType
|
| 10 |
-
from tts_app.auth import require_api_key
|
| 11 |
from tts_app.model_manager import model_manager, tts_manager
|
| 12 |
from tts_app.voice_api.utils import *
|
| 13 |
from utils.data_utils import check_is_none
|
|
|
|
| 7 |
|
| 8 |
from logger import logger
|
| 9 |
from contants import ModelType
|
| 10 |
+
from tts_app.voice_api.auth import require_api_key
|
| 11 |
from tts_app.model_manager import model_manager, tts_manager
|
| 12 |
from tts_app.voice_api.utils import *
|
| 13 |
from utils.data_utils import check_is_none
|