├── .gitignore ├── README.md ├── pymatbridge ├── __init__.py ├── logs │ ├── bashlog_python-matlab-bridge.txt │ └── matlablog_python-matlab-bridge.txt └── matlab │ ├── functions │ ├── JavaTcpServer.m │ ├── header2text.m │ ├── json2mat.m │ ├── make_bin_http_header.m │ ├── make_html_http_header.m │ ├── make_image_http_header.m │ ├── mat2json.m │ ├── multipart2struct.m │ ├── rmvp.m │ ├── run_dot_m.m │ └── text2header.m │ ├── startup.m │ ├── test_functions │ └── test_sum.m │ ├── webserver.m │ └── www │ ├── exit_server.m │ ├── index.html │ ├── test_connect.m │ └── web_feval.m ├── test.m └── test.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .idea/workspace.xml 3 | 4 | .idea/vcs.xml 5 | 6 | .idea/python-matlab-bridge.iml 7 | 8 | .idea/modules.xml 9 | 10 | .idea/misc.xml 11 | 12 | .idea/encodings.xml 13 | 14 | .idea/.name 15 | 16 | .DS_Store 17 | 18 | ADME.markdown 19 | 20 | *.pyc 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python-MATLAB Bridge 2 | 3 | A simple interface to allow Python to call MATLAB functions. 4 | 5 | Unlike other interfaces, MATLAB only has to start once. All communication is done over a TCP server (credit to D.Kroon University of Twente for the TCP server). 6 | 7 | This has not been tested on Windows. 8 | 9 | ## Usage 10 | 11 | Initialize the Matlab class. You must pass in your matlab executable, e.g. 12 | 13 | from pymatbridge import Matlab 14 | mlab = Matlab(matlab='/Applications/MATLAB_R2011a.app/bin/matlab') 15 | 16 | By default the host is localhost and the port is 4000. This can be changed, e.g. 17 | 18 | mlab = Matlab(matlab='/Applications/MATLAB_R2011a.app/bin/matlab', 19 | host='192.168.0.1', port=5151) 20 | 21 | You must then start the MATLAB server: 22 | 23 | mlab.start() 24 | 25 | which will return True once connected. 26 | 27 | You can then run any local MATLAB function contained within a .m file of the same name. For example, to call the function jk in jk.m: 28 | 29 | %% MATLAB 30 | function lol = jk(args) 31 | arg1 = args.arg1; 32 | arg2 = args.arg2; 33 | lol = arg1 + arg2; 34 | end 35 | 36 | by calling: 37 | 38 | res = mlab.run('path/to/jk.m', {'arg1': 3, 'arg2': 5}) 39 | print res['result'] 40 | 41 | which will print 8. 42 | 43 | You can shut down the MATLAB server by calling 44 | 45 | mlab.stop() 46 | 47 | NB: you can call MATLAB code before the server starts by adding code to the ./matlab/startup.m file. 48 | 49 | # Example 50 | 51 | An example MATLAB function and usage from Python is shown in test.py and test.m and you can also see a [Notebook](http://nbviewer.ipython.org/github/plotly/IPython-plotly/blob/master/MATLAB%20Bridge.ipynb) using the Plotly MATLAB API. 52 | 53 | # TODO 54 | 55 | - MATLAB error handling. 56 | - Multiple simultaneous connections. 57 | 58 | Max Jaderberg 2012 59 | -------------------------------------------------------------------------------- /pymatbridge/__init__.py: -------------------------------------------------------------------------------- 1 | ############################################### 2 | # Matlab.py 3 | # Part of Python-MATLAB-bridge 4 | # Max Jaderberg 2012 5 | ############################################### 6 | from httplib import BadStatusLine 7 | import urllib2, urllib, os, json, time 8 | from multiprocessing import Process 9 | 10 | MATLAB_FOLDER = '%s/matlab' % os.path.realpath(os.path.dirname(__file__)) 11 | 12 | class Matlab(object): 13 | eval_func = 'web_feval.m' 14 | running = False 15 | matlab = None 16 | host = None 17 | port = None 18 | server = None 19 | id = None 20 | server_process = Process() 21 | 22 | def __init__(self, matlab='/Applications/MATLAB_R2011a.app/bin/matlab', host='localhost', port=4000, id='python-matlab-bridge'): 23 | self.matlab = matlab 24 | self.host = host 25 | self.port = port 26 | self.server = 'http://%s:%s' % (self.host, str(self.port)) 27 | self.id = id 28 | 29 | def start(self): 30 | def _run_matlab_server(): 31 | os.system('%s -nodesktop -nosplash -nodisplay -r "cd pymatbridge/matlab,webserver(%s),exit" -logfile ./pymatbridge/logs/matlablog_%s.txt > ./pymatbridge/logs/bashlog_%s.txt' % (self.matlab, self.port, self.id, self.id)) 32 | return True 33 | # Start the MATLAB server 34 | print "Starting MATLAB" 35 | self.server_process = Process(target=_run_matlab_server) 36 | self.server_process.daemon = True 37 | self.server_process.start() 38 | while not self.is_connected(): 39 | print "...still starting up..." 40 | time.sleep(1) 41 | print "MATLAB started and connected!" 42 | return True 43 | 44 | 45 | 46 | def stop(self): 47 | # Stop the MATLAB server 48 | try: 49 | try: 50 | resp = self._open_page('exit_server.m', {'id': self.id}) 51 | except BadStatusLine: 52 | pass 53 | except urllib2.URLError: 54 | pass 55 | print "MATLAB closed" 56 | return True 57 | 58 | def is_connected(self): 59 | try: 60 | resp = self._open_page('test_connect.m', {'id': self.id}) 61 | if resp['message']: 62 | return True 63 | except urllib2.URLError: 64 | pass 65 | return False 66 | 67 | def is_function_processor_working(self): 68 | try: 69 | result = self.run('%s/test_functions/test_sum.m' % MATLAB_FOLDER, {'echo': 'Matlab: Function processor is working!'}) 70 | if result['success'] == 'true': 71 | return True 72 | except urllib2.URLError: 73 | pass 74 | return False 75 | 76 | def run(self, func_path, func_args=None, maxtime=None): 77 | if self.running: 78 | time.sleep(0.5) 79 | page_args = { 80 | 'func_path': os.path.abspath(func_path), 81 | } 82 | if func_args: 83 | page_args['arguments'] = json.dumps(func_args) 84 | if maxtime: 85 | result = self._open_page(self.eval_func, page_args, maxtime) 86 | else: 87 | result = self._open_page(self.eval_func, page_args) 88 | return result 89 | 90 | def _open_page(self, page_name, arguments={}, timeout=10): 91 | self.running = True 92 | page = urllib2.urlopen('%s/%s' % (self.server, page_name), urllib.urlencode(arguments), timeout) 93 | self.running = False 94 | return json.loads(page.read()) 95 | 96 | 97 | -------------------------------------------------------------------------------- /pymatbridge/logs/bashlog_python-matlab-bridge.txt: -------------------------------------------------------------------------------- 1 | Warning: No window system found. Java option 'MWT' ignored 2 | 3 | < M A T L A B (R) > 4 | Copyright 1984-2010 The MathWorks, Inc. 5 | Version 7.12.0.635 (R2011a) 64-bit (maci64) 6 | March 18, 2011 7 | 8 | 9 | To get started, type one of these: helpwin, helpdesk, or demo. 10 | For product information, visit www.mathworks.com. 11 | 12 | Webserver Available on http://localhost:4000/ 13 | POST /test_connect.m HTTP/1.1 14 | Accept-Encoding: identity 15 | Content-Length: 23 16 | Host: localhost:4000 17 | Content-Type: application/x-www-form-urlencoded 18 | Connection: close 19 | User-Agent: Python-urllib/2.6 20 | 21 | id=python-matlab-bridge 22 | Post: [1x1 struct] 23 | AcceptEncoding: 'identity' 24 | ContentLength: '23' 25 | Host: 'localhost:4000' 26 | ContentType: [1x1 struct] 27 | Connection: 'close' 28 | UserAgent: 'Python-urllib/2.6' 29 | Content: [1x1 struct] 30 | 31 | HTTP/1.0 200 OK 32 | Date: Tue, 12 Oct 2010 09:19:05 GMT 33 | Server: Matlab Webserver 34 | X-Powered-By: Matlab7.12.0.635 (R2011a) 35 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 36 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 37 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 38 | Pragma: no-cache 39 | Connection: close 40 | Content-Length: 68 41 | Content-Type: text/html; charset=UTF-8 42 | 43 | 44 | POST /web_feval.m HTTP/1.1 45 | Accept-Encoding: identity 46 | Content-Length: 82 47 | Host: localhost:4000 48 | Content-Type: application/x-www-form-urlencoded 49 | Connection: close 50 | User-Agent: Python-urllib/2.6 51 | 52 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+0%7D 53 | Post: [1x1 struct] 54 | AcceptEncoding: 'identity' 55 | ContentLength: '82' 56 | Host: 'localhost:4000' 57 | ContentType: [1x1 struct] 58 | Connection: 'close' 59 | UserAgent: 'Python-urllib/2.6' 60 | Content: [1x1 struct] 61 | 62 | HTTP/1.0 200 OK 63 | Date: Tue, 12 Oct 2010 09:19:05 GMT 64 | Server: Matlab Webserver 65 | X-Powered-By: Matlab7.12.0.635 (R2011a) 66 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 67 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 68 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 69 | Pragma: no-cache 70 | Connection: close 71 | Content-Length: 154 72 | Content-Type: text/html; charset=UTF-8 73 | 74 | 75 | POST /web_feval.m HTTP/1.1 76 | Accept-Encoding: identity 77 | Content-Length: 82 78 | Host: localhost:4000 79 | Content-Type: application/x-www-form-urlencoded 80 | Connection: close 81 | User-Agent: Python-urllib/2.6 82 | 83 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+1%7D 84 | Post: [1x1 struct] 85 | AcceptEncoding: 'identity' 86 | ContentLength: '82' 87 | Host: 'localhost:4000' 88 | ContentType: [1x1 struct] 89 | Connection: 'close' 90 | UserAgent: 'Python-urllib/2.6' 91 | Content: [1x1 struct] 92 | 93 | HTTP/1.0 200 OK 94 | Date: Tue, 12 Oct 2010 09:19:05 GMT 95 | Server: Matlab Webserver 96 | X-Powered-By: Matlab7.12.0.635 (R2011a) 97 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 98 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 99 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 100 | Pragma: no-cache 101 | Connection: close 102 | Content-Length: 154 103 | Content-Type: text/html; charset=UTF-8 104 | 105 | 106 | POST /web_feval.m HTTP/1.1 107 | Accept-Encoding: identity 108 | Content-Length: 82 109 | Host: localhost:4000 110 | Content-Type: application/x-www-form-urlencoded 111 | Connection: close 112 | User-Agent: Python-urllib/2.6 113 | 114 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+2%7D 115 | Post: [1x1 struct] 116 | AcceptEncoding: 'identity' 117 | ContentLength: '82' 118 | Host: 'localhost:4000' 119 | ContentType: [1x1 struct] 120 | Connection: 'close' 121 | UserAgent: 'Python-urllib/2.6' 122 | Content: [1x1 struct] 123 | 124 | HTTP/1.0 200 OK 125 | Date: Tue, 12 Oct 2010 09:19:05 GMT 126 | Server: Matlab Webserver 127 | X-Powered-By: Matlab7.12.0.635 (R2011a) 128 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 129 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 130 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 131 | Pragma: no-cache 132 | Connection: close 133 | Content-Length: 154 134 | Content-Type: text/html; charset=UTF-8 135 | 136 | 137 | POST /web_feval.m HTTP/1.1 138 | Accept-Encoding: identity 139 | Content-Length: 82 140 | Host: localhost:4000 141 | Content-Type: application/x-www-form-urlencoded 142 | Connection: close 143 | User-Agent: Python-urllib/2.6 144 | 145 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+3%7D 146 | Post: [1x1 struct] 147 | AcceptEncoding: 'identity' 148 | ContentLength: '82' 149 | Host: 'localhost:4000' 150 | ContentType: [1x1 struct] 151 | Connection: 'close' 152 | UserAgent: 'Python-urllib/2.6' 153 | Content: [1x1 struct] 154 | 155 | HTTP/1.0 200 OK 156 | Date: Tue, 12 Oct 2010 09:19:05 GMT 157 | Server: Matlab Webserver 158 | X-Powered-By: Matlab7.12.0.635 (R2011a) 159 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 160 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 161 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 162 | Pragma: no-cache 163 | Connection: close 164 | Content-Length: 154 165 | Content-Type: text/html; charset=UTF-8 166 | 167 | 168 | POST /web_feval.m HTTP/1.1 169 | Accept-Encoding: identity 170 | Content-Length: 82 171 | Host: localhost:4000 172 | Content-Type: application/x-www-form-urlencoded 173 | Connection: close 174 | User-Agent: Python-urllib/2.6 175 | 176 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+4%7D 177 | Post: [1x1 struct] 178 | AcceptEncoding: 'identity' 179 | ContentLength: '82' 180 | Host: 'localhost:4000' 181 | ContentType: [1x1 struct] 182 | Connection: 'close' 183 | UserAgent: 'Python-urllib/2.6' 184 | Content: [1x1 struct] 185 | 186 | HTTP/1.0 200 OK 187 | Date: Tue, 12 Oct 2010 09:19:05 GMT 188 | Server: Matlab Webserver 189 | X-Powered-By: Matlab7.12.0.635 (R2011a) 190 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 191 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 192 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 193 | Pragma: no-cache 194 | Connection: close 195 | Content-Length: 154 196 | Content-Type: text/html; charset=UTF-8 197 | 198 | 199 | POST /web_feval.m HTTP/1.1 200 | Accept-Encoding: identity 201 | Content-Length: 82 202 | Host: localhost:4000 203 | Content-Type: application/x-www-form-urlencoded 204 | Connection: close 205 | User-Agent: Python-urllib/2.6 206 | 207 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+5%7D 208 | Post: [1x1 struct] 209 | AcceptEncoding: 'identity' 210 | ContentLength: '82' 211 | Host: 'localhost:4000' 212 | ContentType: [1x1 struct] 213 | Connection: 'close' 214 | UserAgent: 'Python-urllib/2.6' 215 | Content: [1x1 struct] 216 | 217 | HTTP/1.0 200 OK 218 | Date: Tue, 12 Oct 2010 09:19:05 GMT 219 | Server: Matlab Webserver 220 | X-Powered-By: Matlab7.12.0.635 (R2011a) 221 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 222 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 223 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 224 | Pragma: no-cache 225 | Connection: close 226 | Content-Length: 154 227 | Content-Type: text/html; charset=UTF-8 228 | 229 | 230 | POST /web_feval.m HTTP/1.1 231 | Accept-Encoding: identity 232 | Content-Length: 82 233 | Host: localhost:4000 234 | Content-Type: application/x-www-form-urlencoded 235 | Connection: close 236 | User-Agent: Python-urllib/2.6 237 | 238 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+6%7D 239 | Post: [1x1 struct] 240 | AcceptEncoding: 'identity' 241 | ContentLength: '82' 242 | Host: 'localhost:4000' 243 | ContentType: [1x1 struct] 244 | Connection: 'close' 245 | UserAgent: 'Python-urllib/2.6' 246 | Content: [1x1 struct] 247 | 248 | HTTP/1.0 200 OK 249 | Date: Tue, 12 Oct 2010 09:19:05 GMT 250 | Server: Matlab Webserver 251 | X-Powered-By: Matlab7.12.0.635 (R2011a) 252 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 253 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 254 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 255 | Pragma: no-cache 256 | Connection: close 257 | Content-Length: 154 258 | Content-Type: text/html; charset=UTF-8 259 | 260 | 261 | POST /web_feval.m HTTP/1.1 262 | Accept-Encoding: identity 263 | Content-Length: 82 264 | Host: localhost:4000 265 | Content-Type: application/x-www-form-urlencoded 266 | Connection: close 267 | User-Agent: Python-urllib/2.6 268 | 269 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+7%7D 270 | Post: [1x1 struct] 271 | AcceptEncoding: 'identity' 272 | ContentLength: '82' 273 | Host: 'localhost:4000' 274 | ContentType: [1x1 struct] 275 | Connection: 'close' 276 | UserAgent: 'Python-urllib/2.6' 277 | Content: [1x1 struct] 278 | 279 | HTTP/1.0 200 OK 280 | Date: Tue, 12 Oct 2010 09:19:05 GMT 281 | Server: Matlab Webserver 282 | X-Powered-By: Matlab7.12.0.635 (R2011a) 283 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 284 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 285 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 286 | Pragma: no-cache 287 | Connection: close 288 | Content-Length: 154 289 | Content-Type: text/html; charset=UTF-8 290 | 291 | 292 | POST /web_feval.m HTTP/1.1 293 | Accept-Encoding: identity 294 | Content-Length: 82 295 | Host: localhost:4000 296 | Content-Type: application/x-www-form-urlencoded 297 | Connection: close 298 | User-Agent: Python-urllib/2.6 299 | 300 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+8%7D 301 | Post: [1x1 struct] 302 | AcceptEncoding: 'identity' 303 | ContentLength: '82' 304 | Host: 'localhost:4000' 305 | ContentType: [1x1 struct] 306 | Connection: 'close' 307 | UserAgent: 'Python-urllib/2.6' 308 | Content: [1x1 struct] 309 | 310 | HTTP/1.0 200 OK 311 | Date: Tue, 12 Oct 2010 09:19:05 GMT 312 | Server: Matlab Webserver 313 | X-Powered-By: Matlab7.12.0.635 (R2011a) 314 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 315 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 316 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 317 | Pragma: no-cache 318 | Connection: close 319 | Content-Length: 154 320 | Content-Type: text/html; charset=UTF-8 321 | 322 | 323 | POST /web_feval.m HTTP/1.1 324 | Accept-Encoding: identity 325 | Content-Length: 82 326 | Host: localhost:4000 327 | Content-Type: application/x-www-form-urlencoded 328 | Connection: close 329 | User-Agent: Python-urllib/2.6 330 | 331 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+9%7D 332 | Post: [1x1 struct] 333 | AcceptEncoding: 'identity' 334 | ContentLength: '82' 335 | Host: 'localhost:4000' 336 | ContentType: [1x1 struct] 337 | Connection: 'close' 338 | UserAgent: 'Python-urllib/2.6' 339 | Content: [1x1 struct] 340 | 341 | HTTP/1.0 200 OK 342 | Date: Tue, 12 Oct 2010 09:19:05 GMT 343 | Server: Matlab Webserver 344 | X-Powered-By: Matlab7.12.0.635 (R2011a) 345 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 346 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 347 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 348 | Pragma: no-cache 349 | Connection: close 350 | Content-Length: 155 351 | Content-Type: text/html; charset=UTF-8 352 | 353 | 354 | POST /exit_server.m HTTP/1.1 355 | Accept-Encoding: identity 356 | Content-Length: 23 357 | Host: localhost:4000 358 | Content-Type: application/x-www-form-urlencoded 359 | Connection: close 360 | User-Agent: Python-urllib/2.6 361 | 362 | id=python-matlab-bridge 363 | Post: [1x1 struct] 364 | AcceptEncoding: 'identity' 365 | ContentLength: '23' 366 | Host: 'localhost:4000' 367 | ContentType: [1x1 struct] 368 | Connection: 'close' 369 | UserAgent: 'Python-urllib/2.6' 370 | Content: [1x1 struct] 371 | 372 | -------------------------------------------------------------------------------- /pymatbridge/logs/matlablog_python-matlab-bridge.txt: -------------------------------------------------------------------------------- 1 | Warning: No window system found. Java option 'MWT' ignored 2 | 3 | < M A T L A B (R) > 4 | Copyright 1984-2010 The MathWorks, Inc. 5 | Version 7.12.0.635 (R2011a) 64-bit (maci64) 6 | March 18, 2011 7 | 8 | 9 | To get started, type one of these: helpwin, helpdesk, or demo. 10 | For product information, visit www.mathworks.com. 11 | 12 | Webserver Available on http://localhost:4000/ 13 | POST /test_connect.m HTTP/1.1 14 | Accept-Encoding: identity 15 | Content-Length: 23 16 | Host: localhost:4000 17 | Content-Type: application/x-www-form-urlencoded 18 | Connection: close 19 | User-Agent: Python-urllib/2.6 20 | 21 | id=python-matlab-bridge 22 | Post: [1x1 struct] 23 | AcceptEncoding: 'identity' 24 | ContentLength: '23' 25 | Host: 'localhost:4000' 26 | ContentType: [1x1 struct] 27 | Connection: 'close' 28 | UserAgent: 'Python-urllib/2.6' 29 | Content: [1x1 struct] 30 | 31 | HTTP/1.0 200 OK 32 | Date: Tue, 12 Oct 2010 09:19:05 GMT 33 | Server: Matlab Webserver 34 | X-Powered-By: Matlab7.12.0.635 (R2011a) 35 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 36 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 37 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 38 | Pragma: no-cache 39 | Connection: close 40 | Content-Length: 68 41 | Content-Type: text/html; charset=UTF-8 42 | 43 | 44 | POST /web_feval.m HTTP/1.1 45 | Accept-Encoding: identity 46 | Content-Length: 82 47 | Host: localhost:4000 48 | Content-Type: application/x-www-form-urlencoded 49 | Connection: close 50 | User-Agent: Python-urllib/2.6 51 | 52 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+0%7D 53 | Post: [1x1 struct] 54 | AcceptEncoding: 'identity' 55 | ContentLength: '82' 56 | Host: 'localhost:4000' 57 | ContentType: [1x1 struct] 58 | Connection: 'close' 59 | UserAgent: 'Python-urllib/2.6' 60 | Content: [1x1 struct] 61 | 62 | HTTP/1.0 200 OK 63 | Date: Tue, 12 Oct 2010 09:19:05 GMT 64 | Server: Matlab Webserver 65 | X-Powered-By: Matlab7.12.0.635 (R2011a) 66 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 67 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 68 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 69 | Pragma: no-cache 70 | Connection: close 71 | Content-Length: 154 72 | Content-Type: text/html; charset=UTF-8 73 | 74 | 75 | POST /web_feval.m HTTP/1.1 76 | Accept-Encoding: identity 77 | Content-Length: 82 78 | Host: localhost:4000 79 | Content-Type: application/x-www-form-urlencoded 80 | Connection: close 81 | User-Agent: Python-urllib/2.6 82 | 83 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+1%7D 84 | Post: [1x1 struct] 85 | AcceptEncoding: 'identity' 86 | ContentLength: '82' 87 | Host: 'localhost:4000' 88 | ContentType: [1x1 struct] 89 | Connection: 'close' 90 | UserAgent: 'Python-urllib/2.6' 91 | Content: [1x1 struct] 92 | 93 | HTTP/1.0 200 OK 94 | Date: Tue, 12 Oct 2010 09:19:05 GMT 95 | Server: Matlab Webserver 96 | X-Powered-By: Matlab7.12.0.635 (R2011a) 97 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 98 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 99 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 100 | Pragma: no-cache 101 | Connection: close 102 | Content-Length: 154 103 | Content-Type: text/html; charset=UTF-8 104 | 105 | 106 | POST /web_feval.m HTTP/1.1 107 | Accept-Encoding: identity 108 | Content-Length: 82 109 | Host: localhost:4000 110 | Content-Type: application/x-www-form-urlencoded 111 | Connection: close 112 | User-Agent: Python-urllib/2.6 113 | 114 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+2%7D 115 | Post: [1x1 struct] 116 | AcceptEncoding: 'identity' 117 | ContentLength: '82' 118 | Host: 'localhost:4000' 119 | ContentType: [1x1 struct] 120 | Connection: 'close' 121 | UserAgent: 'Python-urllib/2.6' 122 | Content: [1x1 struct] 123 | 124 | HTTP/1.0 200 OK 125 | Date: Tue, 12 Oct 2010 09:19:05 GMT 126 | Server: Matlab Webserver 127 | X-Powered-By: Matlab7.12.0.635 (R2011a) 128 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 129 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 130 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 131 | Pragma: no-cache 132 | Connection: close 133 | Content-Length: 154 134 | Content-Type: text/html; charset=UTF-8 135 | 136 | 137 | POST /web_feval.m HTTP/1.1 138 | Accept-Encoding: identity 139 | Content-Length: 82 140 | Host: localhost:4000 141 | Content-Type: application/x-www-form-urlencoded 142 | Connection: close 143 | User-Agent: Python-urllib/2.6 144 | 145 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+3%7D 146 | Post: [1x1 struct] 147 | AcceptEncoding: 'identity' 148 | ContentLength: '82' 149 | Host: 'localhost:4000' 150 | ContentType: [1x1 struct] 151 | Connection: 'close' 152 | UserAgent: 'Python-urllib/2.6' 153 | Content: [1x1 struct] 154 | 155 | HTTP/1.0 200 OK 156 | Date: Tue, 12 Oct 2010 09:19:05 GMT 157 | Server: Matlab Webserver 158 | X-Powered-By: Matlab7.12.0.635 (R2011a) 159 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 160 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 161 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 162 | Pragma: no-cache 163 | Connection: close 164 | Content-Length: 154 165 | Content-Type: text/html; charset=UTF-8 166 | 167 | 168 | POST /web_feval.m HTTP/1.1 169 | Accept-Encoding: identity 170 | Content-Length: 82 171 | Host: localhost:4000 172 | Content-Type: application/x-www-form-urlencoded 173 | Connection: close 174 | User-Agent: Python-urllib/2.6 175 | 176 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+4%7D 177 | Post: [1x1 struct] 178 | AcceptEncoding: 'identity' 179 | ContentLength: '82' 180 | Host: 'localhost:4000' 181 | ContentType: [1x1 struct] 182 | Connection: 'close' 183 | UserAgent: 'Python-urllib/2.6' 184 | Content: [1x1 struct] 185 | 186 | HTTP/1.0 200 OK 187 | Date: Tue, 12 Oct 2010 09:19:05 GMT 188 | Server: Matlab Webserver 189 | X-Powered-By: Matlab7.12.0.635 (R2011a) 190 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 191 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 192 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 193 | Pragma: no-cache 194 | Connection: close 195 | Content-Length: 154 196 | Content-Type: text/html; charset=UTF-8 197 | 198 | 199 | POST /web_feval.m HTTP/1.1 200 | Accept-Encoding: identity 201 | Content-Length: 82 202 | Host: localhost:4000 203 | Content-Type: application/x-www-form-urlencoded 204 | Connection: close 205 | User-Agent: Python-urllib/2.6 206 | 207 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+5%7D 208 | Post: [1x1 struct] 209 | AcceptEncoding: 'identity' 210 | ContentLength: '82' 211 | Host: 'localhost:4000' 212 | ContentType: [1x1 struct] 213 | Connection: 'close' 214 | UserAgent: 'Python-urllib/2.6' 215 | Content: [1x1 struct] 216 | 217 | HTTP/1.0 200 OK 218 | Date: Tue, 12 Oct 2010 09:19:05 GMT 219 | Server: Matlab Webserver 220 | X-Powered-By: Matlab7.12.0.635 (R2011a) 221 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 222 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 223 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 224 | Pragma: no-cache 225 | Connection: close 226 | Content-Length: 154 227 | Content-Type: text/html; charset=UTF-8 228 | 229 | 230 | POST /web_feval.m HTTP/1.1 231 | Accept-Encoding: identity 232 | Content-Length: 82 233 | Host: localhost:4000 234 | Content-Type: application/x-www-form-urlencoded 235 | Connection: close 236 | User-Agent: Python-urllib/2.6 237 | 238 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+6%7D 239 | Post: [1x1 struct] 240 | AcceptEncoding: 'identity' 241 | ContentLength: '82' 242 | Host: 'localhost:4000' 243 | ContentType: [1x1 struct] 244 | Connection: 'close' 245 | UserAgent: 'Python-urllib/2.6' 246 | Content: [1x1 struct] 247 | 248 | HTTP/1.0 200 OK 249 | Date: Tue, 12 Oct 2010 09:19:05 GMT 250 | Server: Matlab Webserver 251 | X-Powered-By: Matlab7.12.0.635 (R2011a) 252 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 253 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 254 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 255 | Pragma: no-cache 256 | Connection: close 257 | Content-Length: 154 258 | Content-Type: text/html; charset=UTF-8 259 | 260 | 261 | POST /web_feval.m HTTP/1.1 262 | Accept-Encoding: identity 263 | Content-Length: 82 264 | Host: localhost:4000 265 | Content-Type: application/x-www-form-urlencoded 266 | Connection: close 267 | User-Agent: Python-urllib/2.6 268 | 269 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+7%7D 270 | Post: [1x1 struct] 271 | AcceptEncoding: 'identity' 272 | ContentLength: '82' 273 | Host: 'localhost:4000' 274 | ContentType: [1x1 struct] 275 | Connection: 'close' 276 | UserAgent: 'Python-urllib/2.6' 277 | Content: [1x1 struct] 278 | 279 | HTTP/1.0 200 OK 280 | Date: Tue, 12 Oct 2010 09:19:05 GMT 281 | Server: Matlab Webserver 282 | X-Powered-By: Matlab7.12.0.635 (R2011a) 283 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 284 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 285 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 286 | Pragma: no-cache 287 | Connection: close 288 | Content-Length: 154 289 | Content-Type: text/html; charset=UTF-8 290 | 291 | 292 | POST /web_feval.m HTTP/1.1 293 | Accept-Encoding: identity 294 | Content-Length: 82 295 | Host: localhost:4000 296 | Content-Type: application/x-www-form-urlencoded 297 | Connection: close 298 | User-Agent: Python-urllib/2.6 299 | 300 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+8%7D 301 | Post: [1x1 struct] 302 | AcceptEncoding: 'identity' 303 | ContentLength: '82' 304 | Host: 'localhost:4000' 305 | ContentType: [1x1 struct] 306 | Connection: 'close' 307 | UserAgent: 'Python-urllib/2.6' 308 | Content: [1x1 struct] 309 | 310 | HTTP/1.0 200 OK 311 | Date: Tue, 12 Oct 2010 09:19:05 GMT 312 | Server: Matlab Webserver 313 | X-Powered-By: Matlab7.12.0.635 (R2011a) 314 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 315 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 316 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 317 | Pragma: no-cache 318 | Connection: close 319 | Content-Length: 154 320 | Content-Type: text/html; charset=UTF-8 321 | 322 | 323 | POST /web_feval.m HTTP/1.1 324 | Accept-Encoding: identity 325 | Content-Length: 82 326 | Host: localhost:4000 327 | Content-Type: application/x-www-form-urlencoded 328 | Connection: close 329 | User-Agent: Python-urllib/2.6 330 | 331 | func_path=%7E%2FSites%2Fpython-matlab-bridge%2Ftest.m&arguments=%7B%22a%22%3A+9%7D 332 | Post: [1x1 struct] 333 | AcceptEncoding: 'identity' 334 | ContentLength: '82' 335 | Host: 'localhost:4000' 336 | ContentType: [1x1 struct] 337 | Connection: 'close' 338 | UserAgent: 'Python-urllib/2.6' 339 | Content: [1x1 struct] 340 | 341 | HTTP/1.0 200 OK 342 | Date: Tue, 12 Oct 2010 09:19:05 GMT 343 | Server: Matlab Webserver 344 | X-Powered-By: Matlab7.12.0.635 (R2011a) 345 | Set-Cookie: SESSID=5322082bf473207961031e3df1f45a22; path=/ 346 | Expires: Thu, 19 Nov 1980 08:00:00 GMT 347 | Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 348 | Pragma: no-cache 349 | Connection: close 350 | Content-Length: 155 351 | Content-Type: text/html; charset=UTF-8 352 | 353 | 354 | POST /exit_server.m HTTP/1.1 355 | Accept-Encoding: identity 356 | Content-Length: 23 357 | Host: localhost:4000 358 | Content-Type: application/x-www-form-urlencoded 359 | Connection: close 360 | User-Agent: Python-urllib/2.6 361 | 362 | id=python-matlab-bridge 363 | Post: [1x1 struct] 364 | AcceptEncoding: 'identity' 365 | ContentLength: '23' 366 | Host: 'localhost:4000' 367 | ContentType: [1x1 struct] 368 | Connection: 'close' 369 | UserAgent: 'Python-urllib/2.6' 370 | Content: [1x1 struct] 371 | 372 | -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/JavaTcpServer.m: -------------------------------------------------------------------------------- 1 | function [TCP,data]=JavaTcpServer(action,TCP,data,config) 2 | global GlobalserverSocket; 3 | import java.net.Socket 4 | import java.io.* 5 | import java.net.ServerSocket 6 | timeout=1000; 7 | if(nargin<3), data=[]; end 8 | 9 | switch(action) 10 | case 'initialize' 11 | try 12 | serverSocket = ServerSocket(data); 13 | catch 14 | try 15 | GlobalserverSocket.close; 16 | serverSocket = ServerSocket(data); 17 | catch 18 | error('JavaTcpServer:initialize', ['Failed to Open Server Port. ' ... 19 | 'Reasons: "port is still open by Matlab for instance due ' ... 20 | 'to an previous crash", "Blocked by Firewall application", ' ... 21 | '"Port open in another Application", "No rights to open the port"']); 22 | end 23 | end 24 | 25 | serverSocket.setSoTimeout(timeout); 26 | TCP.port = data; 27 | TCP.serverSocket=serverSocket; 28 | GlobalserverSocket=serverSocket; 29 | TCP.stopwindow=stopwindow(); 30 | case 'accept' 31 | while(true), 32 | try socket = TCP.serverSocket.accept; break; catch, end 33 | drawnow 34 | if(~ishandle(TCP.stopwindow)), TCP.socket=-1; return, end 35 | end 36 | TCP.socket = socket; 37 | TCP.remoteHost = char(socket.getInetAddress); 38 | TCP.outputStream = socket.getOutputStream; 39 | TCP.inputStream = socket.getInputStream; 40 | case 'read' 41 | data=zeros(1,1000000,'int8'); tBytes=0; 42 | tstart=tic; 43 | while(true) 44 | nBytes = TCP.inputStream.available; 45 | partdata = zeros(1, nBytes, 'int8'); 46 | for i = 1:nBytes, partdata(i) = DataInputStream(TCP.inputStream).readByte; end 47 | data(tBytes+1:tBytes+nBytes) = partdata; 48 | tBytes=tBytes+nBytes; 49 | % Only exist if the buffer is empty and some request-data 50 | % is received, or if the time is larger then 1.5 seconds 51 | t=toc(tstart); 52 | if(isempty(partdata)&&(t>config.mtime1)&&(tBytes>0)), break; end 53 | if(isempty(partdata)&&(t>config.mtime2)), break; end 54 | end 55 | data=data(1:tBytes); 56 | case 'write' 57 | if(~isa(data,'int8')), error('TCP:input','Data must be of type int8'); end 58 | try 59 | DataOutputStream(TCP.outputStream).write(data,0,length(data)); 60 | catch 61 | end 62 | try 63 | DataOutputStream(TCP.outputStream).flush; 64 | catch 65 | end 66 | case 'close' 67 | TCP.serverSocket.close; 68 | end 69 | 70 | function handle_figure=stopwindow() 71 | handle_figure=figure; 72 | set(handle_figure,'Units','Pixels'); 73 | w=get(handle_figure,'Position'); 74 | set(handle_figure,'Position',[w(1) w(2) 200 100]); 75 | set(handle_figure,'Resize','off') 76 | uicontrol('Style', 'text','String','Close Window to Shutdown Server','Position', [0 0 200 100]); 77 | 78 | -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/header2text.m: -------------------------------------------------------------------------------- 1 | function text=header2text(header) 2 | text=''; 3 | fn=fieldnames(header); 4 | for i=1:length(fn) 5 | name=fn{i}; data=header.(name); 6 | switch name 7 | case 'HTTP' 8 | data=['HTTP/1.0 ' data]; 9 | case 'Date' 10 | data=['Date: ' data]; 11 | case 'Server' 12 | data=['Server: ' data]; 13 | case 'XPoweredBY' 14 | data=['X-Powered-By: ' data]; 15 | case 'SetCookie' 16 | data=['Set-Cookie: ' data]; 17 | case 'Expires' 18 | data=['Expires: ' data]; 19 | case 'CacheControl' 20 | data=['Cache-Control: ' data]; 21 | case 'Pragma' 22 | data=['Pragma: ' data]; 23 | case 'XPingback' 24 | data=['X-Pingback: ' data]; 25 | case 'Connection' 26 | data=['Connection: ' data]; 27 | case 'ContentLength' 28 | data=['Content-Length: ' data]; 29 | case 'ContentType' 30 | data=['Content-Type: ' data]; 31 | case 'LastModified' 32 | data=['Last-Modified: ' data]; 33 | case 'AcceptRanges'; 34 | data=['Accept-Ranges: ' data]; 35 | case 'ETag'; 36 | data=['ETag: ' data]; 37 | case'KeepAlive'; 38 | data=['Keep-Alive: ' data]; 39 | otherwise 40 | warning('header fieldname wrong'); 41 | continue; 42 | end 43 | text=[text data '\n']; 44 | end 45 | text=[text '\n']; 46 | text=sprintf(text); 47 | -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/json2mat.m: -------------------------------------------------------------------------------- 1 | function M=json2mat(J) 2 | 3 | %JSON2MAT converts a javscript data object (JSON) into a Matlab structure 4 | % using s recursive approach. J can also be a file name. 5 | % 6 | %Example: lala=json2mat('{lele:2,lili:4,lolo:[1,2,{lulu:5,bubu:[[1,2],[3,4],[5,6]]}]}') 7 | % notice lala.lolo{3}.bubu is read as a 2D matrix. 8 | % 9 | % Jonas Almeida, March 2010 10 | 11 | if exist(J)==2 % if J is a filename 12 | fid=fopen(J,'r'); 13 | J=''; 14 | while ~feof(fid) 15 | J=[J,fgetl(fid)]; 16 | end 17 | fclose(fid); 18 | M=json2mat(J); 19 | else 20 | J1=regexprep(J(1:min([5,length(J)])),'\s',''); %despaced start of J string 21 | if J1(1)=='{' %extract structures 22 | JJ=regexp(J,'\{(.*)\}','tokens'); 23 | M=extract_struct(JJ{1}{1}); 24 | elseif J1(1)=='[' %extract cells 25 | JJ=regexp(J,'\[(.*)\]','tokens'); 26 | M=extract_cell(JJ{1}{1}); 27 | elseif J1(1)=='"' %literal string 28 | JJ=regexp(J,'\"(.*)\"','tokens'); 29 | M=JJ{1}{1}; 30 | else %numeric value 31 | M=str2num(J); % is number 32 | end 33 | end 34 | 35 | function y=extract_struct(x) 36 | %detag arrays first 37 | indOC=extract_embed(x,'[',']'); 38 | n=size(indOC,1); 39 | for i=n:-1:1 40 | tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); 41 | x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; 42 | end 43 | 44 | 45 | a=regexp(x,'[^:,]+:[^,]+'); 46 | n=length(a); 47 | a=[a,length(x)+2]; 48 | for i=1:n 49 | s=x(a(i):a(i+1)-2); 50 | t=regexp(s,'([^:]+):(.+)','tokens'); 51 | %t{1}{1}(t{1}{1}==32)=[]; % remove blanks, maybe later do something fancier like replace with underscores 52 | t{1}{1}=strrep(t{1}{1},' ','_'); 53 | t{1}{1}=strrep(t{1}{1},'"',''); 54 | if t{1}{1}(1)=='_' %JSON allows for fieldnames starting with "_" 55 | t{1}{1}(1)=''; % this line will cause hard to track problems if the same object has 2 attributes with the same name but one of them starting with "_" 56 | end 57 | if regexp(t{1}{2},'tag{\d+}') 58 | y.(t{1}{1})=eval(t{1}{2}); 59 | else 60 | y.(t{1}{1})=json2mat(t{1}{2}); 61 | end 62 | %y.(t{1}{1})=json2mat(t{1}{2}); 63 | end 64 | 65 | function y=extract_cell(x) 66 | 67 | indOC=extract_embed(x,'{','}'); 68 | n=size(indOC,1); 69 | for i=n:-1:1 70 | tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); 71 | x=[x(1:indOC(i,1)-1),'tag~<',num2str(i),'>~',x(indOC(i,2)+1:end)]; 72 | end 73 | indOC=extract_embed(x,'[',']'); 74 | m=size(indOC,1); 75 | for j=m:-1:1 76 | i=n+j; 77 | tag{i}=json2mat(x(indOC(i,1):indOC(i,2))); 78 | try;tag{i}=cell2mat(tag{i});end 79 | x=[x(1:indOC(i,1)-1),'tag{',num2str(i),'}',x(indOC(i,2)+1:end)]; 80 | end 81 | x=strrep(x,'~<','{'); 82 | x=strrep(x,'>~','}'); 83 | if exist('tag') %catching numeric content 84 | if isnumeric([tag{:}]) 85 | try 86 | y=eval(['[',strrep(x,'},','};'),']']); 87 | end 88 | end 89 | end 90 | 91 | if exist('y')~=1 92 | y=eval(['{',strrep(x,'"',''''),'}']); 93 | end 94 | 95 | %look for embeded objects and arrays 96 | 97 | function y=extract_embed(x,tagOpen,tagClose) 98 | 99 | %EXTRACT_EMBED identifies embeded tagged segments 100 | %Example y=extract_embed(str,'[',']') 101 | 102 | indOpen=strfind(x,tagOpen)'; 103 | indOpen=[indOpen,ones(length(indOpen),1)]; 104 | indClose=strfind(x,tagClose)'; 105 | indClose=[indClose,-ones(length(indClose),1)]; 106 | indOpenClose=[indOpen;indClose]; 107 | [~,Ind]=sort(indOpenClose(:,1)); 108 | indOpenClose=indOpenClose(Ind,:); 109 | n=size(indOpenClose,1); 110 | for i=2:n % add one for open, take one for close 111 | indOpenClose(i,2)=indOpenClose(i-1,2)+indOpenClose(i,2); 112 | end 113 | i=0; 114 | op=0; %open 115 | while i2 % for now treat higher dimensions as linear vectors 50 | J=['[',num2str(M(:)'),']']; % and of destroying dimensionality 51 | J=regexprep(J,'\s+',','); 52 | end 53 | end 54 | else 55 | J=['"',M,'"']; % otherwise it is treated as a string 56 | end 57 | end 58 | 59 | if nargin>1 %save JSON result in file 60 | fid=fopen(F,'w'); 61 | fprintf(fid,'%s',J); 62 | fclose(fid); 63 | end -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/multipart2struct.m: -------------------------------------------------------------------------------- 1 | function subdata=multipart2struct(subrequestdata,config) 2 | request_text=char(subrequestdata); 3 | request_lines = regexp(request_text, '\n+', 'split'); 4 | request_words = regexp(request_lines, '\s+', 'split'); 5 | 6 | i=1; 7 | subdata=struct; 8 | subdata.Name=''; 9 | subdata.Filename=''; 10 | subdata.ContentType=''; 11 | subdata.ContentData=''; 12 | while(true) 13 | i=i+1; if((i>length(request_lines))||(uint8(request_lines{i}(1)==13))), break; end 14 | line=request_lines{i}; 15 | type=request_words{i}{1}; 16 | switch(type) 17 | case 'Content-Disposition:' 18 | for j=3:length(request_words{i}) 19 | line_words=regexp(request_words{i}{j}, '"', 'split'); 20 | switch(line_words{1}) 21 | case 'name=' 22 | subdata.Name=line_words{2}; 23 | case 'filename=' 24 | subdata.Filename=line_words{2}; 25 | end 26 | end 27 | case 'Content-Type:' 28 | subdata.ContentType=rmvp(line(15:end)); 29 | end 30 | end 31 | w=find(subrequestdata==10); 32 | switch(subdata.ContentType) 33 | case '' 34 | subdata.ContentData=char(subrequestdata(w(i)+1:end)); 35 | otherwise 36 | subdata.ContentData=subrequestdata(w(i)+1:end); 37 | [pathstr,name,ext] = fileparts(subdata.Filename); 38 | filename=['/' char(round(rand(1,32)*9)+48)]; 39 | fullfilename=[config.temp_folder filename ext]; 40 | fid = fopen(fullfilename,'w'); fwrite(fid,subdata.ContentData,'int8'); fclose(fid); 41 | subdata.Filename=fullfilename; 42 | end 43 | -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/rmvp.m: -------------------------------------------------------------------------------- 1 | function str=rmvp(str) 2 | while((str(end)==' ') ||(uint8(str(end))==13)), str=str(1:end-1); end -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/run_dot_m.m: -------------------------------------------------------------------------------- 1 | % Max Jaderberg 2011 2 | 3 | function result = run_dot_m( file_to_run, arguments ) 4 | %RUN_DOT_M Runs the given .m file with the argument struct given 5 | % For exmaple run_dot_m('/path/to/function.m', args); 6 | % args is a struct containing the arguments. function.m must take only 7 | % one parameter, the argument structure 8 | 9 | [dir, func_name, ext] = fileparts(file_to_run); 10 | 11 | if ~size(ext) 12 | result = 'Error: Need to give path to .m file'; 13 | return 14 | end 15 | 16 | if ~strcmp(ext, '.m') 17 | result = 'Error: Need to give path to .m file'; 18 | return 19 | end 20 | 21 | % Add function path to current path 22 | addpath(dir); 23 | if isstruct(arguments) 24 | result = feval(func_name, arguments); 25 | else 26 | result = feval(func_name); 27 | end 28 | end 29 | 30 | -------------------------------------------------------------------------------- /pymatbridge/matlab/functions/text2header.m: -------------------------------------------------------------------------------- 1 | function header = text2header(requestdata,config) 2 | request_text=char(requestdata); 3 | request_lines = regexp(request_text, '\r\n+', 'split'); 4 | request_words = regexp(request_lines, '\s+', 'split'); 5 | for i=1:length(request_lines) 6 | line=request_lines{i}; 7 | if(isempty(line)), break; end 8 | type=request_words{i}{1}; 9 | switch(lower(type)) 10 | case 'get' 11 | header.Get.Filename=request_words{i}{2}; 12 | header.Get.Protocol=request_words{i}{3}; 13 | case 'post' 14 | header.Post.Filename=request_words{i}{2}; 15 | header.Post.Protocol=request_words{i}{3}; 16 | case 'host:' 17 | header.Host=rmvp(line(7:end)); 18 | case 'user-agent:' 19 | header.UserAgent=rmvp(line(13:end)); 20 | case 'accept:' 21 | header.Accept=rmvp(line(9:end)); 22 | case 'accept-language:' 23 | header.AcceptLanguage=rmvp(line(18:end)); 24 | case 'accept-encoding:' 25 | header.AcceptEncoding=rmvp(line(18:end)); 26 | case 'accept-charset:' 27 | header.AcceptCharset=rmvp(line(17:end)); 28 | case 'keep-alive:' 29 | header.KeepAlive=rmvp(line(13:end)); 30 | case 'connection:' 31 | header.Connection=rmvp(line(13:end)); 32 | case 'content-length:' 33 | header.ContentLength=rmvp(line(17:end)); 34 | case 'content-type:' 35 | %lines=rmvp(line(15:end)); 36 | switch rmvp(request_words{i}{2}) 37 | case {'application/x-www-form-urlencoded','application/x-www-form-urlencoded;'} 38 | header.ContentType.Type='application/x-www-form-urlencoded'; 39 | header.ContentType.Boundary='&'; 40 | case {'multipart/form-data','multipart/form-data;'} 41 | header.ContentType.Type='multipart/form-data'; 42 | str=request_words{i}{3}; 43 | header.ContentType.Boundary=str(10:end); 44 | otherwise 45 | disp('unknown') 46 | end 47 | otherwise 48 | end 49 | end 50 | header.Content=struct; 51 | if(isfield(header,'ContentLength')) 52 | cl=str2double(header.ContentLength); 53 | str=request_text(end-cl+1:end); 54 | data=requestdata(end-cl+1:end); 55 | if(~isfield(header,'ContentType')) 56 | header.ContentType.Type=''; header.ContentType.Boundary='&'; 57 | end 58 | switch (header.ContentType.Type) 59 | case {'application/x-www-form-urlencoded',''} 60 | str=rmvp(str); 61 | words = regexp(str, '&', 'split'); 62 | for i=1:length(words) 63 | words2 = regexp(words{i}, '=', 'split'); 64 | header.Content.(words2{1})=words2{2}; 65 | end 66 | case 'multipart/form-data' 67 | pos=strfind(str,header.ContentType.Boundary); 68 | while((pos(1)>1)&&(str(pos(1)-1)=='-')) 69 | header.ContentType.Boundary=['-' header.ContentType.Boundary]; 70 | pos=strfind(str,header.ContentType.Boundary); 71 | end 72 | 73 | for i=1:(length(pos)-1) 74 | pstart=pos(i)+length(header.ContentType.Boundary); 75 | pend=pos(i+1)-3; % Remove "13 10" End-line characters 76 | subrequestdata=data(pstart:pend); 77 | subdata= multipart2struct(subrequestdata,config); 78 | header.Content.(subdata.Name).Filename=subdata.Filename; 79 | header.Content.(subdata.Name).ContentType=subdata.ContentType; 80 | header.Content.(subdata.Name).ContentData=subdata.ContentData; 81 | end 82 | otherwise 83 | disp('unknown') 84 | end 85 | end -------------------------------------------------------------------------------- /pymatbridge/matlab/startup.m: -------------------------------------------------------------------------------- 1 | % executed when matlab starts up -------------------------------------------------------------------------------- /pymatbridge/matlab/test_functions/test_sum.m: -------------------------------------------------------------------------------- 1 | function result = test_sum(args) 2 | result = args.echo; 3 | end -------------------------------------------------------------------------------- /pymatbridge/matlab/webserver.m: -------------------------------------------------------------------------------- 1 | function webserver(port,config) 2 | % RUN javaaddpath('mongo-2.7.2.jar') 3 | % This function WEBSERVER, is a HTTP webserver for HTML code and images 4 | % and also allows execution of Matlab code through the web. 5 | % 6 | % webserver(port) 7 | % 8 | % or 9 | % 10 | % webserver(port,config) 11 | % 12 | % port : A port nummer for instance 4000 13 | % (optional) 14 | % config : A struct with config options 15 | % config.www_folder : Folder with all html and other files, 'www'; 16 | % config.temp_folder : Folder to temporary store uploaded files, (default) 'www/temp'; 17 | % config.verbose : Display debug information, (default) true; 18 | % config.defaultfile : If no file aksed display home page, (default) '/index.html'; 19 | % 20 | % Supports 21 | % - HTML and images 22 | % - Sub-Folders 23 | % - Upload files 24 | % - M file execution 25 | % 26 | % Example, 27 | % webserver(4000); 28 | % % Use firefox or internet explorer and visit http://localhost:4000/ 29 | % 30 | % Exampe 2, 31 | % webserver(4000,struct('verbose',false)) 32 | % 33 | % Function is written by D.Kroon University of Twente (November 2010) 34 | 35 | % Config of the HTTP server 36 | close all; 37 | 38 | defaultoptions=struct('www_folder','www','temp_folder','www/temp','verbose',true,'defaultfile','/index.html','mtime1',0.8,'mtime2',3); 39 | 40 | if(~exist('config','var')), config=defaultoptions; 41 | else 42 | tags = fieldnames(defaultoptions); 43 | for i=1:length(tags), 44 | if(~isfield(config,tags{i})), config.(tags{i})=defaultoptions.(tags{i}); end 45 | end 46 | if(length(tags)~=length(fieldnames(config))), 47 | warning('image_registration:unknownoption','unknown options found'); 48 | end 49 | end 50 | 51 | 52 | % Use Default Server Port, if user input not available 53 | if(nargin<1), port=4000; end 54 | 55 | % Add sub-functions to Matlab Search Path 56 | add_function_paths(); 57 | 58 | % Open a TCP Server Port 59 | TCP=JavaTcpServer('initialize',[],port,config); 60 | 61 | if(config.verbose) 62 | disp(['Webserver Available on http://localhost:' num2str(port) '/']); 63 | end 64 | 65 | while(true) 66 | % Wait for connections of browsers 67 | TCP=JavaTcpServer('accept',TCP,[],config); 68 | 69 | % If socket is -1, the user has close the "Close Window" 70 | if(TCP.socket==-1), break, end 71 | 72 | % Read the data form the browser as an byte array of type int8 73 | 74 | [TCP,requestdata]=JavaTcpServer('read',TCP,[],config); 75 | if(isempty(requestdata)) 76 | continue; 77 | end 78 | 79 | if(config.verbose), disp(char(requestdata(1:min(1000,end)))); end 80 | 81 | % Convert the Header text to a struct 82 | request = text2header(requestdata,config); 83 | if(config.verbose), disp(request); end 84 | 85 | % The filename asked by the browser 86 | if(isfield(request,'Get')) 87 | filename=request.Get.Filename; 88 | elseif(isfield(request,'Post')) 89 | filename=request.Post.Filename; 90 | else 91 | warning('Unknown Type of Request'); 92 | continue 93 | end 94 | 95 | % If no filename, use default 96 | if(strcmp(filename,'/')), filename=config.defaultfile; end 97 | 98 | % Make the full filename inluding path 99 | fullfilename=[config.www_folder filename]; 100 | [pathstr,name,ext] = fileparts(fullfilename); 101 | 102 | % Check if file asked by the browser can be opened 103 | fid = fopen(fullfilename, 'r'); 104 | if(fid<0) 105 | filename='/404.html'; found=false; 106 | fullfilename=[config.www_folder filename]; 107 | else 108 | found=true; fclose(fid); 109 | end 110 | 111 | % Based on the extention asked, read a local file and parse it. 112 | % or execute matlab code, which generates the file 113 | switch(ext) 114 | case {'.m'} 115 | addpath(pathstr) 116 | fhandle = str2func(name); 117 | try 118 | html=feval(fhandle,request,config); 119 | catch ME 120 | html=['Error in file : ' name ... 121 | '.m

