Skip to content

Instantly share code, notes, and snippets.

@tomkralidis
Last active November 30, 2021 16:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomkralidis/9adbd4864c03647aa7eb4f96a3c33297 to your computer and use it in GitHub Desktop.
Save tomkralidis/9adbd4864c03647aa7eb4f96a3c33297 to your computer and use it in GitHub Desktop.
Python MapScript via WSGI example

Overview

Simple example of MapServer MapScript Python via WSGI testing

Environment

  • MapServer 6.4.2
  • Ubuntu 14.04

Running

python ./mapscript-wsgi.py
# open "http://localhost:8000/?service=WMS&version=1.3.0&request=GetCapabilities"
# open "http://localhost:8000/?service=WMS&version=1.1.1&request=GetMap&layers=CURRENT_CONDITIONS&srs=EPSG:4326&bbox=-180,-90,180,90&format=image/png&width=500&height=300"
WSGIDaemonProcess foo processes=10 threads=1
Alias /ms-wsgi /tmp/foo/mapscript-wsgi.py
<Directory "/tmp/foo">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AddHandler wsgi-script .py
Order Allow,Deny
Allow from all
</Directory>
import os
import sys
import mapscript
# List of all environment variable used by MapServer
MAPSERV_ENV = [
'CONTENT_LENGTH', 'CONTENT_TYPE', 'CURL_CA_BUNDLE', 'HTTP_COOKIE',
'HTTP_HOST', 'HTTPS', 'HTTP_X_FORWARDED_HOST', 'HTTP_X_FORWARDED_PORT',
'HTTP_X_FORWARDED_PROTO', 'MS_DEBUGLEVEL', 'MS_ENCRYPTION_KEY',
'MS_ERRORFILE', 'MS_MAPFILE', 'MS_MAPFILE_PATTERN', 'MS_MAP_NO_PATH',
'MS_MAP_PATTERN', 'MS_MODE', 'MS_OPENLAYERS_JS_URL', 'MS_TEMPPATH',
'MS_XMLMAPFILE_XSLT', 'PROJ_LIB', 'QUERY_STRING', 'REMOTE_ADDR',
'REQUEST_METHOD', 'SCRIPT_NAME', 'SERVER_NAME', 'SERVER_PORT'
]
def application(env, start_response):
for key in MAPSERV_ENV:
if key in env:
os.environ[key] = env[key]
else:
os.unsetenv(key)
mapfile = '/tmp/foo.map'
mapfile = mapscript.mapObj(mapfile)
request = mapscript.OWSRequest()
mapscript.msIO_installStdoutToBuffer()
request.loadParamsFromURL(env['QUERY_STRING'])
try:
status = mapfile.OWSDispatch(request)
except Exception as err:
pass
content_type = mapscript.msIO_stripStdoutBufferContentType()
result = mapscript.msIO_getStdoutBufferBytes()
start_response('200 OK', [('Content-type', content_type)])
return [result]
if __name__ == '__main__': # run inline using WSGI reference implementation
from wsgiref.simple_server import make_server
port = 8001
if len(sys.argv) > 1:
port = int(sys.argv[1])
httpd = make_server('', port, application)
print('Serving on port %d...' % port)
httpd.serve_forever()
@jmckenna
Copy link

jmckenna commented Jul 21, 2016

Notes on my testing of this, for future readers:

  • Python 2.x users may receive an error regarding the header, such as:
AssertionError: Header values must be string
  • reason is that Python2 does not handle the header correctly (Python3 does handle it nicely). You can force the content-type to bytes, for Python2, by changing line#40 to:
start_response('200 OK', [('Content-type', 'application/octet-stream')])
  • For Windows users of Python, <unsetenv> is not available on Windows, so you can remove the <else> statement (on lines 23-24)

@tomkralidis
Copy link
Author

Thanks @jmckenna. To add, if you ave using MapServer 7.0.4 or below this patch is required.

@jmckenna
Copy link

Still a useful script! (tested with Python 3.10.0, mod_wsgi 4.9.0, Python MapScript 8.0-dev, in MS4W 5.0-dev) Thanks again!

@jmckenna
Copy link

Actually it's so useful that it will be distributed in MS4W 5.0, why not, saves me coming back here to find it each release to test with ha! thanks again.

@tomkralidis
Copy link
Author

Glad you found this useful @jmckenna! And great to see in MS4W moving forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment