File size: 9,890 Bytes
382c6c5
 
 
 
 
 
 
 
 
 
 
 
 
d16fe1a
382c6c5
 
 
6e2b7cb
 
 
 
e95a4f5
6e2b7cb
e95a4f5
6e2b7cb
e95a4f5
6e2b7cb
e95a4f5
6e2b7cb
e95a4f5
6e2b7cb
 
 
 
 
 
 
 
 
 
 
2ec19da
6e2b7cb
 
 
0623c2e
382c6c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311796a
 
 
 
eec9f2b
fd37136
382c6c5
e95a4f5
382c6c5
 
d16fe1a
382c6c5
 
 
 
 
 
 
 
2ec19da
e95a4f5
382c6c5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fd37136
ed4f224
e95a4f5
fd37136
ed4f224
 
382c6c5
9d4b8b8
 
382c6c5
 
 
 
fd37136
382c6c5
ccc71c7
 
90692b1
708d3ee
 
ccc71c7
fd37136
 
382c6c5
 
 
 
 
 
 
 
 
8ba6571
6e2b7cb
be6c483
5f414ce
d817adb
8ba6571
382c6c5
6e2b7cb
f686977
382c6c5
 
be6c483
6e2b7cb
5f414ce
f1aec6f
6e2b7cb
 
f1aec6f
e95a4f5
f686977
2ec19da
6e2b7cb
9dbb160
95187ba
b3640f8
9dbb160
e462bb3
b3640f8
9dbb160
5892974
b3640f8
fd37136
07871d4
eb89fc8
3061c3f
fd37136
 
 
b3640f8
6e2b7cb
e95a4f5
6e2b7cb
6a08a56
6e2b7cb
95187ba
 
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
193
194
195
196
197
198
199
200
201
202
203
import gradio as gr
import pandas as pd
import requests
import json
import time
import base64
from io import StringIO
import getpass
import os

pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

DATABRICKS_INSTANCE = 'https://136286767906206.6.gcp.databricks.com'
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN_")
JOB_ID = os.getenv("JOB_ID_")

# Function that controls the visibility of the panels
def check_words(user_text, input_text):
    # If the entered text is "user" and "casa", show Panel 2 and hide Panel 1
    if user_text == os.getenv("USER_1_") and input_text == os.getenv("PASS_1_"):
        return gr.update(visible=True), gr.update(visible=False)#, user_text#, gr.update(value=""), gr.update(value="")
    elif user_text == os.getenv("USER_2_") and input_text == os.getenv("PASS_2_"):
        return gr.update(visible=True), gr.update(visible=False)#, user_text#, gr.update(value=""), gr.update(value="")
    elif user_text == os.getenv("USER_3_") and input_text == os.getenv("PASS_3_"):
        return gr.update(visible=True), gr.update(visible=False)#, user_text#, gr.update(value=""), gr.update(value="")
    elif user_text == os.getenv("USER_4_") and input_text == os.getenv("PASS_4_"):
        return gr.update(visible=True), gr.update(visible=False)#, user_text#, gr.update(value=""), gr.update(value="")
    else:
        return gr.update(visible=False), gr.update(visible=True)#, user_text#, user_text, input_text  # Keep Panel 2 hidden, show Panel 1

# Function to hide Panel 2
def hide_panel():
    return gr.update(visible=False)  # Hide Panel 2

# Function to show Panel 1
def show_panel_1():
    return gr.update(visible=True)  # Show Panel 1

# Wrapper function to hide Panel 2 and show Panel 1 when btn_2 is clicked
def hide_and_show_panel():
    return hide_panel(), show_panel_1(), gr.update(value=""), gr.update(value="")

#def update_message(request: gr.Request):
#    return f"Welcome, {request.username}"

def get_run_status(run_id):
    url = f"{DATABRICKS_INSTANCE}/api/2.1/jobs/runs/get?run_id={run_id}"
    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}"
    }
    response = requests.get(url, headers=headers)
    return response.json()

def get_databricks_file(file_path):
    # Construct the DBFS URL for the file
    dbfs_url = f"{DATABRICKS_INSTANCE}/api/2.0/dbfs/read"
    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "Content-Type": "application/json"
    }
    data = {
        "path": file_path
    }
    response = requests.get(dbfs_url, headers=headers, json=data)
    #response.raise_for_status()  # Raise an exception for HTTP errors
    content = response.json()
    file_data = base64.b64decode(content['data'])
    return file_data

def get_month_label(i):
    return f'M{i+1}'

#data_predictions_ = get_databricks_file("dbfs:/dbfs/FileStore/forecast_alleviatetax_predictions.csv")
#df = pd.read_csv(StringIO(data_predictions_.decode('utf-8')))
#df['revenue'] = (df['vintage_unique_cases'] / df['predicted_monthly_payment_rate']).round(2)
#df['Month'] = [get_month_label(i) for i in range(len(df))]
df = pd.DataFrame()
#df_2 = pd.DataFrame()
    
def update_table(start_date, end_date, window, user_text):
    #############################################################################################
    try:
        DATABRICKS_INSTANCE = 'https://136286767906206.6.gcp.databricks.com'
        ACCESS_TOKEN = os.getenv("ACCESS_TOKEN_")
        JOB_ID = os.getenv("JOB_ID_")
        
        # Parameters to pass to the job
        params = {
            "events_api_base_url": "https://beta.datascore.ai",
            "month_train_starting": str(start_date),
            "month_for_prediction": str(end_date),
            "moving_average_period": str(window),
            "username": str(user_text) 
        }
        
        url = f"{DATABRICKS_INSTANCE}/api/2.1/jobs/run-now"
        headers = {
            "Authorization": f"Bearer {ACCESS_TOKEN}",
            "Content-Type": "application/json"
        }
        data = {
            "job_id": JOB_ID,
            "notebook_params": params  # Pass parameters here
        }
        response = requests.post(url, headers=headers, data=json.dumps(data))
        #return response.json()
        # Run the Job
        #run_info = post_run_job(JOB_ID, params)
        run_info = response.json()
        run_id = run_info['run_id']
        #print(f"Run ID: {run_id}")
        
        while True:
            status = get_run_status(run_id)
            state = status['state']['life_cycle_state']
            if state in ['TERMINATED', 'SKIPPED', 'FAILED', 'ERROR']:
                print(f"Job finished with state: {state}")
                break
            elif state in ['PROGRES']:
                print(f"Job progress: {state}")
            time.sleep(30)
        
        print(f"Run ID: {run_id}")
        #data_payments = get_databricks_file("dbfs:/dbfs/FileStore/forecast_alleviatetax_payments_"+str(user_text).split('@')[0]+".csv")
        #data_metrics = get_databricks_file("dbfs:/dbfs/FileStore/forecast_alleviatetax_metrics.csv")
        data_predictions = get_databricks_file("dbfs:/dbfs/FileStore/forecast_alleviatetax_predictions_"+str(user_text).split('@')[0]+".csv")
        #df_payments = pd.read_csv(StringIO(data_payments.decode('utf-8')))
        #new_columns = ['vintage', 'vintage_unique_cases'] + [f'M{col}' for col in df_payments.columns[2:]] 
        #df_metrics = pd.read_csv(StringIO(data_metrics.decode('utf-8')))
        df_predictions = pd.read_csv(StringIO(data_predictions.decode('utf-8')))
        #df_predictions['revenue'] = (df_predictions['vintage_unique_cases'] / df_predictions['predicted_monthly_payment_rate']).round(2)
        #df_predictions['Month'] = [get_month_label(i) for i in range(len(df_predictions))]
    except Exception as e:
        return {error: str(e)}
    #############################################################################################
    global df  # Use global variable
    #global df_2
    df = df_predictions.copy()
    #max_row_index = df['Prediction Revenue'].idxmax()
    #df = df.style.apply(lambda x: ['background-color: #d9f7be; color: black' if x.name == max_row_index else '' for i in x], axis=1)
    for i in range(len(df) - 1):
        if df.at[i, 'Prediction Revenue'] > df.at[i + 1, 'Prediction Revenue']:
            df.at[i, 'Prediction Revenue'] = df.at[i + 1, 'Prediction Revenue']
    df = df.style.apply(lambda x: ['background-color: #d9f7be; color: black' if x['Prediction Days Range'] == 'Prediction' else '' for i in range(len(x))], axis=1)
    #df_2 = df_payments.copy() 
    return df#, df_2

def save_csv(file_name):
    global df  # Use global variable
    if file_name:
        df.to_csv(file_name, index=False)
        return f"File '{file_name}' saved!"
    else:
        return "Please set file name!"

with gr.Blocks(fill_height=True) as demo:
    # Create the first panel (visible from the start)
    with gr.Column(visible=True) as panel_1:
        gr.HTML(f"<h1>Forecast UI</h1>")
        user_text = gr.Textbox(label="Username:", placeholder="Type here...", scale=0)
        input_text = gr.Textbox(label="Password:", placeholder="Type here...", scale=0, type="password")
    
        # First button, visible from the start
        btn_1 = gr.Button("Login", scale=0)

    
    with gr.Column(visible=False) as panel_2:
        #m = gr.Markdown()
        gr.HTML(f"<h1>Forecast UI</h1>")
        with gr.Row():
        #    demo.load(update_message, None, gr.Markdown())
        #    logout_button = gr.Button("Logout", link="/logout", scale=0)
            # Add a second button inside Panel 2 to hide the panel and show Panel 1 again
            #tu = gr.Textbox(interactive=False, scale=0) 
            btn_2 = gr.Button("Logout", visible=True, scale=0)
            btn_2.click(hide_and_show_panel, outputs=[panel_2, panel_1, user_text, input_text])  # Hide Panel 2 and show Panel 1
        with gr.Row():
            with gr.Column():               
                start_input = gr.Textbox(label="Start Date:", value= '2023-09-01', placeholder="Enter date (e.g., 2023-09-01)", max_lines=1)
                gr.Markdown("Start of the data range of months that will be used as input by the model for revenue prediction.<br><br>The end month is automatically set to one month before the prediction month.")
            with gr.Column():  
                prediction_input = gr.Text(label="Month Prediction:", placeholder="Enter date (e.g., 2024-10-31)", max_lines=1)
                gr.Markdown("Case creation month to predict its revenue.")
            with gr.Column():  
                range_input = gr.Slider(3, 12, 6, step=1, label="Window / Moving Average Period")
                gr.Markdown("Window = 3-period/months, the predictive model reacts more quickly to recent monthly payment fluctuations, but it may also include more noise.<br><br>Window = 12-period/months, the Forecast adjusts more slowly and is less sensitive to small fluctuations, making it more reliable, but also slower to react to sharp changes.")
        btn_update = gr.Button("Run Forecast")
        gr.HTML(f"<h2>Predictions</h2>")
        gr.Markdown("Also it's recommended to re-run the predictions after the selected month has passed.")
        table_1 = gr.DataFrame(value=df, label="Predictions -> consult 'Prediction Revenue':")
        #table_2 = gr.DataFrame(value=df_2, label="Forecast Inputs:")
        btn_update.click(fn=update_table, inputs=[start_input, prediction_input, range_input, user_text], outputs=[table_1#,table_2
                                                                                                                  ]) 

    # Configure the buttons and the panel visibility
    btn_1.click(check_words, inputs=[user_text, input_text], outputs=[panel_2, panel_1])

demo.launch()