Spaces:
Runtime error
Runtime error
| library(plumber) | |
| library(dplyr) | |
| library(DBI) | |
| library(RPostgres) | |
| library(httr2) | |
| library(jsonlite) | |
| source("00_db_helper.R") | |
| # source("backend/00_db_helper.R") | |
| # Baca statistik training sekali saja saat API start | |
| # train_stats <- NULL | |
| if (file.exists("models/train_statistics.rds")) { | |
| train_stats <- readRDS("models/train_statistics.rds") | |
| # print(train_stats) | |
| } else { | |
| con <- connect_supabase() | |
| train_stats <- dbGetQuery(con, "SELECT * FROM mlops.train_statistics ORDER BY create_date DESC LIMIT 1") | |
| DBI::dbDisconnect(con) | |
| } | |
| #* @filter cors | |
| function(req, res) { | |
| res$setHeader("Access-Control-Allow-Origin", "*") | |
| res$setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS") | |
| res$setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization") | |
| if (req$REQUEST_METHOD == "OPTIONS") { | |
| res$status <- 200 | |
| return(list()) | |
| } | |
| plumber::forward() | |
| } | |
| #* Mengambil ringkasan performa model | |
| #* @param window:int Ukuran window data | |
| #* @get /performance | |
| function(window = 100) { | |
| con <- connect_supabase() | |
| db_res <- dbGetQuery(con, | |
| "SELECT predicted_value FROM mlops.predictions ORDER BY timestamp DESC LIMIT $1", | |
| list(as.integer(window)) | |
| ) | |
| total_db_res <- dbGetQuery(con, "SELECT count(predicted_value) as total FROM mlops.predictions") | |
| dbDisconnect(con) | |
| if(nrow(db_res) == 0) { | |
| return(list(total = 0, mean_pred = NA, sd_pred = NA)) | |
| } | |
| list( | |
| total = total_db_res$total, | |
| window = window, | |
| mean_pred = mean(db_res$predicted_value, na.rm = TRUE), | |
| sd_pred = sd(db_res$predicted_value, na.rm = TRUE), | |
| min_pred = min(db_res$predicted_value, na.rm = TRUE), | |
| max_pred = max(db_res$predicted_value, na.rm = TRUE) | |
| ) | |
| } | |
| #* Mengambil data logs dan drift yang sudah diproses | |
| #* @param window:int Ukuran window data | |
| #* @param drift_feature:str Fitur yang ingin dihitung Z-Score nya | |
| #* @get /logs-drift | |
| function(window = 100) { | |
| con <- connect_supabase() | |
| query_sql <- " | |
| WITH exploded_data AS ( | |
| SELECT | |
| request_id, | |
| timestamp, | |
| variant, version, row_id, | |
| predicted_value, | |
| (input_features->>'displ')::numeric AS displ, | |
| (input_features->>'year')::numeric AS year, | |
| (input_features->>'cyl')::numeric AS cyl, | |
| (input_features->>'class')::text as class, | |
| status, | |
| COALESCE(error_message::text, '') AS error_message | |
| FROM mlops.predictions | |
| WHERE status = 'SUCCESS' | |
| ORDER BY timestamp DESC | |
| LIMIT %d | |
| ) | |
| SELECT | |
| *, | |
| ABS(displ - %f) / %f AS z_displ, | |
| ABS(year - %f) / %f AS z_year, | |
| ABS(cyl - %f) / %f AS z_cyl | |
| FROM exploded_data; | |
| " | |
| # print(train_stats) | |
| query_filled <- sprintf( | |
| query_sql, | |
| as.integer(window), | |
| train_stats$displ_mean, train_stats$displ_sd, | |
| train_stats$year_mean, train_stats$year_sd, | |
| train_stats$cyl_mean, train_stats$cyl_sd | |
| ) | |
| # print(query_filled) | |
| final_data <- dbGetQuery(con, query_filled) | |
| # print("final_data:") | |
| # print(head(final_data)) | |
| # print(str(final_data)) | |
| # Jika query kosong, langsung kembalikan data frame kosong | |
| if(nrow(final_data) == 0) { | |
| dbDisconnect(con) | |
| return(list(data = data.frame())) | |
| } | |
| actuals_db <- tryCatch({ | |
| dbGetQuery(con, "SELECT request_id, row_id, actual_value FROM mlops.actuals;") | |
| }, error = function(e) { | |
| data.frame(request_id = character(), row_id = character(), actual_value = numeric()) | |
| }) | |
| dbDisconnect(con) | |
| # Gabung Actual | |
| # print(nrow(actuals_db) > 0) | |
| # print("row_id" %in% names(final_data)) | |
| if (nrow(actuals_db) > 0 && "row_id" %in% names(final_data)) { | |
| actuals_db$request_id <- as.character(actuals_db$request_id) | |
| actuals_db$row_id <- as.character(actuals_db$row_id) | |
| final_data <- final_data %>% | |
| left_join(actuals_db, by = c("request_id", "row_id")) | |
| # print(final_data) | |
| } else { | |
| final_data$actual_value <- NA_real_ | |
| } | |
| # print("final_data:") | |
| # print(nrow(final_data)) | |
| # print(str(final_data)) | |
| return(final_data) | |
| } |