The file returned the following error:
' ... 122 | ME.message '
']; 123 | fprintf(ME.message); 124 | end 125 | rmpath(pathstr) 126 | header=make_html_http_header(html,found); 127 | response=header2text(header); 128 | case {'.html','.htm'} 129 | fid = fopen(fullfilename, 'r'); 130 | html = fread(fid, inf, 'int8')'; 131 | fclose(fid); 132 | header=make_html_http_header(html,found); 133 | response=header2text(header); 134 | case {'.jpg','.png','.gif','.ico'} 135 | fid = fopen(fullfilename, 'r'); 136 | html = fread(fid, inf, 'int8')'; 137 | fclose(fid); 138 | header=make_image_http_header(html,found); 139 | response=header2text(header); 140 | otherwise 141 | fid = fopen(fullfilename, 'r'); 142 | html = fread(fid, inf, 'int8')'; 143 | fclose(fid); 144 | header=make_bin_http_header(html,found); 145 | response=header2text(header); 146 | end 147 | 148 | if(config.verbose), disp(char(response)); end 149 | 150 | % Give the generated HTML or binary code back to the browser 151 | JavaTcpServer('write',TCP,int8(response),config); 152 | JavaTcpServer('write',TCP,int8(html),config); 153 | end 154 | JavaTcpServer('close',TCP); 155 | 156 | 157 | function add_function_paths() 158 | try 159 | functionname='webserver.m'; 160 | functiondir=which(functionname); 161 | functiondir=functiondir(1:end-length(functionname)); 162 | addpath([functiondir '/functions']) 163 | catch me 164 | disp(me.message); 165 | end 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /pymatbridge/matlab/www/exit_server.m: -------------------------------------------------------------------------------- 1 | function json_response = exit_server(headers, config) 2 | exit; 3 | json_response = '{}'; -------------------------------------------------------------------------------- /pymatbridge/matlab/www/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Python-MATLAB Bridge Server 6 | 7 | 8 |

The Python-MATLAB Bridge Server is running...

9 | 10 | -------------------------------------------------------------------------------- /pymatbridge/matlab/www/test_connect.m: -------------------------------------------------------------------------------- 1 | function json_response = test_connect(headers, config) 2 | c = clock; 3 | response.message = sprintf('Matlab: %s connected!', headers.Content.id); 4 | response.time = sprintf('%d:%d', c(4), c(5)); 5 | json_response = mat2json(response); -------------------------------------------------------------------------------- /pymatbridge/matlab/www/web_feval.m: -------------------------------------------------------------------------------- 1 | % Max Jaderberg 2011 2 | 3 | function json_response = web_feval(headers, config) 4 | %WEB_FEVAL Returns a json object of the result of calling the funciton 5 | % This allows you to run any local matlab file. To be used with webserver.m. 6 | % HTTP POST to /web_feval.m with the following parameters: 7 | % func_path: a string which is the path to the .m file you want to 8 | % call 9 | % arguments: a json string of the arguments structure to pass to the 10 | % function you are calling 11 | % 12 | % Returns a json object containing the result 13 | 14 | response.success = 'false'; 15 | field_names = fieldnames(headers.Content); 16 | 17 | % URL decode the POST data 18 | for i=1:numel(field_names) 19 | headers.Content.(field_names{i}) = urldecode(headers.Content.(field_names{i})); 20 | end 21 | 22 | response.content = ''; 23 | 24 | func_path_check = false; 25 | arguments_check = false; 26 | if size(field_names) 27 | if isfield(headers.Content, 'func_path') 28 | func_path_check = true; 29 | end 30 | if isfield(headers.Content, 'arguments') 31 | arguments_check = true; 32 | end 33 | end 34 | 35 | if ~func_path_check 36 | response.message = 'No function given as func_path POST parameter'; 37 | json_response = mat2json(response); 38 | return 39 | end 40 | 41 | func_path = headers.Content.func_path; 42 | 43 | if arguments_check 44 | arguments = json2mat(headers.Content.arguments); 45 | else 46 | arguments = ''; 47 | end 48 | 49 | response.result = run_dot_m(func_path, arguments); 50 | response.success = 'true'; 51 | response.message = 'Successfully completed request'; 52 | 53 | response.content.func_path = func_path; 54 | response.content.arguments = arguments; 55 | 56 | json_response = mat2json(response); 57 | 58 | return 59 | 60 | 61 | 62 | end 63 | 64 | -------------------------------------------------------------------------------- /test.m: -------------------------------------------------------------------------------- 1 | function res = test(args) 2 | res = args.a + 1; -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | from pymatbridge import Matlab 2 | 3 | # Initialise MATLAB 4 | mlab = Matlab(port=4000) 5 | # Start the server 6 | mlab.start() 7 | # Run a test function: just adds 1 to the argument a 8 | for i in range(10): 9 | print mlab.run('~/Sites/python-matlab-bridge/test.m', {'a': i})['result'] 10 | # Stop the MATLAB server 11 | mlab.stop() --------------------------------------------------------------------------------