4040 raise SystemExit ("Faltou OPENAI_API_KEY no ambiente." )
4141openai_client = OpenAI (api_key = OPENAI_API_KEY )
4242
43+ # Password protection
44+ APP_PASSWORD = os .getenv ("APP_PASSWORD" , "secret42" )
45+
4346lang_cache : Optional [LangCache ] = None
4447if LANGCACHE_API_KEY and LANGCACHE_CACHE_ID and LangCache is not None :
4548 lang_cache = LangCache (
@@ -627,7 +630,7 @@ def calc_savings(tokens_est: int, price_in: float, price_out: float, frac_in: fl
627630 <div class="meta">
628631 <div class="meta-item">
629632 <span class="label">SemVer:</span>
630- <span class="value">v2.2.5 -harness</span>
633+ <span class="value">v2.2.6 -harness</span>
631634 </div>
632635 <div class="meta-item">
633636 <span class="label">PR GitHub:</span>
@@ -948,9 +951,79 @@ def copy_a_to_b(company, bu, person, prompt):
948951 outputs = [flush_both_status , flush_both_debug ],
949952 )
950953
954+ # ============== PASSWORD PROTECTION ==============
955+ def check_password (password ):
956+ """Check if the provided password matches the environment variable."""
957+ if password == APP_PASSWORD :
958+ return {
959+ login_box : gr .update (visible = False ),
960+ main_app : gr .update (visible = True )
961+ }
962+ else :
963+ return {
964+ login_box : gr .update (visible = True ),
965+ main_app : gr .update (visible = False )
966+ }
967+
968+ # Wrap the demo with password protection
969+ with gr .Blocks (title = "Redis LangCache — Demo PT-BR" , css = CUSTOM_CSS ) as app :
970+ with gr .Column (visible = True , elem_id = "login-container" ) as login_box :
971+ gr .HTML ("""
972+ <div style="max-width: 400px; margin: 100px auto; padding: 40px; background: white; border-radius: 16px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);">
973+ <div style="text-align: center; margin-bottom: 30px;">
974+ <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Redis_logo.svg/2560px-Redis_logo.svg.png"
975+ alt="Redis" style="height: 40px; margin-bottom: 16px;">
976+ <h2 style="font-family: 'Space Grotesk', sans-serif; color: #0b1220; margin: 0;">Redis LangCache Demo</h2>
977+ <p style="color: #64748b; margin-top: 8px;">Digite a senha para acessar</p>
978+ </div>
979+ </div>
980+ """ )
981+ with gr .Row ():
982+ gr .HTML ("<div style='flex: 1;'></div>" )
983+ with gr .Column (scale = 1 , min_width = 300 ):
984+ password_input = gr .Textbox (
985+ label = "🔒 Senha" ,
986+ type = "password" ,
987+ placeholder = "Digite a senha..." ,
988+ elem_id = "password-input"
989+ )
990+ login_btn = gr .Button ("Entrar" , variant = "primary" , size = "lg" )
991+ login_status = gr .HTML ("" )
992+ gr .HTML ("<div style='flex: 1;'></div>" )
993+
994+ with gr .Column (visible = False ) as main_app :
995+ demo .render ()
996+
997+ # Handle login
998+ def handle_login (password ):
999+ if password == APP_PASSWORD :
1000+ return {
1001+ login_box : gr .update (visible = False ),
1002+ main_app : gr .update (visible = True ),
1003+ login_status : ""
1004+ }
1005+ else :
1006+ return {
1007+ login_box : gr .update (visible = True ),
1008+ main_app : gr .update (visible = False ),
1009+ login_status : "<p style='color: #ef4444; text-align: center; margin-top: 10px;'>❌ Senha incorreta</p>"
1010+ }
1011+
1012+ login_btn .click (
1013+ fn = handle_login ,
1014+ inputs = [password_input ],
1015+ outputs = [login_box , main_app , login_status ]
1016+ )
1017+
1018+ password_input .submit (
1019+ fn = handle_login ,
1020+ inputs = [password_input ],
1021+ outputs = [login_box , main_app , login_status ]
1022+ )
1023+
9511024if __name__ == "__main__" :
9521025 if lang_cache :
9531026 with lang_cache :
954- demo .launch ()
1027+ app .launch ()
9551028 else :
956- demo .launch ()
1029+ app .launch ()
0 commit comments