Package: iitkgp-erp-login
ERP Login ModuleTired of the tedious ERP login process? Wanted to automate some ERP workflow but stuck at login?🚀 Introducingiitkgp-erp-login: Your Ultimate ERP Login Automation Module forIIT-KGP! 🚀Key Features:Seamless Credentials & OTP HandlingEffortless Session & ssoToken ManagementSmart Token Storage for EfficiencySupports both CLI & WebAppsNoteThis package is not officially affiliated with IIT Kharagpur.https://github.com/proffapt/iitkgp-erp-login-pypi/assets/86282911/c0401f6a-80af-46ae-8a8f-ac735f0e67b5Guess the number of lines of python code it will take you to achieve this.Reading this doc will give you the answer.Table of ContentsEndpointsAboutUsageLoginInputOutputUsageSession status checkInputOutputUsageUsing in WebAppsGet Session TokenGet Secret QuestionGet Login DetailsIs OTP RequiredRequest OTPSign InImplementing Login workflowExampleEndpointsTheendpoints.pyfile includes all the necessary endpoints for the ERP login workflow.AboutHOMEPAGE_URL: The URL of the ERP homepage/loginpage.SECRET_QUESTION_URL: The URL for retrieving the secret question for authentication.OTP_URL: The URL for requesting the OTP (One-Time Password) for authentication.LOGIN_URL: The URL for ERP login.WELCOMEPAGE_URL: The URL of the welcome page, which is accessible only when the user isNOTlogged in, and behaves exactly like theHOMEPAGE_URL. However, when the user is logged in, it returns a404error.Usagefromiitkgp_erp_login.endpointsimport*print(HOMEPAGE_URL)# Output: https://erp.iitkgp.ac.in/IIT_ERP3/print(LOGIN_URL)# Output: https://erp.iitkgp.ac.in/SSOAdministration/auth.htmLoginERP login workflow is implemented inlogin(headers, session, ERPCREDS=None, OTP_CHECK_INTERVAL=None, LOGGING=False, SESSION_STORAGE_FILE=None)function inerp.py.NoteThis function currently compiles the login workflow "ONLY for the CLI", not for web apps.InputThe function requires followingcompulsoryarguments:headers: Headers for the post requests.headers={'timeout':'20','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',}session: Arequests.Session()object, to persist the session parameters throughout the workflow.importrequestssession=requests.Session()The function can also be provided with theseoptionalarguments:ERPCREDS: ERP Login Credentials python file, which is imported into main python file.Default ValueNoneNOT SpecifiedThe user is prompted to enter their credentials manuallySpecified (ERPCREDS=erpcreds)The credentials are retrieved from theerpcreds.pyfileNoteHere,credentialsrefer to the roll number, password, and security question.Prerequisites - ERP credentials fileThis fileMUSTbe present in the same directory as the script whereiitkgp_erp_loginmodule is being imported.Create a.pyfile with your ERP credentials stored in it. Please follow the instructions below to create this file:You can choose any valid name for the file, adhering to Python's naming conventions.Do not change the variable names. Copy the format provided below & update the values inside thedouble quotes(").# ERP CredentialsROLL_NUMBER="XXYYXXXXX"PASSWORD="**********"SECURITY_QUESTIONS_ANSWERS={"Q1":"A1","Q2":"A2","Q3":"A3",}OTP_CHECK_INTERVAL: The interval (inseconds) after which the API continuously checks for new OTP emails.Default ValueNoneNOT SpecifiedThe user will be prompted to manually enter the received OTPSpecified (OTP_CHECKINTERVAL=2)The OTP will be automatically fetched and checked every2 secondsPrerequisites - Token for GMail enabled googleapiThe token fileMUSTbe present in the same directory as the script whereiitkgp_erp_loginmodule is being imported.Follow the steps in theGmail API - Python Quickstartguide to obtaincredentials.jsonfile.NoteThecredentials.jsonfile is permanent unless you manually delete its reference in your Google Cloud Console.To generate thetoken.jsonfile, follow the steps below:Import this modulepipinstalliitkgp-erp-loginExecute following command:python3-c"from iitkgp_erp_login.utils import generate_token; generate_token()"A browser window will open, prompting you to select the Google account associated with receiving OTP for login.Grant permission to the selected email address to utilize the newly enabledGmail API.Click onContinueinstead ofBack To SafetyThen, pressContinueagainThetoken.jsonfile will be generated in the same folder as thecredentials.jsonfileWarningThetoken.jsonfile has an expiration time, so it's important to periodically check and refresh it in your projects to ensure uninterrupted access.LOGGING: Togglescomprehensive logging.Default valueFalseNOT SpecifiedNo LoggingSpecified (LOGGING=True)Logs every step in an exhaustive mannerSESSION_STORAGE_FILE: A file wheresessionTokenandssoToken-  collectively referred to as "session tokens" here  - are stored for direct usage.Default valueNoneNOT SpecifiedThe session tokens will not be stored in a fileSpecified (SESSION_STORAGE_FILE=".session")The session tokens will be stored in.sessionfile for later direct usageNoteThe approximate expiry time forssoTokenis~30 minutesand that ofsessionobject is~2.5 hoursOutputThe function returns the following, in the order of occurrence as here (return sessionToken, ssoToken):sessionTokenssoTokenIt also modifies thesessionobject, which now includes parameters for the logged-in session. Thissessionobject can be utilized for further navigation within the ERP system.ROLL_NUMBERis made available for further usage in the following manner.importiitkgp_erp_login.erpaserpsessionToken,ssoToken=erp.login(headers,session)print('Roll Number =',erp.ROLL_NUMBER)UsageIt is recommended to use theloginfunction in the following manner (optional arguments areyourchoice):# Importing the erp.py fileimportiitkgp_erp_login.erpaserp# Using the login function inside erp.pysessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=2,LOGGING=True,SESSION_STORAGE_FILE=".session")Here are some examples combining all the aspects we have discussed so far about theloginfunction:importrequestsimporterpcredsimportiitkgp_erp_login.erpaserpheaders={'timeout':'20','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',}session=requests.Session()sessionToken,ssoToken=erp.login(headers,session)# Credentials: Manual | OTP: Manual | Logging: No | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds)# Credentials: Automatic - from erpcreds.py | OTP: Manual | Logging: No | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,OTP_CHECK_INTERVAL=2)# Credentials: Manual | OTP: Automatic - checked every 2 seconds | Logging: No | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,LOGGING=True)# Credentials: Manual | OTP: Manual | Logging: Yes | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=5)# Credentials: Automatic - from erpcreds.py | OTP: Automatic - checked every 5 seconds | Logging: No | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=2,LOGGING=True)# Credentials: Automatic - from erpcreds.py | OTP: Automatic - checked every 2 seconds | Logging: Yes | TokenStorage: NosessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=2,SESSION_STORAGE_FILE='.session')# Credentials: Automatic - from erpcreds.py | OTP: Automatic - checked every 2 seconds | Logging: No | TokenStorage: in .session filesessionToken,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=2,LOGGING=True,SESSION_STORAGE_FILE='.session')# Credentials: Automatic - from erpcreds.py | OTP: Automatic - checked every 2 seconds | Logging: Yes | TokenStorage: in .session fileNoteThese are just examples of how to use theloginfunction, not satisfying the prerequisites.Some arguments oflogin()have their own prerequisites that must be satisfied in order to use them. See"Input" section of loginfor complete details.Session status checkThe logic for checking the status of the session is implemented in thesession_alive(session)function inerp.py. This function determines whether the given session is valid/alive or not.InputThe function requires following argument:session:requests.Session()object, to persist the session parameters throughout the workflow.importrequestssession=requests.Session()OutputThesession_alive(session)function returns the status of the session as a boolean value:StatusReturn ValueValid (Alive)TrueNot Valid (Dead)FalseUsageIt is recommended to use thesession_alivefunction in the following manner:# Importing the erp.py fileimportiitkgp_erp_login.erpaserp# Using the session_alive function inside erp.pyprint(erp.session_alive(session))Here's an example combining all the aspects we have discussed so far about theloginfunction andsession_alivefunction:importrequestsimporttimeimporterpcreds# Importing erpcreds.py, which contains ERP credentialsimportiitkgp_erp_login.erpaserpheaders={'timeout':'20','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',}session=requests.Session()print("Logging into ERP for:",creds.ROLL_NUMBER)whileTrue:ifnoterp.session_alive(session):_,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,LOGGING=True)else:print("Session is alive.")ssoToken=session.cookies.get('ssoToken')sessionToken=session.cookies.get('JSID#/IIT_ERP3')# Traverse ERP further using ssoTokentime.sleep(2)NoteThis is merely a Proof of Concept example; this exact functionality has been integrated into the login function itself from version2.3.1onwards.Using in WebAppsTo implement the login workflow forweb applicationsandbackend systems, utilize the following modularized steps in the form of functions.Get Session TokenGets session token from homepage response.Inputsession(requests.Session): Session objectlog(bool,optional): Whether to enable loggingOutput(str): Session token valueGet Secret QuestionFetches the secret question for a roll number.Inputheaders(dict[str, str]): Request headerssession(requests.Session): Session objectroll_number(str): Roll numberlog(bool,optional): Whether to enable loggingOutput(str): The secret question textGet Login DetailsCreates login details dictionary.Inputroll_number(str): User roll numberpassword(str): User passwordsecret_answer(str): Answer to secret questionsession_token(str): Session tokenOutput(LoginDetails): Dictionary with login credentialsIs OTP RequiredChecks if OTP is required for login based on network.InputNoneOutput(bool): True if OTP required, False otherwiseRequest OTPRequests an OTP to be sent to the user.Inputheaders(dict[str, str]): Request headerssession(requests.Session): Session objectlogin_details(LoginDetails): Dictionary with credentialslog(bool,optional): Whether to enable loggingOutputNoneRaisesErpLoginError: If OTP request failsSignInSigns in into the ERP for the given session.Inputheaders(dict[str, str]): Request headerssession(requests.Session): Session objectlogin_details(LoginDetails): Dictionary with credentialslog(bool,optional): Whether to enable loggingOutput(str): ssoToken extracted from the login responseImplementing login workflow for webappsFollowing is a proof of concept example to achieve the login workflow:importrequestsfromflaskimportFlaskimportiitkgp_erp_login.erpaserpapp=Flask(__name__)session=requests.Session()headers={'timeout':'20','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',}@app.route("/login")deflogin():roll=# 1. Get roll number from form inputspassw=# 2. Get password from form inputssessionToken=erp.get_sessiontoken(session)# 3secret_question=erp.get_secret_question(headers,session,roll)# 4# 5. Display the question on the frontendsecret_answer=# 6. Get password from the form inputloginDetails=erp.get_login_details(roll,passw,secret_answer,sessionToken)# 7# 8. Handle OTPiferp.is_otp_required():request_otp(headers=headers,session=session,login_details=login_details,log=False)# 8.1 Request OTPlogin_details["email_otp"]=# 8.2 Get otp from form inputselse:print("OTP not required :yay")ssoToken=erp.signin(headers,session,loginDetails)# 9# ...ExampleNow, we will create a script that opens the ERP Homepage on your default browser with a logged-in session.Install the package.pipinstalliitkgp-erp-loginMake sure thaterpcreds.py&token.jsonfiles exist in the same directory as the script we are about to create.Create a file namedopen_erp.pyand include the following code:importrequestsimportwebbrowserimporterpcredsimportiitkgp_erp_login.erpaserpfromiitkgp_erp_login.endpointsimportHOMEPAGE_URLheaders={'timeout':'20','User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36',}session=requests.Session()_,ssoToken=erp.login(headers,session,ERPCREDS=erpcreds,OTP_CHECK_INTERVAL=2,LOGGING=True,SESSION_STORAGE_FILE=".session")logged_in_url=f"{HOMEPAGE_URL}?ssoToken={ssoToken}"webbrowser.open(logged_in_url)Run the script.python3open_erp.py