Rakshitjan commited on
Commit
8f72369
·
verified ·
1 Parent(s): da67ca4

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +15 -0
  2. main.py +147 -0
  3. requirements.txt +0 -0
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ WORKDIR /code
7
+
8
+ COPY ./requirements.txt /code/requirements.txt
9
+
10
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
11
+
12
+ COPY . .
13
+
14
+ CMD uvicorn main:app --port=8000 --host=0.0.0.0
15
+
main.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
requirements.txt ADDED
Binary file (98 Bytes). View file