Rakshitjan commited on
Commit
70ddb7b
·
verified ·
1 Parent(s): 7f0b1f3

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +148 -147
main.py CHANGED
@@ -1,147 +1,148 @@
1
- from fastapi import FastAPI, HTTPException
2
- import gspread
3
- from google.oauth2.service_account import Credentials
4
- from google.auth.exceptions import GoogleAuthError
5
- import pandas as pd
6
- from collections import defaultdict
7
- from pydantic import BaseModel
8
- from fastapi.middleware.cors import CORSMiddleware
9
- import os
10
-
11
- app = FastAPI()
12
- app.add_middleware(
13
- CORSMiddleware,
14
- allow_origins=["*"], # You can specify domains instead of "*" to restrict access
15
- allow_credentials=True,
16
- allow_methods=["*"], # Allows all HTTP methods (POST, GET, OPTIONS, etc.)
17
- allow_headers=["*"], # Allows all headers
18
- )
19
- # Define Google Sheets API credentials function
20
- def get_credentials():
21
- try:
22
- service_account_info = {
23
- "type": os.getenv("SERVICE_ACCOUNT_TYPE"),
24
- "project_id": os.getenv("PROJECT_ID"),
25
- "private_key_id": os.getenv("PRIVATE_KEY_ID"),
26
- "private_key": os.getenv("PRIVATE_KEY").replace('\\n', '\n'),
27
- "client_email": os.getenv("CLIENT_EMAIL"),
28
- "client_id": os.getenv("CLIENT_ID"),
29
- "auth_uri": os.getenv("AUTH_URI"),
30
- "token_uri": os.getenv("TOKEN_URI"),
31
- "auth_provider_x509_cert_url": os.getenv("AUTH_PROVIDER_X509_CERT_URL"),
32
- "client_x509_cert_url": os.getenv("CLIENT_X509_CERT_URL"),
33
- "universe_domain": os.getenv("UNIVERSE_DOMAIN")
34
- }
35
- scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
36
- creds = Credentials.from_service_account_info(service_account_info, scopes=scope)
37
- return creds
38
- except Exception as e:
39
- print(f"Error getting credentials: {e}")
40
- return None
41
-
42
- # Initialize Google Sheets Client
43
- creds = get_credentials()
44
- if creds:
45
- client = gspread.authorize(creds)
46
-
47
- # Define input model
48
- class CoachingCodeInput(BaseModel):
49
- coachingCode: str
50
-
51
- # Define the endpoint
52
- @app.post("/process/")
53
- def process_data(input_data: CoachingCodeInput):
54
- coachingCode = input_data.coachingCode
55
-
56
- # Define Google Sheet URLs based on coachingCode
57
- journal_file_path = ''
58
- panic_button_file_path = ''
59
- test_file_path = ''
60
-
61
- if coachingCode == '1919':
62
- journal_file_path = 'https://docs.google.com/spreadsheets/d/1EFf2lr4A10nt4RhIqxCD_fxe-l3sXH09II0TEkMmvhA/edit?usp=drive_link'
63
- panic_button_file_path = 'https://docs.google.com/spreadsheets/d/1nFZGkCvRV6qS-mhsORhX3dxI0JSge32_UwWgWKl3eyw/edit?usp=drive_link'
64
- test_file_path = 'https://docs.google.com/spreadsheets/d/13PUHySUXWtKBusjugoe7Dbsm39PwBUfG4tGLipspIx4/edit?usp=drive_link'
65
- else:
66
- raise HTTPException(status_code=404, detail="Invalid coaching code")
67
-
68
- try:
69
- # Open the Google Sheets
70
- journal_file = client.open_by_url(journal_file_path).worksheet('Sheet1')
71
- panic_button_file = client.open_by_url(panic_button_file_path).worksheet('Sheet1')
72
- test_file = client.open_by_url(test_file_path).worksheet('Sheet1')
73
-
74
- # Step 1: Read the Google Sheets into DataFrames
75
- journal_df = pd.DataFrame(journal_file.get_all_values())
76
- panic_button_df = pd.DataFrame(panic_button_file.get_all_values())
77
- test_df = pd.DataFrame(test_file.get_all_values())
78
-
79
- # Label the columns manually
80
- journal_df.columns = ['user_id', 'productivity_yes_no', 'productivity_rate']
81
- panic_button_df.columns = ['user_id', 'panic_button']
82
-
83
- # Step 2: Merge Journal and Panic Button data
84
- panic_button_grouped = panic_button_df.groupby('user_id')['panic_button'].apply(lambda x: ','.join(x)).reset_index()
85
- merged_journal_panic = pd.merge(journal_df, panic_button_grouped, on='user_id', how='outer')
86
-
87
- # Step 3: Process Test data
88
- test_data = []
89
- for index, row in test_df.iterrows():
90
- user_id = row[0]
91
- i = 1
92
- while i < len(row) and pd.notna(row[i]):
93
- chapter = row[i].lower().strip()
94
- score = row[i + 1]
95
- if pd.notna(score):
96
- test_data.append({'user_id': user_id, 'test_chapter': chapter, 'test_score': score})
97
- i += 2
98
-
99
- test_df_processed = pd.DataFrame(test_data)
100
-
101
- # Step 4: Merge all data
102
- merged_data = pd.merge(merged_journal_panic, test_df_processed, on='user_id', how='outer')
103
- merged_data_cleaned = merged_data.dropna(subset=['productivity_yes_no', 'productivity_rate', 'panic_button', 'test_chapter'], how='all')
104
-
105
- # Step 5: Process Data
106
- df = pd.DataFrame(merged_data_cleaned)
107
- academic_weights = {'BACKLOGS': -5, 'MISSED CLASSES': -4, 'NOT UNDERSTANDING': -3, 'BAD MARKS': -3, 'LACK OF MOTIVATION': -3}
108
- non_academic_weights = {'EMOTIONAL FACTORS': -3, 'PROCRASTINATE': -2, 'LOST INTEREST': -4, 'LACK OF FOCUS': -2, 'GOALS NOT ACHIEVED': -2, 'LACK OF DISCIPLINE': -2}
109
- max_weighted_panic_score = sum([max(academic_weights.values()) * 3, max(non_academic_weights.values()) * 3])
110
-
111
- def calculate_potential_score(row):
112
- test_score_normalized = 0
113
- if row['test_scores']:
114
- avg_test_score = sum(row['test_scores'].values()) / len(row['test_scores'])
115
- test_score_normalized = (avg_test_score / 40) * 70
116
-
117
- student_panic_score = 0
118
- if row['panic_button']:
119
- for factor, count in row['panic_button'].items():
120
- if factor in academic_weights:
121
- student_panic_score += academic_weights[factor] * count
122
- elif factor in non_academic_weights:
123
- student_panic_score += non_academic_weights[factor] * count
124
-
125
- panic_score = 20 * (1 - (student_panic_score / max_weighted_panic_score)) if max_weighted_panic_score != 0 else 1
126
- journal_score = (float(row['productivity_rate']) / 10) * 10 if pd.notna(row['productivity_rate']) else 0
127
-
128
- total_potential_score = test_score_normalized + panic_score + journal_score
129
- return total_potential_score
130
-
131
- merged_df = df.groupby('user_id').apply(lambda group: pd.Series({
132
- 'potential_score': calculate_potential_score(group)
133
- })).reset_index()
134
-
135
- merged_df['potential_score'] = merged_df['potential_score'].round(2)
136
- sorted_df = merged_df[['user_id', 'potential_score']].sort_values(by='potential_score', ascending=False)
137
-
138
- # Return the result as JSON
139
- return sorted_df.to_dict(orient='records')
140
-
141
- except GoogleAuthError as e:
142
- raise HTTPException(status_code=500, detail=f"Authentication failed: {str(e)}")
143
- except Exception as e:
144
- raise HTTPException(status_code=500, detail=f"Error processing data: {str(e)}")
145
-
146
- # To run the app:
147
- # uvicorn filename:app --reload
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ import gspread
3
+ from google.oauth2.service_account import Credentials
4
+ from google.auth.exceptions import GoogleAuthError
5
+ import pandas as pd
6
+ from collections import defaultdict
7
+ from pydantic import BaseModel
8
+ from fastapi.middleware.cors import CORSMiddleware
9
+ import os
10
+
11
+ app = FastAPI()
12
+ app.add_middleware(
13
+ CORSMiddleware,
14
+ allow_origins=["*"], # You can specify domains instead of "*" to restrict access
15
+ allow_credentials=True,
16
+ allow_methods=["*"], # Allows all HTTP methods (POST, GET, OPTIONS, etc.)
17
+ allow_headers=["*"], # Allows all headers
18
+ )
19
+ # Define Google Sheets API credentials function
20
+ def get_credentials():
21
+ try:
22
+ service_account_info = {
23
+ "type": os.getenv("SERVICE_ACCOUNT_TYPE"),
24
+ "project_id": os.getenv("PROJECT_ID"),
25
+ "private_key_id": os.getenv("PRIVATE_KEY_ID"),
26
+ "private_key": os.getenv("PRIVATE_KEY").replace('\\n', '\n'),
27
+ "client_email": os.getenv("CLIENT_EMAIL"),
28
+ "client_id": os.getenv("CLIENT_ID"),
29
+ "auth_uri": os.getenv("AUTH_URI"),
30
+ "token_uri": os.getenv("TOKEN_URI"),
31
+ "auth_provider_x509_cert_url": os.getenv("AUTH_PROVIDER_X509_CERT_URL"),
32
+ "client_x509_cert_url": os.getenv("CLIENT_X509_CERT_URL"),
33
+ "universe_domain": os.getenv("UNIVERSE_DOMAIN")
34
+ }
35
+ scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
36
+ creds = Credentials.from_service_account_info(service_account_info, scopes=scope)
37
+ return creds
38
+ except Exception as e:
39
+ print(f"Error getting credentials: {e}")
40
+ return None
41
+
42
+ # Initialize Google Sheets Client
43
+ creds = get_credentials()
44
+ if creds:
45
+ client = gspread.authorize(creds)
46
+ print("Client run done")
47
+
48
+ # Define input model
49
+ class CoachingCodeInput(BaseModel):
50
+ coachingCode: str
51
+
52
+ # Define the endpoint
53
+ @app.post("/process/")
54
+ def process_data(input_data: CoachingCodeInput):
55
+ coachingCode = input_data.coachingCode
56
+
57
+ # Define Google Sheet URLs based on coachingCode
58
+ journal_file_path = ''
59
+ panic_button_file_path = ''
60
+ test_file_path = ''
61
+
62
+ if coachingCode == '1919':
63
+ journal_file_path = 'https://docs.google.com/spreadsheets/d/1EFf2lr4A10nt4RhIqxCD_fxe-l3sXH09II0TEkMmvhA/edit?usp=drive_link'
64
+ panic_button_file_path = 'https://docs.google.com/spreadsheets/d/1nFZGkCvRV6qS-mhsORhX3dxI0JSge32_UwWgWKl3eyw/edit?usp=drive_link'
65
+ test_file_path = 'https://docs.google.com/spreadsheets/d/13PUHySUXWtKBusjugoe7Dbsm39PwBUfG4tGLipspIx4/edit?usp=drive_link'
66
+ else:
67
+ raise HTTPException(status_code=404, detail="Invalid coaching code")
68
+
69
+ try:
70
+ # Open the Google Sheets
71
+ journal_file = client.open_by_url(journal_file_path).worksheet('Sheet1')
72
+ panic_button_file = client.open_by_url(panic_button_file_path).worksheet('Sheet1')
73
+ test_file = client.open_by_url(test_file_path).worksheet('Sheet1')
74
+
75
+ # Step 1: Read the Google Sheets into DataFrames
76
+ journal_df = pd.DataFrame(journal_file.get_all_values())
77
+ panic_button_df = pd.DataFrame(panic_button_file.get_all_values())
78
+ test_df = pd.DataFrame(test_file.get_all_values())
79
+
80
+ # Label the columns manually
81
+ journal_df.columns = ['user_id', 'productivity_yes_no', 'productivity_rate']
82
+ panic_button_df.columns = ['user_id', 'panic_button']
83
+
84
+ # Step 2: Merge Journal and Panic Button data
85
+ panic_button_grouped = panic_button_df.groupby('user_id')['panic_button'].apply(lambda x: ','.join(x)).reset_index()
86
+ merged_journal_panic = pd.merge(journal_df, panic_button_grouped, on='user_id', how='outer')
87
+
88
+ # Step 3: Process Test data
89
+ test_data = []
90
+ for index, row in test_df.iterrows():
91
+ user_id = row[0]
92
+ i = 1
93
+ while i < len(row) and pd.notna(row[i]):
94
+ chapter = row[i].lower().strip()
95
+ score = row[i + 1]
96
+ if pd.notna(score):
97
+ test_data.append({'user_id': user_id, 'test_chapter': chapter, 'test_score': score})
98
+ i += 2
99
+
100
+ test_df_processed = pd.DataFrame(test_data)
101
+
102
+ # Step 4: Merge all data
103
+ merged_data = pd.merge(merged_journal_panic, test_df_processed, on='user_id', how='outer')
104
+ merged_data_cleaned = merged_data.dropna(subset=['productivity_yes_no', 'productivity_rate', 'panic_button', 'test_chapter'], how='all')
105
+
106
+ # Step 5: Process Data
107
+ df = pd.DataFrame(merged_data_cleaned)
108
+ academic_weights = {'BACKLOGS': -5, 'MISSED CLASSES': -4, 'NOT UNDERSTANDING': -3, 'BAD MARKS': -3, 'LACK OF MOTIVATION': -3}
109
+ non_academic_weights = {'EMOTIONAL FACTORS': -3, 'PROCRASTINATE': -2, 'LOST INTEREST': -4, 'LACK OF FOCUS': -2, 'GOALS NOT ACHIEVED': -2, 'LACK OF DISCIPLINE': -2}
110
+ max_weighted_panic_score = sum([max(academic_weights.values()) * 3, max(non_academic_weights.values()) * 3])
111
+
112
+ def calculate_potential_score(row):
113
+ test_score_normalized = 0
114
+ if row['test_scores']:
115
+ avg_test_score = sum(row['test_scores'].values()) / len(row['test_scores'])
116
+ test_score_normalized = (avg_test_score / 40) * 70
117
+
118
+ student_panic_score = 0
119
+ if row['panic_button']:
120
+ for factor, count in row['panic_button'].items():
121
+ if factor in academic_weights:
122
+ student_panic_score += academic_weights[factor] * count
123
+ elif factor in non_academic_weights:
124
+ student_panic_score += non_academic_weights[factor] * count
125
+
126
+ panic_score = 20 * (1 - (student_panic_score / max_weighted_panic_score)) if max_weighted_panic_score != 0 else 1
127
+ journal_score = (float(row['productivity_rate']) / 10) * 10 if pd.notna(row['productivity_rate']) else 0
128
+
129
+ total_potential_score = test_score_normalized + panic_score + journal_score
130
+ return total_potential_score
131
+
132
+ merged_df = df.groupby('user_id').apply(lambda group: pd.Series({
133
+ 'potential_score': calculate_potential_score(group)
134
+ })).reset_index()
135
+
136
+ merged_df['potential_score'] = merged_df['potential_score'].round(2)
137
+ sorted_df = merged_df[['user_id', 'potential_score']].sort_values(by='potential_score', ascending=False)
138
+
139
+ # Return the result as JSON
140
+ return sorted_df.to_dict(orient='records')
141
+
142
+ except GoogleAuthError as e:
143
+ raise HTTPException(status_code=500, detail=f"Authentication failed: {str(e)}")
144
+ except Exception as e:
145
+ raise HTTPException(status_code=500, detail=f"Error processing data: {str(e)}")
146
+
147
+ # To run the app:
148
+ # uvicorn filename:app --reload