session.py 7.22 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("your.email@domain.edu")
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
        >>> session = Session("your.email@domain.edu")
56
        >>> 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
        >>> session = Session("your.email@domain.edu")
72
        >>> 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

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