Created
April 24, 2024 19:02
-
-
Save mtanco/ac68fdebe7b552961e3992a2f3b47dd7 to your computer and use it in GitHub Desktop.
Example for chatbots, waiting dialogs, and custom CSS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[data-test="header"] { | |
background: #000000 !important; | |
} | |
/* will be used by default for buttons*/ | |
.ms-Button--default { | |
background-color: #6c757d; | |
color: #FFFFFF; | |
border-color: #6c757d; | |
border-radius: 2rem; | |
} | |
.ms-Button--default:hover { | |
background-color: #5c636a; | |
color: #ffffff; | |
} | |
/* Specific Buttons: developers can include a key word like "primary" or "success" in the name to get the | |
appropriate style for specific buttons*/ | |
[data-test*="primary"].ms-Button { | |
background-color: #0057b8; | |
color: #FFFFFF; | |
border-color: #0057b8; | |
} | |
[data-test*="primary"].ms-Button:hover { | |
background-color: #004a9c; | |
color: #ffffff; | |
border-color: #0057b8; | |
} | |
[data-test*="secondary"].ms-Button { | |
background-color: #6c757d; | |
color: #FFFFFF; | |
border-color: #6c757d; | |
} | |
[data-test*="secondary"].ms-Button:hover { | |
background-color: #5c636a; | |
color: #ffffff; | |
border-color: #6c757d; | |
} | |
[data-test*="success"].ms-Button { | |
background-color: #198754; | |
color: #FFFFFF; | |
border-color: #198754; | |
} | |
[data-test*="success"].ms-Button:hover { | |
background-color: #157347; | |
color: #ffffff; | |
border-color: #198754; | |
} | |
[data-test*="danger"].ms-Button { | |
background-color: #dc3545; | |
color: #FFFFFF; | |
border-color: #dc3545; | |
} | |
[data-test*="danger"].ms-Button:hover { | |
background-color: #bb2d3b; | |
color: #ffffff; | |
border-color: #dc3545; | |
} | |
[data-test*="warning"].ms-Button { | |
background-color: #ffc107; | |
color: #000000; | |
border-color: #ffc107; | |
} | |
[data-test*="warning"].ms-Button:hover { | |
background-color: #ffca2c; | |
color: #000000; | |
border-color: #ffc107; | |
} | |
[data-test*="info"].ms-Button { | |
background-color: #0dcaf0; | |
color: #000000; | |
border-color: #0dcaf0; | |
} | |
[data-test*="info"].ms-Button:hover { | |
background-color: #31d2f2; | |
color: #000000; | |
border-color: #0dcaf0; | |
} | |
[data-test*="dark"].ms-Button { | |
background-color: #1a2027; | |
color: #FFFFFF; | |
border-color: ##1a2027; | |
} | |
[data-test*="dark"].ms-Button:hover { | |
background-color: #3c4147; | |
color: #ffffff; | |
border-color: ##1a2027; | |
} | |
[data-test*="light"].ms-Button { | |
background-color: #f8f9fa; | |
color: #000000; | |
border-color: #f8f9fa; | |
} | |
[data-test*="light"].ms-Button:hover { | |
background-color: #d3d4d5; | |
color: #000000; | |
border-color: #f8f9fa; | |
} | |
[data-test*="outline_primary"].ms-Button { | |
background-color: #FFFFFF; | |
color: #0057b8; | |
border-color: #0057b8; | |
} | |
[data-test*="outline_primary"].ms-Button:hover { | |
background-color: #0057b8; | |
color: #ffffff; | |
border-color: #0057b8; | |
} | |
[data-test*="outline_secondary"].ms-Button { | |
background-color: #FFFFFF; | |
color: #6c757d; | |
border-color: #6c757d; | |
} | |
[data-test*="outline_secondary"].ms-Button:hover { | |
background-color: #6c757d; | |
color: #ffffff; | |
border-color: #6c757d; | |
} | |
[data-test*="outline_success"].ms-Button { | |
background-color: #FFFFFF; | |
color: #198754; | |
border-color: #198754; | |
} | |
[data-test*="outline_success"].ms-Button:hover { | |
background-color: #198754; | |
color: #ffffff; | |
border-color: #198754; | |
} | |
[data-test*="outline_danger"].ms-Button { | |
background-color: #FFFFFF; | |
color: #dc3545; | |
border-color: #dc3545; | |
} | |
[data-test*="outline_danger"].ms-Button:hover { | |
background-color: #dc3545; | |
color: #ffffff; | |
border-color: #dc3545; | |
} | |
[data-test*="outline_warning"].ms-Button { | |
background-color: #FFFFFF; | |
color: #ffc107; | |
border-color: #ffc107; | |
} | |
[data-test*="outline_warning"].ms-Button:hover { | |
background-color: #ffc107; | |
color: #000000; | |
border-color: #ffc107; | |
} | |
[data-test*="outline_info"].ms-Button { | |
background-color: #FFFFFF; | |
color: #0dcaf0; | |
border-color: #0dcaf0; | |
} | |
[data-test*="outline_info"].ms-Button:hover { | |
background-color: #0dcaf0; | |
color: #000000; | |
border-color: #0dcaf0; | |
} | |
[data-test*="outline_dark"].ms-Button { | |
background-color: #FFFFFF; | |
color: #1a2027; | |
border-color: #1a2027; | |
} | |
[data-test*="outline_dark"].ms-Button:hover { | |
background-color: #1a2027; | |
color: #ffffff; | |
border-color: #1a2027; | |
} | |
[data-test*="outline_light"].ms-Button { | |
background-color: #FFFFFF; | |
color: #f8f9fa; | |
border-color: #f8f9fa; | |
} | |
[data-test*="outline_light"].ms-Button:hover { | |
background-color: #f8f9fa; | |
color: #000000; | |
border-color: #f8f9fa; | |
} | |
/* Message Bars: developers can include a key word like "primary" or "success" in the name to get the | |
appropriate style for specific message bars*/ | |
.ms-MessageBar-icon { | |
display: none; | |
} | |
.ms-MessageBar { | |
background-color: #ccddf1; | |
color: #00234a; | |
border-color: #99bce3; | |
} | |
.ms-MessageBar:has([data-test*="primary"]) { | |
background-color: #ccddf1; | |
color: #00234a; | |
border-color: #99bce3; | |
} | |
.ms-MessageBar:has([data-test*="secondary"]) { | |
background-color: #e2e3e5; | |
color: #2b2f32; | |
border-color: #c4c8cb; | |
} | |
.ms-MessageBar:has([data-test*="success"]) { | |
background-color: #d1e7dd; | |
color: #0a3622; | |
border-color: #a3cfbb; | |
} | |
.ms-MessageBar:has([data-test*="danger"]) { | |
background-color: #f8d7da; | |
color: #58151c; | |
border-color: #f1aeb5; | |
} | |
.ms-MessageBar:has([data-test*="warning"]) { | |
background-color: #fff3cd; | |
color: #664d03; | |
border-color: #ffe69c; | |
} | |
.ms-MessageBar:has([data-test*="info"]) { | |
background-color: #cff4fc; | |
color: #055160; | |
border-color: #0dcaf0; | |
} | |
.ms-MessageBar:has([data-test*="dark"]) { | |
background-color: #ced4da; | |
color: #495057; | |
border-color: ##1a2027; | |
} | |
.ms-MessageBar:has([data-test*="light"]) { | |
background-color: #fcfcfd; | |
color: #495057; | |
border-color: #f8f9fa; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
from h2o_wave import main, app, Q, ui, data, run_on, on | |
from h2ogpte import H2OGPTE | |
import h2o_authn | |
from loguru import logger | |
@app("/") | |
async def serve(q: Q): | |
"""Route the end user based on how they interacted with the app.""" | |
logger.info(f"Entered serve: {q.args}") | |
if not q.client.initialized: # Set up the application for a new browser tab, if not done yet | |
initialize_client(q) | |
await run_on(q) # Route user to the appropriate "on" function | |
await q.page.save() # Update the UI | |
def initialize_client(q: Q): | |
"""Code that is needed for each new browser that visits the app""" | |
logger.info("") | |
with open("att.css") as f: | |
style = f.read() | |
q.page["meta"] = ui.meta_card( | |
box="", | |
title="Chatbot | H2O.ai", | |
theme="att", | |
themes=[ | |
ui.theme(name='att', primary='#0057b8', text='#000000', card='#FFFFFF', page='#E2E2E2'), | |
], | |
stylesheet=ui.inline_stylesheet(style), | |
layouts=[ui.layout(breakpoint="xs", width="900px", zones=[ | |
ui.zone(name="header"), | |
ui.zone(name="main", size="1"), | |
ui.zone(name="footer") | |
])], | |
) | |
q.page["header"] = ui.header_card( | |
box="header", | |
title="Chatbot Template", | |
subtitle="A template app from H2O", | |
image="https://www.pngall.com/wp-content/uploads/13/ATT-Logo-PNG.png", | |
) | |
q.page["chatbot_card"] = ui.chatbot_card( | |
box="main", | |
name="chatbot", | |
data=data( | |
fields="content from_user", | |
t="list", | |
rows=[ | |
["Welcome, please ask your question", False], | |
], | |
), | |
) | |
q.page["footer_card"] = ui.footer_card( | |
box="footer", | |
caption="Made with [Wave](https://wave.h2o.ai), [h2oGPTe](https://h2o.ai/platform/enterprise-h2ogpte), and " | |
"💛 by the Makers at H2O.ai.<br />Find more in the [H2O GenAI App Store](https://genai.h2o.ai/).", | |
) | |
q.client.initialized = True | |
@on() | |
async def chatbot(q: Q): | |
"""Send a user's message to a Large Language Model and stream the response.""" | |
logger.info("") | |
# Add the User's Message to the Chatbot Screen | |
q.page["chatbot_card"].data += [q.args.chatbot, True] | |
# Show the user a blocking dialog so they have to wait for the LLM Call | |
q.page["meta"].dialog = ui.dialog(title='', items=[ | |
ui.progress(label='Talking to an LLM, please wait'), | |
], blocking=True) | |
await q.page.save() | |
# Call the get_llm_response function which returns a message | |
# Use the await q.run to make it so that this blocking LLM call does not block OTHER USERS | |
response = await q.run(get_llm_response, q.args.chatbot, q.auth.refresh_token) | |
# Add the response to the UI | |
q.page["chatbot_card"].data += [response, False] | |
# Close the blocking dialog | |
q.page["meta"].dialog = None | |
def get_llm_response(user_message, refresh_token): | |
"""Interact with h2oGPTe and stream the response""" | |
logger.info(user_message) | |
client = connect_to_h2ogpte(refresh_token) | |
chat_session_id = client.create_chat_session() | |
with client.connect(chat_session_id) as session: | |
response = session.query( | |
message=user_message, | |
timeout=60, | |
rag_config={"rag_type": "llm_only"}, | |
) | |
return response.content | |
def connect_to_h2ogpte(refresh_token): | |
logger.info("") | |
if refresh_token is None: | |
client = H2OGPTE(address=os.getenv("H2OGPTE_URL"), api_key=os.getenv("H2OGPTE_API_TOKEN")) | |
else: | |
token_provider = h2o_authn.TokenProvider( | |
refresh_token=refresh_token, | |
token_endpoint_url=f"{os.getenv('H2O_WAVE_OIDC_PROVIDER_URL')}/protocol/openid-connect/token", | |
client_id=os.getenv("H2O_WAVE_OIDC_CLIENT_ID"), | |
client_secret=os.getenv("H2O_WAVE_OIDC_CLIENT_SECRET"), | |
) | |
client = H2OGPTE(address=os.getenv("H2OGPTE_URL"), token_provider=token_provider) | |
return client |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment