session.py 7.23 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"
atanikan's avatar
atanikan committed
18
19
20
21
22
        self.restAPIinit = "http://imedevel.uchicago.edu:8000/init"
        self.restAPIrun  = "http://imedevel.uchicago.edu:8000/run"
        self.restAPIstop = "http://imedevel.uchicago.edu:8000/stop"
        self.restAPIstatus = "http://imedevel.uchicago.edu:8000/status"
        self.maxSessionTime = 3600 # seconds
Marco Govoni's avatar
Marco Govoni committed
23
        self.maxWaitTime = 1800 # seconds
24
25
26
        self.maxNumberOfCores = 4
        self.allowedExecutables = ["pw","wstat","wfreq"]
        # -------------------------------
Marco Govoni's avatar
Marco Govoni committed
27
        #
Marco Govoni's avatar
Marco Govoni committed
28
        data = {'emailId': self.emailId ,'sessionTime':str(self.maxSessionTime)} 
Marco Govoni's avatar
Marco Govoni committed
29
30
31
32
33
34
35
36
37
        #
        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:
38
            print('The server is not responding.',e)
Marco Govoni's avatar
Marco Govoni committed
39
40
        if response:
            if "Error" in response:
41
                print("Server failed with the following error \n",response['Error'])
Marco Govoni's avatar
Marco Govoni committed
42
43
44
                return None
            else:
                print("Check the inbox/spam folder of your email and click on the link to activate the session")
45
                self.token = response["token"]
Marco Govoni's avatar
Marco Govoni committed
46
        else:
47
            print('The server is not responding.')
Marco Govoni's avatar
Marco Govoni committed
48
    
49
50
    def getToken(self):
        """Returns the token of the session.
Marco Govoni's avatar
Marco Govoni committed
51
52
53
54
        
        :Example:
        
        >>> from westpy import *
55
56
        >>> session = Session("email@domain.com")
        >>> token = session.getToken()
Marco Govoni's avatar
Marco Govoni committed
57
        >>> print(token)
Marco Govoni's avatar
Marco Govoni committed
58
59
        
        """
60
61
        if self.token :
            return self.token
Marco Govoni's avatar
Marco Govoni committed
62
63
64
65
        else:
            raise ValueError("Cannot find output.")
    
    def stop(self):
66
        """Stops the session and clears the remote workspace. 
Marco Govoni's avatar
Marco Govoni committed
67
68
69
70
        
        :Example:
        
        >>> from westpy import *
71
72
        >>> session = Session("email@domain.com")
        >>> session.stop()
Marco Govoni's avatar
Marco Govoni committed
73
74
75
76
77
78
        
        """
        
        import requests
        import json
        #
79
        headers = {'Content-Type':'application/json; charset=utf-8','emailId':self.emailId,'token':self.token}
Marco Govoni's avatar
Marco Govoni committed
80
81
82
        try:
            response = requests.get(self.restAPIstop, headers=headers, timeout=None)
        except Exception as e:
83
            print('The server is not responding.',e)		 
Marco Govoni's avatar
Marco Govoni committed
84
        return json.loads(response.text) 
atanikan's avatar
atanikan committed
85
86
87
88
89
90
91
92

    def status(self):
        """Returns whether the session is active and time left. 
        
        :Example:
        
        >>> from westpy import *
        >>> session = Session("email@domain.com")
Marco Govoni's avatar
Marco Govoni committed
93
94
        >>> status = session.status()
        >>> print(status)
atanikan's avatar
atanikan committed
95
96
97
98
99
100
101
102
103
104
105
106
107
        
        """
        
        import requests
        import json
        #
        headers = {'Content-Type':'application/json; charset=utf-8','emailId':self.emailId,'token':self.token}
        try:
            response = requests.get(self.restAPIstatus, headers=headers, timeout=None)
        except Exception as e:
            print('The server is not responding.',e)		 
        return json.loads(response.text) 
		
Marco Govoni's avatar
Marco Govoni committed
108
    def run(self,executable=None,inputFile=None,outputFile=None,downloadUrl=[],number_of_cores=2) :
109
        """Runs the executable on the remote server.
Marco Govoni's avatar
Marco Govoni committed
110
111
112
113
114
115
116
        
        :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
117
118
        :param downloadUrl: URLs to be downloaded
        :type downloadUrl: list of string
Marco Govoni's avatar
Marco Govoni committed
119
120
121
122
123
124
        :param number_of_cores: number of cores
        :type number_of_cores: int
        
        :Example:
        
        >>> from westpy import *
125
126
127
        >>> 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
128
129
130
131
132
        
        """
        #
        import json
        #
133
134
135
136
        assert( number_of_cores <= self.maxNumberOfCores )
        #
        output_dict = {}
        if executable in self.allowedExecutables : 
Marco Govoni's avatar
Marco Govoni committed
137
138
139
140
141
142
           # 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
143
              output = self.__runExecutable(executable,inputFile,downloadUrl,number_of_cores)
Marco Govoni's avatar
Marco Govoni committed
144
145
              output_json = json.loads(output)
              if "Error" in output_json:
146
                 print("Server failed with the following error \n",output_json['Error'])
Marco Govoni's avatar
Marco Govoni committed
147
148
149
150
151
                 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()
152
153
154
155
              if "pw" in executable:
                 output_dict = json.loads(output_json['output_dict'])
              else:
                 output_dict = output_json['output_dict']
Marco Govoni's avatar
Marco Govoni committed
156
157
158
159
              # write the output file
              with open(outputFile, "w") as file :
                 file.write(str(output_data))
           except Exception as e:
Marco Govoni's avatar
Marco Govoni committed
160
              print("Session Expired! Invalid Request sent, Please recreate session and recheck your input. \n"+ str(e))		 
Marco Govoni's avatar
Marco Govoni committed
161
162
              return None          
        else:
163
           raise ValueError("Invalid executable name") 
Marco Govoni's avatar
Marco Govoni committed
164
165
166
        #
        print("Generated ",outputFile)
        return output_dict
Marco Govoni's avatar
Marco Govoni committed
167
      
Marco Govoni's avatar
Marco Govoni committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    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
184
        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
185
186
        jsondata = json.dumps(body)
        jsondataasbytes = jsondata.encode('utf-8')   # needs to be bytes
187
        headers = {'Content-Type':'application/json; charset=utf-8','emailId':self.emailId,'token':self.token}
Marco Govoni's avatar
Marco Govoni committed
188
        response = ""
189
        print("Requested to run executable", executable, "on server", self.serverName)
Marco Govoni's avatar
Marco Govoni committed
190
191
192
193
        try:
           response = requests.post(self.restAPIrun, data = jsondataasbytes, headers=headers, timeout=None)
           return response.text
        except Exception as e:
194
           print('The server is not responding.',e)	
Marco Govoni's avatar
Marco Govoni committed
195
196
           return None
        return None