async def get_all_student_info( username=Depends(auth_handler.auth_wrapper), num: int = 30): """ Get all student info Require: Admin-read """ logger.debug(f"User({username}) trying fetching all students info.") permission_ok: bool = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) student_info_list = [] count = 0 try: for student_info in students_collection.find(): count += 1 clean_dict(student_info) student_info_list.append(student_info) if count >= num: break except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return student_info_list
def generate_video_list(video_folder: str): """ get metadata of all videos inside a video_folder, and write to `video_metadata_lst.json` and save it to the video_folder existing `video_metadata_lst.json` inside the target folder will be overwritten """ video_folder = Path(video_folder) if not video_folder.is_dir(): raise ValueError(f"'{dir}' is not a valid path to a folder.") video_list: list = [] for file in os.listdir(video_folder): logger.debug(file) video_filepath = os.path.join(video_folder, file) if os.path.isfile(video_filepath): try: video_metadata: dict = get_video_metadata(video_filepath) video_list.append(video_metadata) except Exception as err: logger.error(f"Error for {video_filepath}: {err}") continue # sort video list by video name alphabetically video_list = sorted(video_list, key=lambda x: x["filename"]) print(f"\nTotal number of videos: {len(video_list)}\n") export_filepath = video_folder / "video_metadata_lst.json" with export_filepath.open(mode="w") as f: f.write(json.dumps(video_list, indent=4))
def test_1(self): """Test Creation of a new ApplicationPeriod by using API endpoint POST method""" if self.ignore: return request_url = self.url_server_root + "/api/application_periods/" _data = { "uid": self.test_use_uid, "application_window_open": datetime.now().isoformat(), "application_window_close": (datetime.now() + timedelta(days=1)).isoformat(), "applicable_periods": [{ "start_date": date.today().isoformat(), "end_date": (date.today() + timedelta(days=30)).isoformat(), }], "applicable_rooms": ["59-409", "59-410", "59-411", "59-412"], "applicable_students": ["1000000", "1003432", "1004515", "1004234"], } # Not supposed to be used here but note here first # Ref: https://stackoverflow.com/a/11875813 # data = json.dumps(_data, default=json_util.default, indent=4) data = json.dumps(_data, indent=4) logger.debug(f"data: {data}") response = requests.post( url=request_url, headers=self.headers, # json=data, data=data, ) self.assertEqual(response.status_code, 201)
async def get_list_of_events(event_uids: List[str], username=Depends(auth_handler.auth_wrapper)): """ Get a list of Events for a given list of Event UIDs. If one or more provided uid(s) do not exist, it will be ignored. Require: Any authenticated user """ logger.debug(f"User({username}) fetching a list of events info") event_info_list: List[dict] = [] event_uids = list(set(event_uids)) try: for uid in event_uids: if isinstance(uid, str): event_dict: dict = events_collection.find_one({"uid": uid}) if event_dict: clean_dict(event_dict) event_info_list.append(event_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return event_info_list
def student_update_application_form_status( AF_uid: str, username: str, new_status: str, pre_status: List[str] ) -> dict: # Check access 1 permission_ok = False if Access.is_student(username) or Access.is_admin_write(username): permission_ok = True if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) # Check access 2: check if the application belongs to student if Access.is_student(username): try: student_info = students_collection.find_one({"student_id": username}) clean_dict(student_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) student_application_uids = student_info.get("application_uids", []) if AF_uid not in student_application_uids: raise HTTPException(status_code=400, detail=MSG.NOT_YOUR_AF) _updated = update_application_form_both_status(AF_uid, new_status, pre_status) return _updated
async def get_an_application_info( uid: str, username=Depends(auth_handler.auth_wrapper) ): """ Get an ApplicationForm info Require: Student-self or Admin-read """ # Special case, check permission after getting item from DB logger.debug(f"User({username}) fetching record({uid}) info") try: application_dict: dict = applications_collection.find_one({"uid": uid}) clean_dict(application_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if not application_dict: raise HTTPException(status_code=404, detail=MSG.ITEM_NOT_FOUND) # Student-self can access DisciplinaryRecord issued to himself/herself. application_owner = application_dict.get("student_id", "") permission_ok = Access.is_admin(username) permission_ok = True if username == application_owner else permission_ok if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) return application_dict
def url_MsgHandler(update, context): # context.bot.send_message(chat_id=update.effective_chat.id, text=update.message.text) try: url_received = update.message.text if "arxiv" in url_received: logger.debug("URL identified: arXiv") paper = get_paper(url_received) msg = "*Paper*: {}\n\n*Author*: {}\n\n*PDF*: {}".format( paper.title, paper.first_author, paper.pdf_url) user = get_current_telegram_user(update) add_paper_to_user(paper, user) elif "openaccess.thecvf.com" in url_received: logger.debug("URL identified: CVPR Open Access") msg = "CVPR Open Access (in development)" else: msg = "Currently only arxiv paper url is supported." except Exception as err: logger.error(err) msg = "Internal Server Error" # msg = telegram.utils.helpers.escape_markdown(msg) # respond to user update.message.reply_text(msg, parse_mode=telegram.ParseMode.MARKDOWN) user_log(update, remarks="respond_paper_info_from_url")
async def get_all_disciplinary_record(username=Depends( auth_handler.auth_wrapper)): """ Get all Disciplinary Records Require: Admin-read """ logger.debug(f"User({username}) fetching all records info") permission_ok: bool = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) records_list = [] try: for record in records_collection.find(): clean_dict(record) records_list.append(record) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return records_list
async def login(auth_details: User): try: user = users_collection.find_one({"username": auth_details.username}) except Exception as e: logger.error("Failed to query user from database.") logger.error(e) raise HTTPException(status_code=500, detail="Databse Error.") if not user or not auth_handler.verify_password(auth_details.password, user["password"]): raise HTTPException(status_code=401, detail="Invalid username and/or password") token = auth_handler.encode_token(auth_details.username) logger.debug( f"New JWT token generated for user: '******'") is_student = Access.is_student(auth_details.username) is_student_hg = Access.is_student_hg(auth_details.username) is_admin = Access.is_admin(auth_details.username) is_admin_write = Access.is_admin_write(auth_details.username) return { "token": token, "is_student": is_student, "is_student_hg": is_student_hg, "is_admin": is_admin, "is_admin_write": is_admin_write, }
async def get_active_application_periods(username=Depends( auth_handler.auth_wrapper)): """ Get Active (currently open) Application Periods Require: Any authenticated user """ logger.debug(f"User({username}) fetching active ApplicationPeriods") ap_list = [] _now = datetime.now() try: for ap_dict in application_periods_collection.find({ "application_window_open": { "$lt": _now }, "application_window_close": { "$gte": _now }, }).sort("application_window_open"): clean_dict(ap_dict) ap_dict["applicable_periods"] = convert_to_applicable_periods( ap_dict["applicable_periods"]) ap_list.append(ap_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return ap_list
async def get_all_application_periods(username=Depends( auth_handler.auth_wrapper)): """ Get ALL Application Periods Require: Admin-read """ logger.debug(f"User({username}) fetching ALL ApplicationPeriods.") permission_ok = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) ap_list = [] try: for ap_dict in application_periods_collection.find().sort( "created_by", DESCENDING): clean_dict(ap_dict) ap_dict["applicable_periods"] = convert_to_applicable_periods( ap_dict["applicable_periods"]) ap_list.append(ap_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return ap_list
async def get_an_application_period(uid: str, username=Depends( auth_handler.auth_wrapper)): """ Get an Application Period Require: Admin-read """ logger.debug( f"User({username}) requested to get ApplicationPeriod({uid}).") permission_ok = Access.is_admin(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: ap_info = application_periods_collection.find_one(filter={"uid": uid}) clean_dict(ap_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if ap_info: ap_info["applicable_periods"] = convert_to_applicable_periods( ap_info["applicable_periods"]) return ap_info else: raise HTTPException(status_code=404, detail=MSG.ITEM_NOT_FOUND)
def test_3_random_password_verification(self): password_hash = auth_handler.get_password_hash(self.password) for i in random_N_strings(N=20): logger.debug(f"Testing Random Password: {i}") verified = auth_handler.verify_password( plain_password=i, hashed_password=password_hash, ) self.assertFalse(verified)
def ics(update, context): # get file type file_type = update.message.document.mime_type # proceed only if the file is an ics if file_type == "text/calendar": # update.message.reply_text("Received!", parse_mode=telegram.ParseMode.MARKDOWN) logger.debug("New file (text/calendar) received.") ts: str = timestamp_now() file_id = update.message.document.file_id tg_file_ref = context.bot.get_file(file_id) download_filepath: Path = usr_data_path / f"{ts}.ics" tg_file_ref.download(download_filepath) # format the ics file try: new_file, number_of_events = calendarFixer.fix(download_filepath) user_log(update, ts=ts, remarks="ics") except Exception as e: logger.error("re-formatting of calendar ics file has failed.") logger.error(str(e)) update.message.reply_text( "Sorry, I failed to parse your file, please report the issue from here: /source", parse_mode=telegram.ParseMode.MARKDOWN, ) return # reply back update.message.reply_text( f"{number_of_events} events successfully re-formatted!", parse_mode=telegram.ParseMode.MARKDOWN, ) context.bot.send_document(chat_id=update.effective_chat.id, document=open(new_file, "rb")) update.message.reply_text( """*Fantastic, you can now import this `xxx_new.ics` into your Google/ Apple Calendar App, but you need to do this on your computer.* Instructions for Google Calendar: 1. Open [Google Calendar](https://calendar.google.com/) on Web. 2. At the top right, click gear-like icon and then *Settings*. 3. At the left, click *Import & Export*. 4. Click *Select file from your computer* and select the `.ics` file you get from me. 5. Choose which calendar to add the imported events to. By default, events will be imported into your primary calendar. 6. Click *Import*. """, parse_mode=telegram.ParseMode.MARKDOWN, ) else: update.message.reply_text( "I can only digest `.ics` file for now.", parse_mode=telegram.ParseMode.MARKDOWN, )
def tearDown(self): if self.ignore: return request_url = ( self.url_local_root + f"/api/application_periods/{self.test_use_uid}" ) response = requests.delete(url=request_url, headers=self.headers) if response.status_code == 200: logger.debug("Successfully removed test-generated data from database.") elif response.status_code == 404: logger.debug("No test-generated data found in database.") else: logger.error("Failed to remove test-generated data from database.")
async def student_decline_offer(uid: str, username=Depends(auth_handler.auth_wrapper)): """ Student to decline the offer in an Application Require: Student-self or Admin-write """ logger.debug(f"{username} trying to decline the offer in an ApplicationForm") _updated = student_update_application_form_status( AF_uid=uid, username=username, new_status=AFStatus.DECLINE, pre_status=[AFStatus.OFFER], ) return _updated
async def reject_application(uid: str, username=Depends(auth_handler.auth_wrapper)): """ Reject an Application Require: Admin-write """ logger.debug(f"{username} trying to reject an ApplicationForm") permission_ok = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) _updated = update_application_form_both_status(uid, AFStatus.REJECT) return _updated
async def add_room(new_room: Room, username=Depends(auth_handler.auth_wrapper)): """ Add a new Room to database Require: Admin-write """ logger.debug(f"User({username}) trying add new Room.") permission_ok: bool = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) room_dict = dict(new_room.dict()) try: _inserted_id = rooms_collection.insert_one(room_dict).inserted_id logger.debug(f"New Room inserted to DB with inserted_id: {_inserted_id}") except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) clean_dict(room_dict) logger.debug(f"New Room info: {room_dict}") return room_dict
async def create_an_event(new_event: Event, username=Depends(auth_handler.auth_wrapper)): """ Create an Event Require: Student-HG or Admin-write """ logger.debug(f"User({username}) trying creating new Event.") # Check access permission_ok = Access.at_least_student_hg_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) new_event.created_by = str(username) event_dict = dict(new_event.dict()) try: _inserted_id = events_collection.insert_one(event_dict).inserted_id logger.debug( f"New Event inserted to DB with inserted_id: {_inserted_id}") _event = events_collection.find_one({"_id": _inserted_id}) clean_dict(_event) logger.debug(f"New Event info: {_event}") return _event except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR)
async def get_student_submitted_applications(student_id: str, username=Depends( auth_handler.auth_wrapper)): """ Get a list of ApplicationForm that the student has submitted. Require: Student-self or Admin-read """ logger.debug( f"User({username}) trying fetching Student({student_id})'s Applications" ) permission_ok = Access.is_admin(username) or (username == student_id) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) application_list = [] try: student_info = students_collection.find_one({"student_id": student_id}) clean_dict(student_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if not student_info: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND) AF_uids = student_info.get("application_uids", []) if not AF_uids: return {} else: AF_uids = list(set(AF_uids)) submitted_applications: Dict[str, dict] = {} try: for uid in AF_uids: if isinstance(uid, str): ap_dict: dict = applications_collection.find_one({"uid": uid}) clean_dict(ap_dict) if ap_dict: submitted_applications[uid] = ap_dict except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) return submitted_applications
def migrate_2(): joe_video_folder = Path( "/data/urop/gs-samill/Video_Folders/joe_videos/traffic_videos") destination_folder = Path("/home/UROP/data_urop/unlabelled/joe") assert joe_video_folder.is_dir() assert destination_folder.is_dir() for file in os.listdir(joe_video_folder): if file[-4:] != ".mov": continue new_name = "j_" + file.lower()[4:] video_filepath: Path = joe_video_folder / file dst_path: Path = destination_folder / new_name logger.debug(f"{video_filepath} -> {dst_path}") shutil.copy2(video_filepath, dst_path)
def blur_videos_folder( infolder: str = "/data/urop/all_videos_final") -> List[str]: infolder = Path(infolder).resolve() assert infolder.is_dir() video_filepath_list = [] for file in os.listdir(str(infolder)): if not file.endswith(".mp4"): logger.debug(f"Ignore: {file}") continue filepath = infolder / file assert filepath.is_file() video_filepath_list.append(str(filepath)) return video_filepath_list
async def student_withdraw_application( uid: str, username=Depends(auth_handler.auth_wrapper) ): """ Student to withdraw an Application Require: Student-self or Admin-write """ logger.debug(f"{username} trying to withdraw an ApplicationForm") _updated = student_update_application_form_status( AF_uid=uid, username=username, new_status=AFStatus.WITHDRAW, pre_status=AFStatus.PRE_WITHDRAW, ) return _updated
def safe_copy(src, dest): if not Path(src).exists(): logger.error( f"safe_copy cannot be done, because source file {src} not found.") return if Path(dest).exists(): logger.error( f"safe_copy cannot be done, because destination file {dest} already exist." ) return try: # subprocess.run(["cp", str(src), str(dest)]) shutil.copy2(src, dest) logger.debug(f"'{src}' has been copied to '{dest}'") except Exception as err: logger.error(f"Copy operation failed, reason: {err}")
async def delete_application(uid: str, username=Depends(auth_handler.auth_wrapper)): """ Delete an ApplicationForm info Require: Admin-write """ logger.debug(f"{username} trying to delete an ApplicationForm") permission_ok = Access.is_admin_write(username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: application_dict = applications_collection.find_one(filter={"uid": uid}) owner_student = application_dict.get("student_id") AP_uid = application_dict.get("application_period_uid") clean_dict(application_dict) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if not application_dict: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND) try: with client.start_session() as session: with session.start_transaction(): # delete application applications_collection.delete_one({"uid": uid}) # remove application uid from student profile _updated = students_collection.find_one_and_update( filter={"student_id": owner_student}, # NOTE: $pull Removes all array elements that match a specified query. update={"$pull": {"application_uids": uid}}, return_document=ReturnDocument.AFTER, session=session, ) logger.debug(f"Student Updated: {str(_updated)}") # decrease application period reference count # remove uid from application map _updated = application_periods_collection.find_one_and_update( filter={"uid": AP_uid}, update={ "$inc": {"reference_count": -1}, # NOTE: use dot notation to update field in dict in a document "$unset": {f"application_forms_map.{owner_student}": uid}, }, return_document=ReturnDocument.AFTER, session=session, ) logger.debug(f"AP Updated: {str(_updated)}") except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR)
def generate_data_for_p1(master_occurrence_map: Dict[str, Dict]): year_name_key = list(sorted(master_occurrence_map.keys())) # get the latest year_name_key = year_name_key[-2:] directed_connections = ["source,target,value"] for president in year_name_key: data = master_occurrence_map.get(president) for word, count in data.items(): record = president[5:] + "," + word + "," + str(count) directed_connections.append(record) export_path = result_folder / "word_directed_graph.csv" with export_path.open("w") as f: f.write("\n".join(directed_connections)) logger.debug(f"Exported: {export_path}")
async def delete_an_event(uid: str, username=Depends(auth_handler.auth_wrapper)): """ Delete an Event. Deletion can be done if and only if nobody has signed up/ attended the event. Require: HG or Admin-write """ logger.debug(f"User({username}) trying to delete Event({uid}).") permission_ok = Access.is_student_hg(username) or Access.is_admin_write( username) if not permission_ok: logger.debug(MSG.permission_denied_msg(username)) raise HTTPException(status_code=401, detail=MSG.PERMISSION_ERROR) try: event_info = events_collection.find_one(filter={"uid": uid}) clean_dict(event_info) except Exception as e: logger.error(MSG.DB_QUERY_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_QUERY_ERROR) if not event_info: raise HTTPException(status_code=404, detail=MSG.TARGET_ITEM_NOT_FOUND) ref_count = len(event_info.get("signups", [])) + len( event_info.get("attendance", [])) if ref_count != 0: raise HTTPException(status_code=400, detail=MSG.DEL_REF_COUNT_ERR) try: _DeleteResult = events_collection.delete_one({"uid": uid}) except Exception as e: logger.error(MSG.DB_UPDATE_ERROR) logger.error(e) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) if _DeleteResult.deleted_count != 1: logger.error(MSG.UNEXPECTED) raise HTTPException(status_code=500, detail=MSG.DB_UPDATE_ERROR) return
def get_stacked_chart_data(): filepath = result_folder / "tokenised_with_tag.json" with filepath.open() as f: content = json.load(f) master_dict = {} for name, token_tag_list in content.items(): master_dict[name] = {} for token_tag in token_tag_list: token = token_tag[0] tag = token_tag[1] if tag in master_dict[name]: master_dict[name][tag] += 1 else: master_dict[name][tag] = 1 fixed_tag_seq = [] for name, data in master_dict.items(): for tag in data.keys(): if tag not in fixed_tag_seq: fixed_tag_seq.append(tag) fixed_tag_seq = sorted(fixed_tag_seq) print(fixed_tag_seq) csv_datalist = [] for name, data in master_dict.items(): csv_row = [name] for tag in fixed_tag_seq: if tag in data: csv_row.append(str(data[tag])) else: csv_row.append("0") csv_datalist.append(",".join(csv_row)) fixed_tag_seq.insert(0, "Presidents") csv_datalist.insert(0, ",".join(fixed_tag_seq)) csv_data = "\n".join(csv_datalist) # export export_path = result_folder / "word_stack_chart.csv" with export_path.open("w") as f: f.write(csv_data) logger.debug(f"Exported: {export_path}")
def get_all_documents() -> List[str]: src_folder = Path(__file__).parent / "Inaugural_Addresses" docs = [] doc_names = [] for filename in sorted(os.listdir(src_folder)): filepath = src_folder / filename assert filepath.is_file() logger.debug(filename) with filepath.open() as f: lines = f.readlines() lines = [line.strip() for line in lines] doc = " ".join(lines) doc_names.append(filename[:-4]) docs.append(doc) return doc_names, docs
def setUp(self): self.test_use_uid = "TEST_123" self.url_local_root = "http://127.0.0.1:8000" self.url_server_root = "http://esc.dev.markhh.com" self.admin_username = "******" self.admin_password = None self.token = auth_handler.encode_token(self.admin_username) self.ignore = False # test connection request_url = str(self.url_server_root + "/api") try: response = requests.get(url=request_url, timeout=1) if response.status_code != 200: logger.error("setUp: Failed to connect") self.ignore = True return except Exception as e: logger.error(f"setUp: Failed to connect: {e}") self.ignore = True return # construct header headers = { "accept": "application/json", "Content-Type": "application/json", } request_url = self.url_server_root + "/api/auth/login" data = { "username": self.admin_username, "password": self.admin_password, } if not self.token: logger.debug("setUp: Getting new TOKEN") response = requests.post(url=request_url, headers=headers, json=data) if response.status_code != 200: raise Exception("Failed to login") res_data = response.json() self.token = str(res_data["token"]) # set self.headers logger.debug(f"setUp: TOKEN: {self.token}") headers["Authorization"] = "Bearer " + self.token self.headers = headers