File size: 5,954 Bytes
28a5857
f2f5171
8311f5b
cdd5b2f
 
 
28a5857
8311f5b
28a5857
8311f5b
cdd5b2f
8311f5b
28a5857
 
 
957c035
 
 
 
 
 
f2f5171
8311f5b
f2f5171
28a5857
 
 
cdd5b2f
 
 
28a5857
f2f5171
 
cdd5b2f
f2f5171
28a5857
8311f5b
28a5857
 
 
8311f5b
 
 
 
 
28a5857
 
8311f5b
28a5857
8311f5b
 
 
28a5857
 
 
 
 
8311f5b
 
 
 
 
 
28a5857
957c035
cdd5b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2f5171
cdd5b2f
 
 
957c035
8311f5b
d95cbea
 
 
 
cdd5b2f
 
 
957c035
8311f5b
f2f5171
d95cbea
 
8311f5b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d95cbea
 
 
957c035
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d95cbea
 
957c035
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d95cbea
957c035
d95cbea
 
 
 
 
 
 
 
 
 
 
 
8311f5b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import os
import gradio as gr
import random
import secrets
from typing import Annotated
from fastapi import FastAPI, Request, status, Depends
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from fastapi.exceptions import HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from loguru import logger
from dotenv import load_dotenv

from app import Summarizer, TextRequest, Result
from app import (
    EN_SENTIMENT_MODEL,
    EN_SUMMARY_MODEL,
    RU_SENTIMENT_MODEL,
    RU_SUMMARY_MODEL,
)
from app import DEFAULT_EN_TEXT, DEFAULT_RU_TEXT
from models.forms import VerificationForm

load_dotenv()

SITE_KEY = os.getenv("SITE_KEY")
API_USER = os.getenv("API_USER")
API_PWD = os.getenv("API_PWD")
users = set()

app = FastAPI()
pipe = Summarizer()
security = HTTPBasic()

# mount FastAPI StaticFiles server
app.mount("/static", StaticFiles(directory="static"), name="static")
templates = Jinja2Templates(directory="templates")


@app.get("/")
async def index(request: Request):
    return RedirectResponse("/index/", status_code=302)


@app.get("/verify_page", response_class=HTMLResponse)
async def verify_page(request: Request):
    captcha_id = random.randint(1, 5)
    return templates.TemplateResponse(
        request=request,
        name="verification.html",
        context={"site_key": SITE_KEY, "captcha_id": captcha_id},
    )


@app.post("/verify")
async def verify(request: Request):
    form = VerificationForm(request)
    await form.load_data()
    if await form.is_valid():
        logger.info("Form is valid")
        return RedirectResponse("/index/", status_code=302)
    return await verify_page(request)


def get_current_username(
    credentials: Annotated[HTTPBasicCredentials, Depends(security)]
):
    current_username_bytes = credentials.username.encode("utf8")
    correct_username_bytes = bytes(API_USER, "utf-8")
    is_correct_username = secrets.compare_digest(
        current_username_bytes, correct_username_bytes
    )
    current_password_bytes = credentials.password.encode("utf8")
    correct_password_bytes = bytes(API_PWD, "utf-8")
    is_correct_password = secrets.compare_digest(
        current_password_bytes, correct_password_bytes
    )
    if not (is_correct_username and is_correct_password):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Basic"},
        )
    return credentials.username


@app.post("/summ_ru", response_model=Result)
async def ru_summ_api(
    request: TextRequest, username: Annotated[str, Depends(get_current_username)]
):
    results = pipe.summarize(request.text, lang="ru")
    logger.info(results)
    return results


@app.post("/summ_en", response_model=Result)
async def en_summ_api(
    request: TextRequest, username: Annotated[str, Depends(get_current_username)]
):
    results = pipe.summarize(request.text, lang="en")
    logger.info(results)
    return results


@app.exception_handler(403)
async def unavailable_error(request: Request, exc: HTTPException):
    logger.warning("Error 403")
    return templates.TemplateResponse(
        "errors/error.html",
        {"request": request, "message": "403. Sorry, this page unavailable."},
        status_code=403,
    )


@app.exception_handler(404)
async def not_found_error(request: Request, exc: HTTPException):
    logger.warning("Error 404")
    return templates.TemplateResponse(
        "errors/error.html",
        {"request": request, "message": "404. Page Not Found."},
        status_code=404,
    )


@app.exception_handler(500)
async def internal_error(request: Request, exc: HTTPException):
    logger.warning("Error 500")
    return templates.TemplateResponse(
        "errors/error.html",
        {"request": request, "message": "500. Oops. Something has gone wrong."},
        status_code=500,
    )


with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=2, min_width=600):
            en_sum_description = gr.Markdown(
                value=f"Model for Summary: {EN_SUMMARY_MODEL}"
            )
            en_sent_description = gr.Markdown(
                value=f"Model for Sentiment: {EN_SENTIMENT_MODEL}"
            )
            en_inputs = gr.Textbox(
                label="en_input",
                lines=5,
                value=DEFAULT_EN_TEXT,
                placeholder=DEFAULT_EN_TEXT,
            )
            en_lang = gr.Textbox(value="en", visible=False)
            en_outputs = gr.Textbox(
                label="en_output",
                lines=5,
                placeholder="Summary and Sentiment would be here...",
            )
            en_inbtn = gr.Button("Proceed")
        with gr.Column(scale=2, min_width=600):
            ru_sum_description = gr.Markdown(
                value=f"Model for Summary: {RU_SUMMARY_MODEL}"
            )
            ru_sent_description = gr.Markdown(
                value=f"Model for Sentiment: {RU_SENTIMENT_MODEL}"
            )
            ru_inputs = gr.Textbox(
                label="ru_input",
                lines=5,
                value=DEFAULT_RU_TEXT,
                placeholder=DEFAULT_RU_TEXT,
            )
            ru_lang = gr.Textbox(value="ru", visible=False)
            ru_outputs = gr.Textbox(
                label="ru_output",
                lines=5,
                placeholder="Здесь будет обобщение и эмоциональный окрас текста...",
            )
            ru_inbtn = gr.Button("Запустить")

    en_inbtn.click(
        pipe.summ,
        [en_inputs, en_lang],
        [en_outputs],
    )
    ru_inbtn.click(
        pipe.summ,
        [ru_inputs, ru_lang],
        [ru_outputs],
    )

# mounting at the root path
app = gr.mount_gradio_app(app, demo, path="/index")