Skip to content

Commit

Permalink
Add prometheus metrics pytvzhen_api_request_counter.
Browse files Browse the repository at this point in the history
  • Loading branch information
HanFa committed Jun 6, 2024
1 parent 2851190 commit 7813e67
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 16 deletions.
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ ENV FLASK_RUN_PORT 8080
ENV FLASK_APP app.py
ENV FLASK_DEBUG 0

ARG PYTVZHEN_STAGE=beta
ENV PYTVZHEN_STAGE=${PYTVZHEN_STAGE}

# Run app.py when the container launches
CMD [ "/bin/bash", "-c", "python -m flask run --host=0.0.0.0" ]
74 changes: 58 additions & 16 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@
app = Flask(__name__)
app.config.from_file("./pytvzhen-config.json", load=json.load)
metrics = PrometheusMetrics(app)
metrics.info('pytvzhen_web', 'Pytvzhen backend API', version='1.0.0')

PYTVZHEN_STAGE = 'PYTVZHEN_STAGE'

pytvzhen_api_request_counter = metrics.counter(
'pytvzhen_api_request_counter', 'Request count by request paths',
labels={'base_url': lambda: url_rule_to_base(request.url_rule), 'stage': lambda: pytvzhen_stage(),
'method': lambda: request.method, 'status': lambda r: r.status_code}
)


def pytvzhen_stage():
return os.environ[PYTVZHEN_STAGE] if PYTVZHEN_STAGE in os.environ else 'default'


def log_info_return_str(message):
app.logger.info(message)
Expand All @@ -35,6 +49,11 @@ def log_warning_return_str(message):
return message


def url_rule_to_base(url_rule):
base_path = str(url_rule)
return base_path.split('<')[0].rstrip('/')


def require_video_id_from_post_request(func):
@wraps(func)
def decorated_func(*args, **kwargs):
Expand All @@ -56,6 +75,7 @@ def decorated_func(*args, **kwargs):


@app.route('/', methods=['GET'])
@metrics.do_not_track()
def index():
return render_template('index.html')

