1+ import os
2+ from typing import Optional
3+
4+ from dotenv import dotenv_values
5+ from src .sheets import Sheet
6+
7+ PREFIX = "flextensions_"
8+
9+ DEFAULT_COURSE_NAME = "PLEASE SET A COURSE NAME"
10+ DEFAULT_REPLY_TO_EMAIL = "PLEASE SET REPLY-TO EMAIL"
11+
12+ DEFAULT_AUTO_APPROVE_THRESHOLD = 1
13+ DEFAULT_AUTO_APPROVE_THRESHOLD_DSP = 1
14+ DEFAULT_APPROVE_ASSIGNMENT_THRESHOLD = 1
15+ DEFAULT_MAX_TOTAL_REQUESTED_EXTENSIONS_THRESHOLD = 3
16+
17+ DEFAULT_EMAIL_FROM = "[{}] <{}@berkeley.edu>" .format (DEFAULT_COURSE_NAME , DEFAULT_COURSE_NAME )
18+ DEFAULT_EMAIL_SUBJECT = "[CS 000] Extension Request Update"
19+ DEFAULT_EMAIL_SIGNATURE = "{} Staff" .format (DEFAULT_COURSE_NAME )
20+
21+ DEFAULT_EXTEND_GRADESCOPE_ASSIGNMENTS = "No"
22+
23+ class Environment :
24+ @staticmethod
25+ def clear ():
26+ keys = os .environ .keys ()
27+ for key in keys :
28+ if key .startswith (PREFIX ):
29+ del os .environ [key ]
30+
31+ @staticmethod
32+ def contains (key : str ) -> bool :
33+ return os .getenv (PREFIX + key ) is not None and str (os .getenv (PREFIX + key )).strip () != ""
34+
35+ @staticmethod
36+ def _safe_get (key : str , default : str = None ) -> Optional [str ]:
37+ if os .getenv (PREFIX + key ):
38+ data = str (os .getenv (PREFIX + key )).strip ()
39+ if data :
40+ return data
41+ return default
42+
43+ # @staticmethod
44+ # def get(key: str) -> Any:
45+ # if not os.getenv(PREFIX + key):
46+ # raise ConfigurationError("Environment variable not set: " + key)
47+ # return os.getenv(PREFIX + key)
48+
49+ @staticmethod
50+ def get_auto_approve_threshold () -> int :
51+ return int (Environment ._safe_get ("AUTO_APPROVE_THRESHOLD" , DEFAULT_AUTO_APPROVE_THRESHOLD ))
52+
53+ @staticmethod
54+ def get_auto_approve_threshold_dsp () -> int :
55+ return int (Environment ._safe_get ("AUTO_APPROVE_THRESHOLD_DSP" , DEFAULT_AUTO_APPROVE_THRESHOLD_DSP ))
56+
57+ @staticmethod
58+ def get_max_total_requested_extensions_threshold () -> int :
59+ return int (Environment ._safe_get ("MAX_TOTAL_REQUESTED_EXTENSIONS_THRESHOLD" , DEFAULT_MAX_TOTAL_REQUESTED_EXTENSIONS_THRESHOLD ))
60+
61+ @staticmethod
62+ def get_auto_approve_assignment_threshold () -> int :
63+ return int (Environment ._safe_get ("AUTO_APPROVE_ASSIGNMENT_THRESHOLD" , DEFAULT_APPROVE_ASSIGNMENT_THRESHOLD ))
64+
65+ @staticmethod
66+ def get_course_name () -> str :
67+ return Environment ._safe_get ("COURSE_NAME" , DEFAULT_COURSE_NAME )
68+
69+ @staticmethod
70+ def get_reply_to_email () -> str :
71+ return Environment ._safe_get ("REPLY_TO_EMAIL" , DEFAULT_REPLY_TO_EMAIL )
72+
73+ @staticmethod
74+ def get_email_from () -> str :
75+ return Environment ._safe_get ("EMAIL_FROM" , DEFAULT_EMAIL_FROM )
76+
77+ @staticmethod
78+ def get_email_subject () -> str :
79+ return Environment ._safe_get ("EMAIL_SUBJECT" , DEFAULT_EMAIL_SUBJECT )
80+
81+ @staticmethod
82+ def get_email_signature () -> str :
83+ return Environment ._safe_get ("EMAIL_SIGNATURE" , DEFAULT_EMAIL_SIGNATURE )
84+
85+ @staticmethod
86+ def get_email_cc () -> Optional [str ]:
87+ return Environment ._safe_get ("EMAIL_CC" )
88+
89+ @staticmethod
90+ def get_slack_endpoint () -> Optional [str ]:
91+ return Environment ._safe_get ("SLACK_ENDPOINT" )
92+
93+ @staticmethod
94+ def get_slack_debug_endpoint () -> Optional [str ]:
95+ return Environment ._safe_get ("SLACK_DEBUG_ENDPOINT" )
96+
97+ @staticmethod
98+ def get_slack_tag_list () -> Optional [str ]:
99+ return Environment ._safe_get ("SLACK_TAG_LIST" )
100+
101+ @staticmethod
102+ def get_extend_gradescope_assignments () -> bool :
103+ return Environment ._safe_get ("EXTEND_GRADESCOPE_ASSIGNMENTS" , DEFAULT_EXTEND_GRADESCOPE_ASSIGNMENTS )
104+
105+ @staticmethod
106+ def get_gradescope_email () -> Optional [str ]:
107+ return Environment ._safe_get ("GRADESCOPE_EMAIL" )
108+
109+ @staticmethod
110+ def get_gradescope_password () -> Optional [str ]:
111+ return Environment ._safe_get ("GRADESCOPE_PASSWORD" )
112+
113+ @staticmethod
114+ def get_spreadsheet_url () -> Optional [str ]:
115+ return Environment ._safe_get ("SPREADSHEET_URL" )
116+
117+ @staticmethod
118+ def configure_env_vars (sheet : Sheet ):
119+ """
120+ Reads environment variables from the "Environment Variables" sheet, and stores them into this process's
121+ environment variables for downstream use. Expects two columns: a "key" column, and a "value"
122+ """
123+ records = sheet .get_all_records ()
124+ for record in records :
125+ key = record .get ("key" )
126+ value = record .get ("value" )
127+ if not key :
128+ continue
129+ os .environ [PREFIX + key ] = str (value )
130+
131+ # Load local environment variables now from .env, which override remote provided variables for debugging
132+ if os .path .exists (".env-pytest" ):
133+ for key , value in dotenv_values (".env-pytest" ).items ():
134+ if key == "APP_MASTER_SECRET" :
135+ os .environ [key ] = value
136+ else :
137+ os .environ [PREFIX + key ] = value
0 commit comments