"""A gradio app for credit card approval prediction using FHE."""
import subprocess
import time
import gradio as gr
from settings import (
REPO_DIR,
ACCOUNT_MIN_MAX,
CHILDREN_MIN_MAX,
INCOME_MIN_MAX,
AGE_MIN_MAX,
EMPLOYED_MIN_MAX,
FAMILY_MIN_MAX,
INCOME_TYPES,
OCCUPATION_TYPES,
HOUSING_TYPES,
EDUCATION_TYPES,
FAMILY_STATUS,
)
from backend import (
pre_process_keygen_encrypt_send_user,
pre_process_keygen_encrypt_send_bank,
pre_process_keygen_encrypt_send_third_party,
run_fhe,
get_output,
decrypt_output,
)
subprocess.Popen(["uvicorn", "server:app"], cwd=REPO_DIR)
time.sleep(3)
demo = gr.Blocks()
print("Starting the demo...")
with demo:
gr.Markdown(
"""
Credit Card Approval Prediction Using Fully Homomorphic Encryption
"""
)
gr.Markdown("## Client side")
gr.Markdown("### Step 1: Infos. ")
with gr.Row():
with gr.Column():
gr.Markdown("### User")
gender = gr.Radio(["Female", "Male"], label="Gender")
bool_inputs = gr.CheckboxGroup(["Car", "Property", "Work phone", "Phone", "Email"], label="What do you own ?")
num_children = gr.Slider(**CHILDREN_MIN_MAX, step=1, label="Number of children", info="How many children do you have (0 to 19) ?")
num_family = gr.Slider(**FAMILY_MIN_MAX, step=1, label="Family", info="How many members does your family have? (1 to 20) ?")
total_income = gr.Slider(**INCOME_MIN_MAX, label="Income", info="What's you total yearly income (in euros, 3780 to 220500) ?")
age = gr.Slider(**AGE_MIN_MAX, step=1, label="Age", info="How old are you (20 to 68) ?")
income_type = gr.Dropdown(choices=INCOME_TYPES, label="Income type", info="What is your main type of income ?")
education_type = gr.Dropdown(choices=EDUCATION_TYPES, label="Education", info="What is your education background ?")
family_status = gr.Dropdown(choices=FAMILY_STATUS, label="Family", info="What is your family status ?")
occupation_type = gr.Dropdown(choices=OCCUPATION_TYPES, label="Occupation", info="What is your main occupation ?")
housing_type = gr.Dropdown(choices=HOUSING_TYPES, label="Housing", info="In what type of housing do you live ?")
with gr.Column():
gr.Markdown("### Bank ")
account_length = gr.Slider(**ACCOUNT_MIN_MAX, step=1, label="Account length", info="How long have this person had this account (in months, 0 to 60) ?")
with gr.Column():
gr.Markdown("### Third party ")
employed = gr.Radio(["Yes", "No"], label="Is the person employed ?")
years_employed = gr.Slider(**EMPLOYED_MIN_MAX, step=1, label="Years of employment", info="How long have this person been employed (in years, 0 to 43) ?")
gr.Markdown("### Step 2: Keygen, encrypt using FHE and send the inputs to the server.")
with gr.Row():
with gr.Column():
gr.Markdown("### User")
encrypt_button_user = gr.Button("Encrypt the inputs and send to server.")
user_id = gr.Textbox(label="", max_lines=2, interactive=False, visible=False)
encrypted_input_user = gr.Textbox(
label="Encrypted input representation:", max_lines=2, interactive=False
)
# keys_user = gr.Textbox(
# label="Keys representation:", max_lines=2, interactive=False
# )
with gr.Column():
gr.Markdown("### Bank ")
encrypt_button_bank = gr.Button("Encrypt the inputs and send to server.")
bank_id = gr.Textbox(label="", max_lines=2, interactive=False, visible=False)
encrypted_input_bank = gr.Textbox(
label="Encrypted input representation:", max_lines=2, interactive=False
)
# keys_bank = gr.Textbox(
# label="Keys representation:", max_lines=2, interactive=False
# )
with gr.Column():
gr.Markdown("### Third Party ")
encrypt_button_third_party = gr.Button("Encrypt the inputs and send to server.")
third_party_id = gr.Textbox(label="", max_lines=2, interactive=False, visible=False)
encrypted_input_third_party = gr.Textbox(
label="Encrypted input representation:", max_lines=2, interactive=False
)
# keys_3 = gr.Textbox(
# label="Keys representation:", max_lines=2, interactive=False
# )
gr.Markdown("## Server side")
gr.Markdown(
"The encrypted values are received by the server. The server can then compute the prediction "
"directly over them. Once the computation is finished, the server returns "
"the encrypted result to the client."
)
gr.Markdown("### Step 6: Run FHE execution.")
execute_fhe_button = gr.Button("Run FHE execution.")
fhe_execution_time = gr.Textbox(
label="Total FHE execution time (in seconds):", max_lines=1, interactive=False
)
gr.Markdown("## Client side")
gr.Markdown(
"The encrypted output is sent back to the client, who can finally decrypt it with the "
"private key."
)
gr.Markdown("### Step 7: Receive the encrypted output from the server.")
gr.Markdown(
"The output displayed here is the encrypted result sent by the server, which has been "
"decrypted using a different private key. This is only used to visually represent an "
"encrypted output."
)
get_output_button = gr.Button("Receive the encrypted output from the server.")
# encrypted_output_representation = gr.Textbox(
# label="Encrypted output representation: ", max_lines=1, interactive=False
# )
gr.Markdown("### Step 8: Decrypt the output.")
decrypt_button = gr.Button("Decrypt the output")
prediction_output = gr.Textbox(
label="Credit card approval decision: ", max_lines=1, interactive=False
)
# Button to pre-process, generate the key, encrypt and send the user inputs from the client
# side to the server
encrypt_button_user.click(
pre_process_keygen_encrypt_send_user,
inputs=[gender, bool_inputs, num_children, num_family, total_income, age, income_type, \
education_type, family_status, occupation_type, housing_type],
outputs=[user_id, encrypted_input_user],
)
# Button to pre-process, generate the key, encrypt and send the bank inputs from the client
# side to the server
encrypt_button_bank.click(
pre_process_keygen_encrypt_send_bank,
inputs=[account_length],
outputs=[bank_id, encrypted_input_bank],
)
# Button to pre-process, generate the key, encrypt and send the third party inputs from the
# client side to the server
encrypt_button_third_party.click(
pre_process_keygen_encrypt_send_third_party,
inputs=[employed, years_employed],
outputs=[third_party_id, encrypted_input_third_party],
)
# TODO : ID should be unique
# Button to send the encodings to the server using post method
execute_fhe_button.click(run_fhe, inputs=[user_id, bank_id, third_party_id], outputs=[fhe_execution_time])
# TODO : ID should be unique
# Button to send the encodings to the server using post method
get_output_button.click(
get_output,
inputs=[user_id, bank_id, third_party_id],
# outputs=[encrypted_output_representation]
)
# TODO : ID should be unique
# Button to decrypt the output as the user
decrypt_button.click(
decrypt_output,
inputs=[user_id, bank_id, third_party_id],
outputs=[prediction_output],
)
gr.Markdown(
"The app was built with [Concrete-ML](https://github.com/zama-ai/concrete-ml), a "
"Privacy-Preserving Machine Learning (PPML) open-source set of tools by [Zama](https://zama.ai/). "
"Try it yourself and don't forget to star on Github ⭐."
)
demo.launch(share=False)