Expand All @@ -67,6 +87,7 @@ def video_extension_allowed(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


def get_extension(filename):
return filename.rsplit('.', 1)[1].lower()

Expand All @@ -77,6 +98,7 @@ def unique_video_fn_with_extension(extension):


@app.route('/video_upload', methods=['POST'])
@pytvzhen_api_request_counter
def video_upload():
output_path = app.config['OUTPUT_PATH']

Expand All @@ -103,6 +125,7 @@ def video_upload():


@app.route('/yt_download', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def yt_download(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -140,6 +163,7 @@ def yt_download(video_id):


@app.route('/yt/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def yt_serve(video_id):
output_path = app.config['OUTPUT_PATH']
video_fn = f'{video_id}.mp4'
Expand All @@ -151,6 +175,7 @@ def yt_serve(video_id):


@app.route('/extra_audio', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def extra_audio(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -182,6 +207,7 @@ def extra_audio(video_id):


@app.route('/audio/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def audio_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -197,6 +223,7 @@ def audio_serve(video_id):


@app.route('/remove_audio_bg', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def remove_audio_bg(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -236,6 +263,7 @@ def remove_audio_bg(video_id):


@app.route('/audio_no_bg/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def audio_no_bg_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -250,6 +278,7 @@ def audio_no_bg_serve(video_id):


@app.route('/audio_bg/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def audio_bg_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -264,6 +293,7 @@ def audio_bg_serve(video_id):


@app.route('/transcribe', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def transcribe(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -315,21 +345,8 @@ def srt_en_serve(video_id):
f'Transcribed English SRT {en_srt_fn} not found at {en_srt_path}')}), 404


@app.route('/srt_en_merged/<video_id>', methods=['GET'])
def srt_en_merged_serve(video_id):
output_path = app.config['OUTPUT_PATH']

en_srt_merged_fn = f'{video_id}_en_merged.srt'
en_srt_merged_path = os.path.join(output_path, en_srt_merged_fn)

if os.path.exists(en_srt_merged_path):
return send_from_directory(output_path, en_srt_merged_fn, as_attachment=True)

return jsonify({"message": log_warning_return_str(
f'Transcribed English SRT {en_srt_merged_fn} not found at {en_srt_merged_path}')}), 404


@app.route('/translate_to_zh', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def transhlate_to_zh(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -396,7 +413,24 @@ def transhlate_to_zh(video_id):

return jsonify({"message": log_error_return_str("Translate failed.")}), 500


@app.route('/srt_en_merged/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def srt_en_merged_serve(video_id):
output_path = app.config['OUTPUT_PATH']

en_srt_merged_fn = f'{video_id}_en_merged.srt'
en_srt_merged_path = os.path.join(output_path, en_srt_merged_fn)

if os.path.exists(en_srt_merged_path):
return send_from_directory(output_path, en_srt_merged_fn, as_attachment=True)

return jsonify({"message": log_warning_return_str(
f'Transcribed English SRT {en_srt_merged_fn} not found at {en_srt_merged_path}')}), 404


@app.route('/translated_zh_upload', methods=['POST'])
@pytvzhen_api_request_counter
def translated_zh_upload():
video_id = request.form['video_id']
output_path = app.config['OUTPUT_PATH']
Expand All @@ -408,15 +442,16 @@ def translated_zh_upload():
# if user does not select file, browser also
# submit an empty part without filename
if file and get_extension(file.filename):
filename = video_id+"_zh_merge.srt"
print("save:"+filename)
filename = video_id + "_zh_merge.srt"
print("save:" + filename)
file.save(os.path.join(output_path, filename))
return jsonify({"message": log_info_return_str(f"SRT {filename} uploaded")})
else:
return jsonify({"message", log_error_return_str(f"Video upload failed: {file.filename} extension not allowed")})


@app.route('/srt_zh_merged/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def srt_zh_merged_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -431,6 +466,7 @@ def srt_zh_merged_serve(video_id):


@app.route('/voice_connect', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def voice_connect(video_id):
output_path = app.config['OUTPUT_PATH']
Expand All @@ -457,6 +493,7 @@ def voice_connect(video_id):


@app.route('/voice_connect_log/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def voice_connect_log_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -471,6 +508,7 @@ def voice_connect_log_serve(video_id):


@app.route('/voice_connect/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def voice_connect_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -485,6 +523,7 @@ def voice_connect_serve(video_id):


@app.route('/tts', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def tts(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -519,6 +558,7 @@ def tts(video_id):


@app.route('/tts/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def tts_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand All @@ -544,6 +584,7 @@ def tts_serve(video_id):


@app.route('/video_preview', methods=['POST'])
@pytvzhen_api_request_counter
@require_video_id_from_post_request
def video_preview(video_id):
output_path = app.config['OUTPUT_PATH']
Expand Down Expand Up @@ -589,6 +630,7 @@ def video_preview(video_id):


@app.route('/video_preview/<video_id>', methods=['GET'])
@pytvzhen_api_request_counter
def video_preview_serve(video_id):
output_path = app.config['OUTPUT_PATH']

Expand Down
21 changes: 21 additions & 0 deletions test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@
import tempfile

from app import app
from app import url_rule_to_base


class PytvzhenUnitTest(unittest.TestCase):

def test_video_url_rule_to_base_succeeds(self):
assert url_rule_to_base("/videos/<video_id>") == "/videos"
assert url_rule_to_base("/audio/<video_id>") == "/audio"
assert url_rule_to_base("/audio_no_bg/<video_id>") == "/audio_no_bg"
assert url_rule_to_base("/audio_bg/<video_id>") == "/audio_bg"
assert url_rule_to_base("/srt_en/<video_id>") == "/srt_en"
assert url_rule_to_base("/srt_en_merged/<video_id>") == "/srt_en_merged"
assert url_rule_to_base("/srt_en/<video_id>") == "/srt_en"
assert url_rule_to_base("/srt_zh_merged/<video_id>") == "/srt_zh_merged"
assert url_rule_to_base("/voice_connect_log/<video_id>") == "/voice_connect_log"
assert url_rule_to_base("/voice_connect/<video_id>") == "/voice_connect"
assert url_rule_to_base("/tts/<video_id>") == "/tts"
assert url_rule_to_base("/video_preview/<video_id>") == "/video_preview"

def test_video_url_rule_to_base_succeeds_with_prefix(self):
assert url_rule_to_base("/api/video_preview/<video_id>") == "/api/video_preview"


class PytvzhenAPITest(unittest.TestCase):
Expand Down

0 comments on commit 7813e67

Please sign in to comment.