From the uDemy course on LLM engineering.
https://www.udemy.com/course/llm-engineering-master-ai-and-large-language-models
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
11 KiB
332 lines
11 KiB
import gradio as gr |
|
|
|
# Define custom CSS with dark theme fixes, updated to use html.dark |
|
custom_css = """ |
|
/* Root variables for light theme */ |
|
:root { |
|
--background: #ffffff; |
|
--secondary-background: #f7f7f7; |
|
--tertiary-background: #f0f0f0; |
|
--text: #000000; |
|
--secondary-text: #5d5d5d; |
|
--border: #e0e0e0; |
|
--accent: #ff7b2c; |
|
--accent-hover: #ff6a14; |
|
--button-text: #ffffff; |
|
--code-bg: #f7f7f7; |
|
--code-text: #000000; |
|
--dropdown-bg: #ffffff; |
|
--slider-track: #e0e0e0; |
|
--slider-thumb: #ff7b2c; |
|
--collapsible-header: #f0f0f0; |
|
--primary-button-bg: #4a6ee0; /* Blue */ |
|
--primary-button-hover: #3a5ec8; |
|
--secondary-button-bg: #444444; |
|
--secondary-button-hover: #555555; |
|
--danger-button-bg: #e74c3c; /* Red */ |
|
--danger-button-hover: #c0392b; |
|
--success-button-bg: #e67e22; /* Orange */ |
|
--success-button-hover: #d35400; |
|
} |
|
|
|
/* Dark theme variables using html.dark */ |
|
html.dark { |
|
--background: #1a1a1a; |
|
--secondary-background: #252525; |
|
--tertiary-background: #2a2a2a; |
|
--text: #ffffff; |
|
--secondary-text: #cccccc; |
|
--border: #444444; |
|
--accent: #ff7b2c; |
|
--accent-hover: #ff6a14; |
|
--button-text: #ffffff; |
|
--code-bg: #252525; |
|
--code-text: #ffffff; |
|
--dropdown-bg: #2a2a2a; |
|
--slider-track: #444444; |
|
--slider-thumb: #ff7b2c; |
|
--collapsible-header: #333333; |
|
--primary-button-bg: #4a6ee0; |
|
--primary-button-hover: #3a5ec8; |
|
--secondary-button-bg: #444444; |
|
--secondary-button-hover: #555555; |
|
--danger-button-bg: #e74c3c; |
|
--danger-button-hover: #c0392b; |
|
--success-button-bg: #e67e22; |
|
--success-button-hover: #d35400; |
|
} |
|
|
|
/* Base styles */ |
|
body { |
|
background-color: var(--background) !important; |
|
color: var(--text) !important; |
|
transition: all 0.3s ease; |
|
} |
|
|
|
.gradio-container { |
|
background-color: var(--background) !important; |
|
max-width: 100% !important; |
|
} |
|
|
|
/* Headers */ |
|
h1, h2, h3, h4, h5, h6, .gr-header { |
|
color: var(--text) !important; |
|
} |
|
|
|
/* Panels and blocks */ |
|
.gr-panel, .gr-form, .gr-box, .gr-block { |
|
background-color: var(--secondary-background) !important; |
|
color: var(--text) !important; |
|
border-color: var(--border) !important; |
|
border-radius: 6px !important; |
|
} |
|
|
|
/* Validation messages section */ |
|
.gr-accordion .gr-panel { |
|
background-color: var(--secondary-background) !important; |
|
color: var(--text) !important; |
|
border-color: #e74c3c !important; /* Red border */ |
|
} |
|
|
|
.gr-accordion-header { |
|
background-color: var(--collapsible-header) !important; |
|
color: var(--text) !important; |
|
} |
|
|
|
/* Code editors */ |
|
.codebox, .code-editor, .cm-editor { |
|
background-color: var(--code-bg) !important; |
|
color: var(--code-text) !important; |
|
border: 1px solid var(--border) !important; |
|
border-radius: 4px !important; |
|
} |
|
|
|
/* Syntax highlighting */ |
|
.cm-editor .cm-content, .cm-editor .cm-line { |
|
color: var(--code-text) !important; |
|
} |
|
.cm-editor .cm-keyword { color: #ff79c6 !important; } /* Pink */ |
|
.cm-editor .cm-number { color: #bd93f9 !important; } /* Purple */ |
|
.cm-editor .cm-string { color: #f1fa8c !important; } /* Yellow */ |
|
.cm-editor .cm-comment { color: #6272a4 !important; } /* Gray */ |
|
|
|
/* Buttons */ |
|
.gr-button { |
|
background-color: var(--tertiary-background) !important; |
|
color: var(--text) !important; |
|
border-color: var(--border) !important; |
|
border-radius: 4px !important; |
|
} |
|
.gr-button.success { |
|
background-color: var(--success-button-bg) !important; |
|
color: var(--button-text) !important; |
|
} |
|
.gr-button.success:hover { |
|
background-color: var(--success-button-hover) !important; |
|
} |
|
.gr-button.danger { |
|
background-color: var(--danger-button-bg) !important; |
|
color: var(--button-text) !important; |
|
} |
|
.gr-button.danger:hover { |
|
background-color: var(--danger-button-hover) !important; |
|
} |
|
.gr-button.secondary { |
|
background-color: var(--secondary-button-bg) !important; |
|
color: var(--button-text) !important; |
|
} |
|
.gr-button.secondary:hover { |
|
background-color: var(--secondary-button-hover) !important; |
|
} |
|
|
|
/* File upload */ |
|
.gr-file, .gr-file-upload { |
|
background-color: var(--secondary-background) !important; |
|
color: var(--text) !important; |
|
border-color: var(--border) !important; |
|
} |
|
|
|
/* Dropdowns */ |
|
.gr-dropdown, .gr-dropdown-container, .gr-dropdown select, .gr-dropdown option { |
|
background-color: var(--dropdown-bg) !important; |
|
color: var(--text) !important; |
|
border-color: var(--border) !important; |
|
} |
|
|
|
/* Slider */ |
|
.gr-slider { |
|
background-color: var(--background) !important; |
|
} |
|
.gr-slider-track { |
|
background-color: var(--slider-track) !important; |
|
} |
|
.gr-slider-handle { |
|
background-color: var(--slider-thumb) !important; |
|
} |
|
.gr-slider-value { |
|
color: var(--text) !important; |
|
} |
|
|
|
/* Code output */ |
|
.gr-code { |
|
background-color: var(--code-bg) !important; |
|
color: var(--code-text) !important; |
|
border-color: var(--border) !important; |
|
} |
|
|
|
/* Footer */ |
|
.footer { |
|
color: var(--secondary-text) !important; |
|
} |
|
.footer a { |
|
color: var(--accent) !important; |
|
} |
|
""" |
|
|
|
# JavaScript for theme toggling and initialization |
|
js_code = """ |
|
<script> |
|
function toggleTheme(theme) { |
|
var url = new URL(window.location.href); |
|
if (theme === "dark") { |
|
url.searchParams.set('__theme', 'dark'); |
|
} else { |
|
url.searchParams.delete('__theme'); |
|
} |
|
window.location.href = url.href; |
|
} |
|
|
|
// Set the radio button based on current theme |
|
document.addEventListener('DOMContentLoaded', function() { |
|
var urlParams = new URLSearchParams(window.location.search); |
|
var currentTheme = urlParams.get('__theme'); |
|
if (currentTheme === 'dark') { |
|
document.querySelector('#theme_radio_container input[value="dark"]').checked = true; |
|
} else { |
|
document.querySelector('#theme_radio_container input[value="light"]').checked = true; |
|
} |
|
}); |
|
</script> |
|
""" |
|
|
|
# Language and model options |
|
INPUT_LANGUAGES = ["Python", "JavaScript", "Java", "TypeScript", "Swift", "C#", "Ruby", "Go", "Rust", "PHP"] |
|
OUTPUT_LANGUAGES = ["Python", "JavaScript", "Java", "TypeScript", "Swift", "C#", "Ruby", "Go", "Rust", "PHP", "Julia"] |
|
MODELS = ["GPT", "Claude", "CodeLlama", "Llama", "Gemini"] |
|
DOC_STYLES = ["standard", "detailed", "minimal"] |
|
|
|
# Build the interface |
|
with gr.Blocks(css=custom_css, theme=gr.themes.Base()) as demo: |
|
# Inject the JavaScript code |
|
gr.HTML(js_code) |
|
|
|
# States for dynamic button text |
|
input_lang_state = gr.State("Python") |
|
output_lang_state = gr.State("JavaScript") |
|
|
|
# Header |
|
with gr.Row(elem_classes="header-container"): |
|
gr.HTML("<h1 class='header-title'>AI CodeXchange</h1>") |
|
# Theme selection radio and apply button |
|
theme_radio = gr.Radio(["light", "dark"], label="Theme", elem_id="theme_radio_container", value="dark") |
|
theme_button = gr.Button("Apply Theme") |
|
|
|
# Validation Messages |
|
with gr.Accordion("Validation Messages", open=True): |
|
with gr.Row(): |
|
with gr.Column(): |
|
input_code = gr.Code(language="python", label="Code In", lines=15, elem_classes="code-container") |
|
with gr.Column(): |
|
output_code = gr.Code(language="javascript", label="Converted Code", lines=15, elem_classes="code-container") |
|
|
|
# Configuration Options |
|
with gr.Row(): |
|
input_lang = gr.Dropdown(INPUT_LANGUAGES, label="Code In", value="Python") |
|
output_lang = gr.Dropdown(OUTPUT_LANGUAGES, label="Code Out", value="JavaScript") |
|
model = gr.Dropdown(MODELS, label="Model", value="GPT") |
|
temperature = gr.Slider(minimum=0, maximum=1, step=0.1, value=0.7, label="Temperature") |
|
|
|
# Document Options |
|
with gr.Row(): |
|
document_check = gr.Checkbox(label="Document", value=True) |
|
doc_style = gr.Dropdown(DOC_STYLES, label="Document Style", value="standard") |
|
|
|
# File Upload |
|
with gr.Accordion("Upload", open=True): |
|
file_upload = gr.File(label="Drop File Here - or - Click to Upload") |
|
|
|
# Action Buttons |
|
with gr.Row(elem_classes="button-row"): |
|
convert_btn = gr.Button("Convert", elem_classes="success") |
|
clear_btn = gr.Button("Clear All", elem_classes="danger") |
|
|
|
# Run Buttons |
|
with gr.Row(elem_classes="button-row"): |
|
run_source = gr.Button("Run Source Code", elem_classes="secondary") |
|
run_target = gr.Button("Run Target Code", elem_classes="secondary") |
|
|
|
# Results |
|
with gr.Row(): |
|
source_result = gr.Code(label="Source Code Result", language="python", lines=10, elem_classes="code-container") |
|
target_result = gr.Code(label="Converted Code Result", language="javascript", lines=10, elem_classes="code-container") |
|
|
|
# Download |
|
with gr.Accordion("Download", open=True): |
|
with gr.Row(): |
|
dl_source = gr.Button("Download Source Code") |
|
dl_target = gr.Button("Download Converted Code") |
|
|
|
# Footer |
|
with gr.Row(elem_classes="footer"): |
|
gr.HTML("<div>Use via API</div><div>•</div><div>Built with Gradio</div><div>•</div><div>Settings</div>") |
|
|
|
# Theme toggle event |
|
theme_button.click( |
|
fn=None, |
|
inputs=None, |
|
outputs=[], |
|
js=""" |
|
var theme = document.querySelector('#theme_radio_container input:checked').value; |
|
toggleTheme(theme); |
|
""" |
|
) |
|
|
|
# Existing event handlers |
|
def convert_code(input_code, in_lang, out_lang, model, temp, doc, doc_style): |
|
return f"// Converted from {in_lang} to {out_lang} using {model}\n// Temperature: {temp}\n// Documentation: {doc} ({doc_style if doc else 'N/A'})" |
|
|
|
convert_btn.click(fn=convert_code, inputs=[input_code, input_lang_state, output_lang_state, model, temperature, document_check, doc_style], outputs=[output_code]) |
|
|
|
def update_convert_btn_text(in_lang, out_lang): |
|
return f"Convert {in_lang} to {out_lang}", in_lang, out_lang |
|
|
|
input_lang.change(fn=update_convert_btn_text, inputs=[input_lang, output_lang], outputs=[convert_btn, input_lang_state, output_lang_state]) |
|
output_lang.change(fn=update_convert_btn_text, inputs=[input_lang, output_lang], outputs=[convert_btn, input_lang_state, output_lang_state]) |
|
|
|
def update_run_btn_text(in_lang, out_lang): |
|
return f"Run {in_lang}", f"Run {out_lang}" |
|
|
|
input_lang.change(fn=update_run_btn_text, inputs=[input_lang, output_lang], outputs=[run_source, run_target]) |
|
output_lang.change(fn=update_run_btn_text, inputs=[input_lang, output_lang], outputs=[run_source, run_target]) |
|
|
|
def clear_all(): |
|
return "", "", "", "" |
|
|
|
clear_btn.click(fn=clear_all, inputs=[], outputs=[input_code, output_code, source_result, target_result]) |
|
|
|
def run_code(code, lang): |
|
return f"// Running {lang} code...\n// Results would appear here" |
|
|
|
run_source.click(fn=run_code, inputs=[input_code, input_lang_state], outputs=[source_result]) |
|
run_target.click(fn=run_code, inputs=[output_code, output_lang_state], outputs=[target_result]) |
|
|
|
def handle_file_upload(file): |
|
if file is None: |
|
return "" |
|
with open(file.name, "r") as f: |
|
return f.read() |
|
|
|
file_upload.change(fn=handle_file_upload, inputs=[file_upload], outputs=[input_code]) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |