session.py 6.36 KB
Newer Older
Marco Govoni's avatar
Marco Govoni committed
1
2
from __future__ import print_function

3
4
class Session(object):
    """Class for setting up a session, connected to a remove server via rest APIs.
Marco Govoni's avatar
Marco Govoni committed
5
6
7
8
    
    :Example:
    
    >>> from westpy import *
9
    >>> session = Session("email@domain.com")
Marco Govoni's avatar
Marco Govoni committed
10
11
12
    
    """
    def __init__(self,emailId) :
13
        self.token = None
Marco Govoni's avatar
Marco Govoni committed
14
        self.emailId = str(emailId)
15
16
17
        #
        # --- CONFIGURABLE PARAMETERS --- 
        self.serverName = "imedevel.uchicago.edu"
Marco Govoni's avatar
Marco Govoni committed
18
19
20
        self.restAPIinit = "http://imedevel.uchicago.edu:8000/getSessionId"
        self.restAPIrun  = "http://imedevel.uchicago.edu:8000/runWestCode"
        self.restAPIstop = "http://imedevel.uchicago.edu:8000/stopSession"
Marco Govoni's avatar
Marco Govoni committed
21
22
        self.maxSessionTime = 1800 # seconds
        self.maxWaitTime = 1800 # seconds
23
24
25
        self.maxNumberOfCores = 4
        self.allowedExecutables = ["pw","wstat","wfreq"]
        # -------------------------------
Marco Govoni's avatar
Marco Govoni committed
26
        #
Marco Govoni's avatar
Marco Govoni committed
27
        data = {'emailId': self.emailId ,'sessionTime':str(self.maxSessionTime)} 
Marco Govoni's avatar
Marco Govoni committed
28
29
30
31
32
33
34
35
36
        #
        import requests
        import json
        #
        response = None
        try:
            output = requests.post(self.restAPIinit, data=json.dumps(data))
            response = json.loads(output.text)
        except Exception as e:
37
            print('The server is not responding.',e)
Marco Govoni's avatar
Marco Govoni committed
38
39
        if response:
            if "Error" in response:
40
                print("Server failed with the following error \n",response['Error'])
Marco Govoni's avatar
Marco Govoni committed
41
42
43
                return None
            else:
                print("Check the inbox/spam folder of your email and click on the link to activate the session")
44
                self.token = response["token"]
Marco Govoni's avatar
Marco Govoni committed
45
        else:
46
            print('The server is not responding.')
Marco Govoni's avatar
Marco Govoni committed
47
    
48
49
    def getToken(self):
        """Returns the token of the session.
Marco Govoni's avatar
Marco Govoni committed
50
51
52
53
        
        :Example:
        
        >>> from westpy import *
54
55
        >>> session = Session("email@domain.com")
        >>> token = session.getToken()
Marco Govoni's avatar
Marco Govoni committed
56
57
        
        """
58
59
        if self.token :
            return self.token
Marco Govoni's avatar
Marco Govoni committed
60
61
62
63
        else:
            raise ValueError("Cannot find output.")
    
    def stop(self):
64
        """Stops the session and clears the remote workspace. 
Marco Govoni's avatar
Marco Govoni committed
65
66
67
68
        
        :Example:
        
        >>> from westpy import *
69
70
        >>> session = Session("email@domain.com")
        >>> session.stop()
Marco Govoni's avatar
Marco Govoni committed
71
72
73
74
75
76
        
        """
        
        import requests
        import json
        #
77
        headers = {'Content-Type':'application/json; charset=utf-8','emailId':self.emailId,'token':self.token}
Marco Govoni's avatar
Marco Govoni committed
78
79
80
        try:
            response = requests.get(self.restAPIstop, headers=headers, timeout=None)
        except Exception as e:
81
            print('The server is not responding.',e)		 
Marco Govoni's avatar
Marco Govoni committed
82
83
        return json.loads(response.text) 
    
Marco Govoni's avatar
Marco Govoni committed
84
    def run(self,executable=None,inputFile=None,outputFile=None,downloadUrl=[],number_of_cores=2) :
85
        """Runs the executable on the remote server.
Marco Govoni's avatar
Marco Govoni committed
86
87
88
89
90
91
92
        
        :param executable: name of executable
        :type executable: string
        :param inputFile: name of input file
        :type inputFile: string
        :param outputFile: name of output file
        :type outputFile: string
Marco Govoni's avatar
Marco Govoni committed
93
94
        :param downloadUrl: URLs to be downloaded
        :type downloadUrl: list of string
Marco Govoni's avatar
Marco Govoni committed
95
96
97
98
99
100
        :param number_of_cores: number of cores
        :type number_of_cores: int
        
        :Example:
        
        >>> from westpy import *
101
102
103
        >>> session = Session("email@domain.com")
        >>> session.run( "pw", "pw.in", "pw.out", ["http://www.quantum-simulation.org/potentials/sg15_oncv/upf/C_ONCV_PBE-1.0.upf"] , 2 )
        >>> session.stop()
Marco Govoni's avatar
Marco Govoni committed
104
105
106
107
108
        
        """
        #
        import json
        #
109
110
111
112
        assert( number_of_cores <= self.maxNumberOfCores )
        #
        output_dict = {}
        if executable in self.allowedExecutables : 
Marco Govoni's avatar
Marco Govoni committed
113
114
115
116
117
118
           # set inputs
           if inputFile is None:
              inputFile = str(executable)+".in"
           if outputFile is None:
              outputFile = str(executable)+".out"		 
           try:
Marco Govoni's avatar
Marco Govoni committed
119
              output = self.__runExecutable(executable,inputFile,downloadUrl,number_of_cores)
Marco Govoni's avatar
Marco Govoni committed
120
121
              output_json = json.loads(output)
              if "Error" in output_json:
122
                 print("Server failed with the following error \n",output_json['Error'])
Marco Govoni's avatar
Marco Govoni committed
123
124
125
126
127
                 return None			   
              elif "JOB DONE." not in str(output_json['output']).strip():
                 print("MPI execution failed with the following error:  \n"+str(output))
                 return None
              output_data = str(output_json['output']).strip()
128
              output_dict = json.loads(output_json['output_dict'])
Marco Govoni's avatar
Marco Govoni committed
129
130
131
132
133
134
135
              # write the output file
              with open(outputFile, "w") as file :
                 file.write(str(output_data))
           except Exception as e:
              print("Session Expired! Invalid Request sent, Please recreate session and recheck your input. \n"+ e)		 
              return None          
        else:
136
           raise ValueError("Invalid executable name") 
Marco Govoni's avatar
Marco Govoni committed
137
138
139
        #
        print("Generated ",outputFile)
        return output_dict
Marco Govoni's avatar
Marco Govoni committed
140
      
Marco Govoni's avatar
Marco Govoni committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    def __runExecutable(self,executable,input_file,download_urls,number_of_cores) :
        """Runs remotely the executable using a REST api.
        """
        #
        import requests
        import json
        # suck in the input file
        try:
           file_content = ""	     
           with open(input_file,'r') as f :
              for line in f :
                 file_content = file_content + line + "\\n"
        except FileNotFoundError:
           error = "Could not find "+ input_file + ". \n Generate input file "+ input_file +" and try again."	  
           print(error)
           return None
Marco Govoni's avatar
Marco Govoni committed
157
        body = {'urls':download_urls,'file':file_content,'cmd_timeout':str(self.maxWaitTime),'script_type':str(executable),'no_of_cores':str(number_of_cores)}  
Marco Govoni's avatar
Marco Govoni committed
158
159
        jsondata = json.dumps(body)
        jsondataasbytes = jsondata.encode('utf-8')   # needs to be bytes
160
        headers = {'Content-Type':'application/json; charset=utf-8','emailId':self.emailId,'token':self.token}
Marco Govoni's avatar
Marco Govoni committed
161
        response = ""
162
        print("Requested to run executable", executable, "on server", self.serverName)
Marco Govoni's avatar
Marco Govoni committed
163
164
165
166
        try:
           response = requests.post(self.restAPIrun, data = jsondataasbytes, headers=headers, timeout=None)
           return response.text
        except Exception as e:
167
           print('The server is not responding.',e)	
Marco Govoni's avatar
Marco Govoni committed
168
169
           return None
        return None