Skip to content
Commits on Source (7)
environment:
matrix:
# Pre-installed Python versions, which Appveyor may upgrade to
# a later point release.
# See: http://www.appveyor.com/docs/installed-software#python
- PYTHON_VERSION: 2.7
MINICONDA: C:\Miniconda
PYTHON_ARCH: "32"
# - PYTHON_VERSION: 3.4
# MINICONDA: C:\Miniconda3
# PYTHON_ARCH: "32"
# - PYTHON_VERSION: 3.5
# MINICONDA: C:\Miniconda35
# PYTHON_ARCH: "32"
# - PYTHON_VERSION: 3.6
# MINICONDA: C:\Miniconda36
# PYTHON_ARCH: "32"
# - PYTHON_VERSION: 2.7
# MINICONDA: C:\Miniconda-x64
# PYTHON_ARCH: "64"
# - PYTHON_VERSION: 3.4
# MINICONDA: C:\Miniconda3-x64
# PYTHON_ARCH: "64"
# - PYTHON_VERSION: 3.5
# MINICONDA: C:\Miniconda35-x64
# PYTHON_ARCH: "64"
- PYTHON_VERSION: 3.6
MINICONDA: C:\Miniconda36-x64
PYTHON_ARCH: "64"
# - PYTHON: "C:\\Python27"
# PYTHON_VERSION: "2.7.x"
# PYTHON_ARCH: "32"
# - PYTHON: "C:\\Python27-x64"
# PYTHON_VERSION: "2.7.x"
# PYTHON_ARCH: "64"
# - PYTHON: "C:\\Python34"
# PYTHON_VERSION: "3.4.x"
# PYTHON_ARCH: "32"
# - PYTHON: "C:\\Python34-x64"
# PYTHON_VERSION: "3.4.x"
# PYTHON_ARCH: "64"
# - PYTHON: "C:\\Python35"
# PYTHON_VERSION: "3.5.x"
# PYTHON_ARCH: "32"
# - PYTHON: "C:\\Python35-x64"
# PYTHON_VERSION: "3.5.x"
# PYTHON_ARCH: "64"
# - PYTHON: "C:\\Python36"
# PYTHON_VERSION: "3.6.x"
# PYTHON_ARCH: "32"
# - PYTHON: "C:\\Python36-x64"
# PYTHON_VERSION: "3.6.x"
# PYTHON_ARCH: "64"
install:
- "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%PATH%"
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda info -a
- conda config --add channels conda-forge
# If there is a newer build queued for the same PR, cancel this one.
# The AppVeyor 'rollout builds' option is supposed to serve the same
# purpose but it is problematic because it tends to cancel builds pushed
# directly to master instead of just PR builds (or the converse).
# credits: JuliaLang developers.
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- ECHO "Installed SDKs:"
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
- "conda create -q -n test-environment python=%PYTHON_VERSION%"
- activate test-environment
- conda install Shapely Pillow pyproj lxml fiona pyyaml
- pip install -r requirements-appveyor.txt"
build_script:
# Build the compiled extension
- python setup.py build"
test_script:
# Run the project tests
- pytest mapproxy"
after_test:
# If tests are successful, create binary packages for the project.
- python setup.py bdist_wheel"
- python setup.py bdist_wininst"
- python setup.py bdist_msi"
- ps: "ls dist"
artifacts:
# Archive the generated packages in the ci.appveyor.com build report.
- path: dist\*
#on_success:
# - TODO: upload the content of dist/*.whl to a public wheelhouse
#
......@@ -2,23 +2,24 @@ language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
services:
- couchdb
- riak
- redis-server
addons:
apt:
sources:
- sourceline: 'deb https://packagecloud.io/basho/riak/ubuntu/ xenial main'
key_url: 'https://packagecloud.io/basho/riak/gpgkey'
packages:
- libproj0
- proj-bin
- libgeos-dev
- libgdal-dev
- libgdal1h
- libxslt1-dev
- libxml2-dev
- build-essential
......@@ -28,11 +29,13 @@ addons:
- libfreetype6-dev
- protobuf-compiler
- libprotoc-dev
- riak
env:
global:
- MAPPROXY_TEST_COUCHDB=http://127.0.0.1:5984
- MAPPROXY_TEST_REDIS=127.0.0.1:6379
- MAPPROXY_TEST_RIAK_HTTP=http://localhost:8098
- MAPPROXY_TEST_RIAK_PBC=pbc://localhost:8087
......@@ -41,11 +44,11 @@ env:
- BOTO_CONFIG=/doesnotexist
matrix:
# Test 2.7 and 3.6 also with latest Pillow version
include:
# Test 2.7 and 3.7 also with latest Pillow version
- python: "2.7"
env: USE_LATEST_PILLOW=1
- python: "3.6"
- python: "3.7"
env: USE_LATEST_PILLOW=1
cache:
......@@ -53,11 +56,12 @@ cache:
- $HOME/.cache/pip
before_install:
- echo -n "ulimit -n 4096" | sudo tee /etc/default/riak && sudo service riak restart # default open file limit is too low for riak
- "sudo systemctl start riak"
install:
- "pip install -r requirements-tests.txt"
- "if [[ $USE_LATEST_PILLOW = '1' ]]; then pip install -U Pillow; fi"
- "pip freeze"
script: nosetests mapproxy
script:
- pytest mapproxy
1.12.0 2019-08-30
~~~~~~~~~~~~~~~~~
Improvements:
- Cache: Rescale tiles existing tiles with new upscale_tiles/downscale_tiles option.
- Cache: Finer control for reprojection sources with preferred_src_proj option.
- WMS: Add georeference to TIFF images (GeoTIFF).
- WMS: Support for compressed TIFF images (LZW/JPEG).
- WMS: Advertise MaxWidth/MaxHeight.
- WMTS: Support for FeatureInfo requests.
- WMS/ArcGIS: Add on_error handler (similar to on_error handling for tile sources).
- WMS/WMTS: Add keyword_list to capabilities.
- S3: Support for custom S3 server and ACL.
- autoconfig: Support for username/password in URL.
Fixes:
- Various fixes for Python 3.6 and 3.7 compatibility.
- Set explicit permissions for write_atomic on Windows.
Other:
- WMS: Respond with highest supported WMS version (1.3.0 by default).
- Test: Now uses pytest instead of nosetest for all unit and system tests.
- YAML: Always use load_safe to support PyYAML >3 without warnings.
- Paster and eventlet specific code removed.
1.11.1 2019-08-06
~~~~~~~~~~~~~~~~~
Fixes:
- Fix Cross Site Scripting (XSS) issue in demo service. Fix for #322 did not
properly escaped input used in JavaScript examples.
properly escaped input used in JavaScript examples. Found by Janek Vind.
A targeted attack could be used for information disclosure. For
example: Session cookies of a third party application running on
the same domain.
1.11.0 2017-11-20
~~~~~~~~~~~~~~~~~
......
mapproxy (1.12.0-1~exp1) experimental; urgency=medium
* New upstream release.
* Update build dependencies for pytest instead of nose.
* Drop patches applied upstream, refresh remaining patch.
* Remove obsolete environment variable for tests.
-- Bas Couwenberg <sebastic@debian.org> Fri, 30 Aug 2019 13:24:50 +0200
mapproxy (1.11.1-2) unstable; urgency=medium
* Add upstream patch to fix WMS Capabilties with Python 3.7.
......
......@@ -8,9 +8,9 @@ Build-Depends: debhelper (>= 9),
libgdal-dev,
python3-all,
python3-lxml,
python3-nose,
python3-pil,
python3-pkg-resources,
python3-pytest,
python3-redis,
python3-requests,
python3-setuptools,
......
Description: wms: fix capabilities on Windows for Python >=3.6.7
Tempita does not correctly parses function signature on Windows with
recent Python versions. Likely introduced with changes in Python
tokenizer package with 3.6.7.. Use keyword arg as workaround.
Author: Oliver Tonnhofer <olt@bogosoft.com>
Origin: https://github.com/mapproxy/mapproxy/commit/81c84d47bbc77da324c36ca718fbca7dde1c1c66
--- a/mapproxy/service/templates/wms100capabilities.xml
+++ b/mapproxy/service/templates/wms100capabilities.xml
@@ -66,7 +66,7 @@
</Format>
</Exception>
-{{def layer_capabilities(layer, with_srs)}}
+{{def layer_capabilities(layer, with_srs=False)}}
<Layer{{if layer.queryable}} queryable="1"{{endif}}>
{{if layer.name}}
<Name>{{ layer.name }}</Name>
--- a/mapproxy/service/templates/wms110capabilities.xml
+++ b/mapproxy/service/templates/wms110capabilities.xml
@@ -101,7 +101,7 @@
</VendorSpecificCapabilities>
{{endif}}
-{{def layer_capabilities(layer, with_srs)}}
+{{def layer_capabilities(layer, with_srs=False)}}
<Layer{{if layer.queryable}} queryable="1"{{endif}}>
{{if layer.name}}
<Name>{{ layer.name }}</Name>
--- a/mapproxy/service/templates/wms111capabilities.xml
+++ b/mapproxy/service/templates/wms111capabilities.xml
@@ -113,7 +113,7 @@
</VendorSpecificCapabilities>
{{endif}}
-{{def layer_capabilities(layer, with_srs)}}
+{{def layer_capabilities(layer, with_srs=False)}}
<Layer{{if layer.queryable}} queryable="1"{{endif}}>
{{if layer.name}}
<Name>{{ layer.name }}</Name>
--- a/mapproxy/service/templates/wms130capabilities.xml
+++ b/mapproxy/service/templates/wms130capabilities.xml
@@ -196,7 +196,7 @@
{{endif}}
</inspire_vs:ExtendedCapabilities>
{{endif}}
-{{def layer_capabilities(layer, with_srs)}}
+{{def layer_capabilities(layer, with_srs=False)}}
{{py: md = bunch(default='', **layer.md)}}
<Layer{{if layer.queryable}} queryable="1"{{endif}}>
......@@ -8,7 +8,7 @@ Forwarded: not-needed
--- a/setup.cfg
+++ b/setup.cfg
@@ -6,7 +6,7 @@ with-doctest = 1
@@ -6,7 +6,7 @@ testpaths = mapproxy
[egg_info]
#tag_build = .dev
......@@ -16,6 +16,4 @@ Forwarded: not-needed
+tag_date = false
[bdist_wheel]
-universal=1
\ No newline at end of file
+universal=1
universal=1
Description: Disable tests that require network.
Author: Bas Couwenberg <sebastic@debian.org>
Forwarded: not-needed
--- a/mapproxy/test/system/test_util_wms_capabilities.py
+++ b/mapproxy/test/system/test_util_wms_capabilities.py
@@ -16,6 +16,7 @@
import os
from nose.tools import assert_raises
+from nose.plugins.skip import SkipTest
from mapproxy.client.http import HTTPClient
from mapproxy.script.wms_capabilities import wms_capabilities_command
@@ -35,6 +36,9 @@ class TestUtilWMSCapabilities(object):
self.args = ['command_dummy', '--host', TESTSERVER_URL + '/service']
def test_http_error(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.args = ['command_dummy', '--host', 'http://foo.doesnotexist']
with capture() as (out,err):
assert_raises(SystemExit, wms_capabilities_command, self.args)
@@ -46,6 +50,9 @@ class TestUtilWMSCapabilities(object):
assert err.getvalue().startswith("ERROR:")
def test_request_not_parsable(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/service?request=GetCapabilities&version=1.1.1&service=WMS', 'method': 'GET'},
{'status': '200', 'body': ''})]):
with capture() as (out,err):
@@ -54,6 +61,9 @@ class TestUtilWMSCapabilities(object):
assert error_msg.startswith('Could not parse the document')
def test_service_exception(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.args = ['command_dummy', '--host', TESTSERVER_URL + '/service?request=GetCapabilities']
with open(SERVICE_EXCEPTION_FILE, 'rb') as fp:
capabilities_doc = fp.read()
@@ -65,6 +75,9 @@ class TestUtilWMSCapabilities(object):
assert 'Not a capabilities document' in error_msg
def test_parse_capabilities(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.args = ['command_dummy', '--host', TESTSERVER_URL + '/service?request=GetCapabilities', '--version', '1.1.1']
with open(CAPABILITIES111_FILE, 'rb') as fp:
capabilities_doc = fp.read()
@@ -76,6 +89,9 @@ class TestUtilWMSCapabilities(object):
assert lines[1].startswith('Capabilities Document Version 1.1.1')
def test_parse_130capabilities(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.args = ['command_dummy', '--host', TESTSERVER_URL + '/service?request=GetCapabilities', '--version', '1.3.0']
with open(CAPABILITIES130_FILE, 'rb') as fp:
capabilities_doc = fp.read()
@@ -87,6 +103,9 @@ class TestUtilWMSCapabilities(object):
assert lines[1].startswith('Capabilities Document Version 1.3.0')
def test_key_error(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.args = ['command_dummy', '--host', TESTSERVER_URL + '/service?request=GetCapabilities']
with open(CAPABILITIES111_FILE, 'rb') as fp:
capabilities_doc = fp.read()
--- a/mapproxy/test/unit/test_cache.py
+++ b/mapproxy/test/unit/test_cache.py
@@ -55,6 +55,7 @@ from mapproxy.test.http import assert_qu
from collections import defaultdict
from nose.tools import eq_, raises, assert_not_equal, assert_raises
+from nose.plugins.skip import SkipTest
TEST_SERVER_ADDRESS = ('127.0.0.1', 56413)
GLOBAL_GEOGRAPHIC_EXTENT = MapExtent((-180, -90, 180, 90), SRS(4326))
@@ -743,6 +744,9 @@ class TestWMSSourceWithClient(object):
self.source = WMSSource(self.client)
def test_get_map(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
with tmp_image((512, 512)) as img:
expected_req = ({'path': r'/service?LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng'
'&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326&styles='
@@ -756,6 +760,9 @@ class TestWMSSourceWithClient(object):
assert is_png(result.as_buffer(seekable=True))
eq_(result.as_image().size, (512, 512))
def test_get_map_non_image_content_type(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
with tmp_image((512, 512)) as img:
expected_req = ({'path': r'/service?LAYERS=foo&SERVICE=WMS&FORMAT=image%2Fpng'
'&REQUEST=GetMap&HEIGHT=512&SRS=EPSG%3A4326&styles='
@@ -770,6 +777,9 @@ class TestWMSSourceWithClient(object):
else:
assert False, 'no SourceError raised'
def test_basic_auth(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
http_client = HTTPClient(self.req_template.url, username='foo', password='bar@')
self.client.http_client = http_client
def assert_auth(req_handler):
@@ -935,4 +945,4 @@ class TestNeastedConditionalLayers(objec
assert self.l4326.requested
def test_resolution_low_projected(self):
self.layer.get_map(MapQuery((0, 0, 10000, 10000), (100, 100), SRS(31467)))
- assert self.l900913.requested
\ No newline at end of file
+ assert self.l900913.requested
--- a/mapproxy/test/unit/test_client.py
+++ b/mapproxy/test/unit/test_client.py
@@ -42,11 +42,17 @@ class TestHTTPClient(object):
self.client = HTTPClient()
def test_post(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/service?foo=bar', 'method': 'POST'},
{'status': '200', 'body': b''})]):
self.client.open(TESTSERVER_URL + '/service', data=b"foo=bar")
def test_internal_error_response(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
try:
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/'},
{'status': '500', 'body': b''})]):
@@ -56,6 +62,9 @@ class TestHTTPClient(object):
else:
assert False, 'expected HTTPClientError'
def test_invalid_url_type(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
try:
self.client.open('htp://example.org')
except HTTPClientError as e:
@@ -63,6 +72,9 @@ class TestHTTPClient(object):
else:
assert False, 'expected HTTPClientError'
def test_invalid_url(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
try:
self.client.open('this is not a url')
except HTTPClientError as e:
@@ -70,6 +82,9 @@ class TestHTTPClient(object):
else:
assert False, 'expected HTTPClientError'
def test_unknown_host(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
try:
self.client.open('http://thishostshouldnotexist000136really42.org')
except HTTPClientError as e:
@@ -77,6 +92,9 @@ class TestHTTPClient(object):
else:
assert False, 'expected HTTPClientError'
def test_no_connect(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
try:
self.client.open('http://localhost:53871')
except HTTPClientError as e:
@@ -86,6 +104,9 @@ class TestHTTPClient(object):
@attr('online')
def test_https_untrusted_root(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
if not supports_ssl_default_context:
# old python versions require ssl_ca_certs
raise SkipTest()
@@ -97,12 +118,18 @@ class TestHTTPClient(object):
@attr('online')
def test_https_insecure(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
self.client = HTTPClient(
'https://untrusted-root.badssl.com/', insecure=True)
self.client.open('https://untrusted-root.badssl.com/')
@attr('online')
def test_https_valid_ca_cert_file(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
# verify with fixed ca_certs file
cert_file = '/etc/ssl/certs/ca-certificates.crt'
if os.path.exists(cert_file):
@@ -117,6 +144,9 @@ class TestHTTPClient(object):
@attr('online')
def test_https_valid_default_cert(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
# modern python should verify by default
if not supports_ssl_default_context:
raise SkipTest()
@@ -125,6 +155,9 @@ class TestHTTPClient(object):
@attr('online')
def test_https_invalid_cert(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
# load 'wrong' root cert
with TempFile() as tmp:
with open(tmp, 'wb') as f:
@@ -137,6 +170,9 @@ class TestHTTPClient(object):
assert_re(e.args[0], r'Could not verify connection to URL')
def test_timeouts(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
test_req = ({'path': '/', 'req_assert_function': lambda x: time.sleep(0.9) or True},
{'body': b'nothing'})
@@ -240,6 +276,9 @@ class TestTMSClient(object):
def setup(self):
self.client = TMSClient(TESTSERVER_URL)
def test_get_tile(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/9/5/13.png'},
{'body': b'tile', 'headers': {'content-type': 'image/png'}})]):
resp = self.client.get_tile((5, 13, 9)).source.read()
@@ -247,6 +286,9 @@ class TestTMSClient(object):
class TestTileClient(object):
def test_tc_path(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
template = TileURLTemplate(TESTSERVER_URL + '/%(tc_path)s.png')
client = TileClient(template)
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/09/000/000/005/000/000/013.png'},
@@ -256,6 +298,9 @@ class TestTileClient(object):
eq_(resp, b'tile')
def test_quadkey(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
template = TileURLTemplate(TESTSERVER_URL + '/key=%(quadkey)s&format=%(format)s')
client = TileClient(template)
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/key=000002303&format=png'},
@@ -264,6 +309,9 @@ class TestTileClient(object):
resp = client.get_tile((5, 13, 9)).source.read()
eq_(resp, b'tile')
def test_xyz(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
template = TileURLTemplate(TESTSERVER_URL + '/x=%(x)s&y=%(y)s&z=%(z)s&format=%(format)s')
client = TileClient(template)
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/x=5&y=13&z=9&format=png'},
@@ -273,6 +321,9 @@ class TestTileClient(object):
eq_(resp, b'tile')
def test_arcgiscache_path(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
template = TileURLTemplate(TESTSERVER_URL + '/%(arcgiscache_path)s.png')
client = TileClient(template)
with mock_httpd(TESTSERVER_ADDRESS, [({'path': '/L09/R0000000d/C00000005.png'},
@@ -282,6 +333,9 @@ class TestTileClient(object):
eq_(resp, b'tile')
def test_bbox(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
grid = tile_grid(4326)
template = TileURLTemplate(TESTSERVER_URL + '/service?BBOX=%(bbox)s')
client = TileClient(template, grid=grid)
--- a/mapproxy/test/unit/test_tiled_source.py
+++ b/mapproxy/test/unit/test_tiled_source.py
@@ -14,6 +14,8 @@
# limitations under the License.
+import os
+
from mapproxy.client.tile import TMSClient
from mapproxy.grid import TileGrid
from mapproxy.srs import SRS
@@ -23,6 +25,7 @@ from mapproxy.layer import MapQuery
from mapproxy.test.http import mock_httpd
from nose.tools import eq_
+from nose.plugins.skip import SkipTest
TEST_SERVER_ADDRESS = ('127.0.0.1', 56413)
TESTSERVER_URL = 'http://%s:%d' % TEST_SERVER_ADDRESS
@@ -33,6 +36,9 @@ class TestTileClientOnError(object):
self.client = TMSClient(TESTSERVER_URL)
def test_cacheable_response(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
error_handler = HTTPSourceErrorHandler()
error_handler.add_handler(500, (255, 0, 0), cacheable=True)
self.source = TiledSource(self.grid, self.client, error_handler=error_handler)
@@ -44,6 +50,9 @@ class TestTileClientOnError(object):
eq_(resp.as_image().getcolors(), [((256*256), (255, 0, 0))])
def test_image_response(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
error_handler = HTTPSourceErrorHandler()
error_handler.add_handler(500, (255, 0, 0), cacheable=False)
self.source = TiledSource(self.grid, self.client, error_handler=error_handler)
@@ -55,6 +64,9 @@ class TestTileClientOnError(object):
eq_(resp.as_image().getcolors(), [((256*256), (255, 0, 0))])
def test_multiple_image_responses(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
error_handler = HTTPSourceErrorHandler()
error_handler.add_handler(500, (255, 0, 0), cacheable=False)
error_handler.add_handler(204, (255, 0, 127, 200), cacheable=True)
--- a/mapproxy/test/system/test_seed.py
+++ b/mapproxy/test/system/test_seed.py
@@ -31,6 +31,7 @@ from mapproxy.test.http import mock_http
from mapproxy.test.image import tmp_image, create_tmp_image_buf, create_tmp_image
from nose.tools import eq_
+from nose.plugins.skip import SkipTest
FIXTURE_DIR = os.path.join(os.path.dirname(__file__), 'fixture')
@@ -356,6 +357,9 @@ class TestConcurrentRequestsSeed(SeedTes
empty_ogrdata = 'empty_ogrdata.geojson'
def test_timeout(self):
+ if 'OFFLINE_TESTS' in os.environ:
+ raise SkipTest
+
# test concurrent seeding where seed concurrency is higher than the permitted
# concurrent_request value of the source and a lock times out
This diff is collapsed.
offline-tests.patch
disable-tag_date.patch
skip-tests-for-missing-files.patch
python3.7-async.patch
spelling-errors.patch
0001-wms-fix-capabilities-on-Windows-for-Python-3.6.7.patch
Description: Skip tests for missing data files.
Author: Bas Couwenberg <sebastic@debian.org>
Forwarded: not-needed
--- a/mapproxy/test/system/test_cache_geopackage.py
+++ b/mapproxy/test/system/test_cache_geopackage.py
@@ -27,6 +27,7 @@ from mapproxy.test.system import prepare
from mapproxy.cache.geopackage import GeopackageCache
from mapproxy.grid import TileGrid
from nose.tools import eq_
+from nose.plugins.skip import SkipTest
import sqlite3
test_config = {}
@@ -35,6 +36,9 @@ test_config = {}
def setup_module():
prepare_env(test_config, 'cache_geopackage.yaml')
+ if not os.path.exists(os.path.join(test_config['fixture_dir'], 'cache.gpkg')):
+ raise SkipTest
+
shutil.copy(os.path.join(test_config['fixture_dir'], 'cache.gpkg'),
test_config['base_dir'])
create_app(test_config)
--- a/mapproxy/test/unit/test_cache_geopackage.py
+++ b/mapproxy/test/unit/test_cache_geopackage.py
@@ -29,6 +29,7 @@ from mapproxy.grid import tile_grid, Til
from mapproxy.test.unit.test_cache_tile import TileCacheTestBase
from nose.tools import eq_
+from nose.plugins.skip import SkipTest
class TestGeopackageCache(TileCacheTestBase):
@@ -190,6 +191,10 @@ class TestGeopackageCacheInitErrors(obje
'fixture'),
'cache.gpkg')
table_name = 'cache'
+
+ if not os.path.exists(gpkg_file):
+ raise SkipTest
+
try:
GeopackageCache(gpkg_file, TileGrid(srs=4326), table_name)
except ValueError as ve:
@@ -202,6 +207,10 @@ class TestGeopackageCacheInitErrors(obje
'fixture'),
'cache.gpkg')
table_name = 'cache'
+
+ if not os.path.exists(gpkg_file):
+ raise SkipTest
+
try:
GeopackageCache(gpkg_file, TileGrid(srs=900913, tile_size=(512, 512)), table_name)
except ValueError as ve:
@@ -214,6 +223,10 @@ class TestGeopackageCacheInitErrors(obje
'fixture'),
'cache.gpkg')
table_name = 'cache'
+
+ if not os.path.exists(gpkg_file):
+ raise SkipTest
+
try:
GeopackageCache(gpkg_file, TileGrid(srs=900913, res=[1000, 100, 10]), table_name)
except ValueError as ve:
Description: Fix spelling errors
* everytime -> every time
Author: Bas Couwenberg <sebastic@debian.org>
Forwarded: https://github.com/mapproxy/mapproxy/pull/373
Applied-Upstream: https://github.com/mapproxy/mapproxy/commit/f8c32bfae05f29b49e9c7b2f4fccdbabdec58ff1
--- a/doc/mapproxy_util_autoconfig.rst
+++ b/doc/mapproxy_util_autoconfig.rst
@@ -78,7 +78,7 @@ Write MapProxy configuration with caches
Overwrites
==========
-It's likely that you need to tweak the created configuration – e.g. to define another coverage, disable featureinfo, etc. You can do this by editing the output file of course, or you can modify the output by defining all changes to an overwrite file. Overwrite files are applied everytime you call ``mapproxy-util autoconfig``.
+It's likely that you need to tweak the created configuration – e.g. to define another coverage, disable featureinfo, etc. You can do this by editing the output file of course, or you can modify the output by defining all changes to an overwrite file. Overwrite files are applied every time you call ``mapproxy-util autoconfig``.
Overwrites are YAML files that will be merged with the created configuration file.
--- a/doc/seed.rst
+++ b/doc/seed.rst
@@ -411,9 +411,9 @@ Example: Background seeding
The ``--duration`` option allows you run MapProxy seeding for a limited time. In combination with the ``--continue`` option, you can resume the seeding process at a later time.
You can use this to call ``mapproxy-seed`` with ``cron`` to seed in the off-hours.
-However, this will restart the seeding process from the begining everytime the is seeding completed.
+However, this will restart the seeding process from the begining every time the is seeding completed.
You can prevent this with the ``--reeseed-interval`` and ``--reseed-file`` option.
-The follwing example starts seeding for six hours. It will seed for another six hours, everytime you call this command again. Once all seed and cleanup tasks were proccessed the command will exit immediately everytime you call it within 14 days after the first call. After 14 days, the modification time of the ``reseed.time`` file will be updated and the re-seeding process starts again.
+The follwing example starts seeding for six hours. It will seed for another six hours, every time you call this command again. Once all seed and cleanup tasks were proccessed the command will exit immediately every time you call it within 14 days after the first call. After 14 days, the modification time of the ``reseed.time`` file will be updated and the re-seeding process starts again.
::
......@@ -33,7 +33,7 @@ override_dh_auto_build:
(cd doc && PYTHONPATH=$(CURDIR) $(MAKE) html)
override_dh_auto_test:
OFFLINE_TESTS=1 dh_auto_test || echo "Ignoring test failures"
dh_auto_test || echo "Ignoring test failures"
override_dh_auto_install:
PYBUILD_INSTALL_ARGS="--install-scripts=/usr/lib/{package}" dh_auto_install
......
......@@ -493,7 +493,9 @@ WMTS Service
The WMTS authorization is similar to the TMS authorization, including the ``limited_to`` option.
The WMTS service uses ``wmts`` as the service string for all authorization requests.
The WMTS service uses ``wmts`` as the service string for tile requests and ``wmts.featureinfo`` for feature info requests.
.. versionadded:: 1.12 ``wmts.featureinfo``
Demo Service
......
......@@ -286,7 +286,7 @@ This backend is good for very large caches which can be distributed over many no
Requirements
------------
You will need the `Python Riak client <https://pypi.python.org/pypi/riak>`_ version 2.4.2 or older. You can install it in the usual way, for example with ``pip install riak==2.4.2``. Environments with older version must be upgraded with ``pip install -U riak==2.4.2``. Python library depends on packages `python-dev`, `libffi-dev` and `libssl-dev`.
You will need the `Python Riak client <https://pypi.org/project/riak>`_ version 2.4.2 or older. You can install it in the usual way, for example with ``pip install riak==2.4.2``. Environments with older version must be upgraded with ``pip install -U riak==2.4.2``. Python library depends on packages `python-dev`, `libffi-dev` and `libssl-dev`.
Configuration
-------------
......@@ -347,7 +347,7 @@ Your Redis database should be configured with ``maxmemory`` and ``maxmemory-poli
Requirements
------------
You will need the `Python Redis client <https://pypi.python.org/pypi/redis>`_. You can install it in the usual way, for example with ``pip install redis``.
You will need the `Python Redis client <https://pypi.org/project/redis>`_. You can install it in the usual way, for example with ``pip install redis``.
Configuration
-------------
......@@ -434,13 +434,16 @@ You can set the ``sources`` to an empty list, if you use an existing geopackage
.. versionadded:: 1.10.0
Store tiles in a `Amazon Simple Storage Service (S3) <https://aws.amazon.com/s3/>`_.
.. versionadded:: 1.11.0
``region_name``, ``endpoint_url`` and ``access_control_list``
Store tiles in a `Amazon Simple Storage Service (S3) <https://aws.amazon.com/s3/>`_ or any other S3 compatible object storage.
Requirements
------------
You will need the Python `boto3 <https://github.com/boto/boto3>`_ package. You can install it in the usual way, for example with ``pip install boto3``.
You will need the Python `boto3 <https://pypi.org/project/boto3>`_ package. You can install it in the usual way, for example with ``pip install boto3``.
Configuration
-------------
......@@ -454,6 +457,15 @@ Available options:
Optional profile name for `shared credentials <http://boto3.readthedocs.io/en/latest/guide/configuration.html>`_ for this cache. Alternative methods of authentification are using the ``AWS_ACCESS_KEY_ID`` and ``AWS_SECRET_ACCESS_KEY`` environmental variables, or by using an `IAM role <http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html>`_ when using an Amazon EC2 instance.
You can set the default profile with ``globals.cache.s3.profile_name``.
``region_name``:
Optional name of the region. You can set the default region_name with ``globals.cache.s3.region_name``
``endpoint_url``:
Optional endpoint_url for the S3. You can set the default endpoint_url with ``globals.cache.s3.endpoint_url``.
``access_control_list``:
Optional access control list for the S3. You can set the default access_control_list with ``globals.cache.s3.access_control_list``.
``directory``:
Base directory (path) where all tiles are stored.
......@@ -482,6 +494,28 @@ Example
profile_name: default
Example usage with DigitalOcean Spaces
--------------------------------------
::
cache:
my_layer_20110501_epsg_4326_cache_out:
sources: [my_layer_20110501_cache]
cache:
type: s3
directory: /1.0.0/my_layer/default/20110501/4326/
bucket_name: my-s3-tiles-cache
globals:
cache:
s3:
profile_name: default
region_name: nyc3
endpoint_url: https://nyc3.digitaloceanspaces.com
access_control_list: public-read
.. _cache_compact:
......
......@@ -49,9 +49,9 @@ copyright = u'Oliver Tonnhofer, Omniscale'
# built documents.
#
# The short X.Y version.
version = '1.11'
version = '1.12'
# The full version, including alpha/beta/rc tags.
release = '1.11.1'
release = '1.12.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......
......@@ -487,6 +487,32 @@ Enables meta-tile handling for tiled sources. See :ref:`global cache options <me
You can limit until which resolution MapProxy should cache data with these two options.
Requests below the configured resolution or level will be passed to the underlying source and the results will not be stored. The resolution of ``use_direct_from_res`` should use the units of the first configured grid of this cache. This takes only effect when used in WMS services.
``upscale_tiles`` and ``downscale_tiles``
"""""""""""""""""""""""""""""""""""""""""
MapProxy is able to create missing tiles by rescaling tiles from zoom levels below or above.
MapProxy will scale up tiles from one or more zoom levels above (with lower resolutions) if you set ``upscale_tiles`` to 1 or higher. The value configures by how many zoom levels MapProxy can search for a proper tile. Higher values allow more blurry results.
You can use ``upscale_tiles`` if you want to provide tiles or WMS responses in a higher resolution then your available cache. This also works with partially seeded caches, eg. where you have an arial image cache of 20cm, with some areas also in 10cm resolution. ``upscale_tiles`` allows you to provide responses for 10cm requests in all areas, allways returning the best available data.
MapProxy will scale down tiles from one or more zoom levels below (with higher resolutions) if you set ``downscale_tiles`` to 1 or higher. The value configures by how many zoom levels MapProxy can search for a proper tile. Note that the number of tiles growth exponentialy. Typically, a single tile can be downscaled from four tiles of the next zoom level. Downscaling from two levels below requires 16 tiles, three levels below requires 64, etc.. A larger WMS request can quickly accumulate thousands of tiles required for downscaling. It is therefore `not` recommended to use ``downscale_tiles`` values larger then one.
You can use ``downscale_tiles`` to fill a cache for a source that only provides data for higher resolutions.
``mapproxy-seed`` will seed each level independently for caches with ``upscale_tiles`` or ``downscale_tiles``. It will start with the highest zoom level for ``downscale_tiles``, so that tiles in the next (lower) zoom levels can be created by downscaling the already created tiles. It will start in the lowest zoom level for ``upscale_tiles``, so that tiles in the next (higher) zoom levels can be created by upscaling the already creates tiles.
A transparent tile is returned if no tile is found within the configured ``upscale_tiles`` or ``downscale_tiles`` range.
To trigger the rescaling behaviour, a tile needs to be missing in the cache and MapProxy needs to be unable to fetch the tile from the source. MapProxy is unable to fetch the tile if the cache has no sources, or if all sources are either ``seed_only`` or limited to a different resolution (``min_res``/``max_res``).
``cache_rescaled_tiles``
""""""""""""""""""""""""
Tiles created by the ``upscale_tiles`` or ``downscale_tiles`` option are only stored in the cache if this option is set to true.
``disable_storage``
""""""""""""""""""""
......@@ -858,6 +884,29 @@ The following options define how tiles are created and stored. Most options can
``srs``
"""""""
``preferred_src_proj``
This option allows you to control which source projection MapProxy should use
when it needs to reproject an image.
When you make a request for a projection that is not supported by your cache (tile grid) or by your source (``supported_srs``), then MapProxy will reproject the image from the `best` available projection. By default, the `best` available projection is the first supported projection by your cache or source that is also either projected or geographic.
You can change this behavior with ``preferred_src_proj``. For example, you can configure that MapProxy should prefer similar projections from neighboring zones over Webmercator.
``preferred_src_proj`` is a dictionary with the target EPSG code (i.e. the SRS requested by the user) and a list of preferred source EPSG codes.
With the following configuration, WMS requests for EPSG:25831 are served from a cache with EPSG:25832, if there is no cache for EPSG:25831.
::
srs:
preferred_src_proj:
'EPSG:25831': ['EPSG:25832', 'EPSG:3857']
'EPSG:25832': ['EPSG:25831', 'EPSG:25833', 'EPSG:3857']
'EPSG:25833': ['EPSG:25832'', 'EPSG:3857']
'EPSG:31466': ['EPSG:25831', 'EPSG:25832', 'EPSG:3857']
'EPSG:31467': ['EPSG:25832', 'EPSG:25833', 'EPSG:25831', 'EPSG:3857']
.. versionadded:: 1.12.0
``proj_data_dir``
MapProxy uses Proj4 for all coordinate transformations. If you need custom projections
or need to tweak existing definitions (e.g. add towgs parameter set) you can point
......@@ -866,6 +915,7 @@ The following options define how tiles are created and stored. Most options can
The configured path can be absolute or relative to the mapproxy.yaml.
.. _axis_order:
``axis_order_ne`` and ``axis_order_en``
......@@ -1048,6 +1098,12 @@ The following encoding options are available:
The algorithm used to quantize (reduce) the image colors. Quantizing is used for GIF and paletted PNG images. Available quantizers are ``mediancut`` and ``fastoctree``. ``fastoctree`` is much faster and also supports 8bit PNG with full alpha support, but the image quality can be better with ``mediancut`` in some cases.
The quantizing is done by the Python Image Library (PIL). ``fastoctree`` is a `new quantizer <http://mapproxy.org/blog/improving-the-performance-for-png-requests/>`_ that is only available in Pillow >=2.0. See :ref:`installation of PIL<dependencies_pil>`.
``tiff_compression``
Enable compression for TIFF images. Available compression methods are `tiff_lzw` for lossless LZW compression, `jpeg` for JPEG compression and `raw` for no compression (default). You can use the ``jpeg_quality`` option to tune the image quality for JPEG compressed TIFFs. Requires Pillow >= 6.1.0.
.. versionadded:: 1.12.0
Global
""""""
......
......@@ -393,6 +393,7 @@ You can specify a different factor that is used to calculate the resolutions. By
res_factor: 1.6
The third options is a convenient variation of the previous option. A factor of 1.41421, the square root of two, would get resolutions of 10, 7.07, 5, 3.54, 2.5,…. Notice that every second resolution is identical to the power-of-two resolutions. This comes in handy if you use the layer not only in classic WMS clients but also want to use it in tile-based clients like OpenLayers, which only request in these resolutions.
::
grids:
......@@ -469,6 +470,7 @@ Reproject WMS layers
If you do not want to cache data but still want to use MapProxy's ability to reproject WMS layers on the fly, you can use a direct layer. Add your source directly to your layer instead of a cache.
You should explicitly define the SRS the source WMS supports. Requests in other SRS will be reprojected. You should specify at least one geographic and one projected SRS to limit the distortions from reprojection.
::
layers:
......@@ -504,6 +506,9 @@ MapProxy can pass-through FeatureInformation requests to your WMS sources. You n
MapProxy will mark all layers that use this source as ``queryable``. It also works for sources that are used with caching.
FeatureInfo support is enabled by default for WMS. For :ref:`WMTS you need to enable FeatureInfo queries by configuring the supported formats <wmts_feature_info>`.
.. note:: The more advanced features :ref:`require the lxml library <lxml_install>`.
Concatenation
......@@ -572,7 +577,7 @@ Example
Lets assume we have two WMS sources where we have no control over the format of the feature info responses.
One source only offers HTML feature information. The XSLT script extracts data from a table. We force the ``INFO_FORMAT`` to HTML, so that MapProxy will not query another format.
One source only offers HTML feature information. The XSLT script extracts data from a table. We force the WMS ``INFO_FORMAT`` to HTML with the ``featureinfo_format`` option, so that MapProxy will not query another format. The XSLT script returns XML and not HTML. We configure this with the ``featureinfo_out_format`` option.
::
......@@ -582,10 +587,12 @@ One source only offers HTML feature information. The XSLT script extracts data f
featureinfo: true
featureinfo_xslt: ./html_in.xslt
featureinfo_format: text/html
featureinfo_out_format: text/xml
req: [...]
The second source supports XML feature information. The script converts the XML data to the same format as the HTML script. This service uses WMS 1.3.0 and the format is ``text/xml``.
::
fi_source:
......@@ -706,16 +713,16 @@ You can disable the certificate verification if you you don't need it.
Access sources through HTTP proxy
=================================
MapProxy can use an HTTP proxy to make requests to your sources, if your system does not allow direct access to the source. You need to set the ``http_proxy`` environment variable to the proxy URL. This also applies if you install MapProxy with ``pip`` or ``easy_install``.
MapProxy can use an HTTP proxy to make requests to your sources, if your system does not allow direct access to the source. You need to set the ``http_proxy`` and ``https_proxy`` environment variable to the proxy URL. This also applies if you install MapProxy with ``pip``.
On Linux/Unix::
$ export http_proxy="http://example.com:3128"
$ export http_proxy="http://example.com:3128" https_proxy="http://example.com:3128"
$ mapproxy-util serve-develop mapproxy.yaml
On Windows::
c:\> set http_proxy="http://example.com:3128"
c:\> set http_proxy="http://example.com:3128" https_proxy="http://example.com:3128"
c:\> mapproxy-util serve-develop mapproxy.yaml
......@@ -723,6 +730,7 @@ You can also set this in your :ref:`server script <server_script>`::
import os
os.environ["http_proxy"] = "http://example.com:3128"
os.environ["https_proxy"] = "http://example.com:3128"
Add a username and password to the URL if your HTTP proxy requires authentication. For example ``http://username:password@example.com:3128``.
......@@ -730,7 +738,6 @@ You can use the ``no_proxy`` environment variable if you need to bypass the prox
$ export no_proxy="localhost,127.0.0.1,196.168.1.99"
``no_proxy`` is available since Python 2.6.3.
.. _paster_urlmap:
......
......@@ -86,7 +86,7 @@ Any polygon datasource that is supported by OGR (e.g. Shapefile, GeoJSON, PostGI
``where``:
Restrict which polygons should be loaded from the datasource. Either a simple where
statement (e.g. ``'CNTRY_NAME="Germany"'``) or a full select statement. Refer to the
statement (e.g. ``"CNTRY_NAME='Germany'"``) or a full select statement. Refer to the
`OGR SQL support documentation <http://www.gdal.org/ogr/ogr_sql.html>`_. If this
option is unset, the first layer from the datasource will be used.
......@@ -193,7 +193,7 @@ To define a seed-area in the ``seed.yaml``, add the coverage directly to the vie
coverages:
germany:
datasource: 'shps/world_boundaries_m.shp'
where: 'CNTRY_NAME = "Germany"'
where: CNTRY_NAME = 'Germany'
srs: 'EPSG:900913'
.. index:: PostGIS, PostgreSQL
......
......@@ -27,7 +27,7 @@ The server automatically reloads if the configuration or any code of MapProxy ch
.. cmdoption:: --debug
Start MapProxy in debug mode. If you have installed Werkzeug_ (recommended) or Paste_, you will get an interactive traceback in the web browser on any unhandled exception (internal error).
Start MapProxy in debug mode. If you have installed Werkzeug_, you will get an interactive traceback in the web browser on any unhandled exception (internal error).
.. note:: This server is sufficient for local testing of the configuration, but it is `not` stable for production or load testing.
......@@ -49,8 +49,6 @@ Behind an HTTP server or proxy
Both approaches require a configuration that maps your MapProxy configuration with the MapProxy application. You can write a small script file for that.
Running MapProxy as a FastCGI server behind HTTP server, a third option, is no longer advised for new setups since the FastCGI package (flup) is no longer maintained and the Python HTTP server improved significantly.
.. _server_script:
Server script
......@@ -67,7 +65,7 @@ The script contains the following lines and makes the configured MapProxy availa
from mapproxy.wsgiapp import make_wsgi_app
application = make_wsgi_app('examples/minimal/etc/mapproxy.yaml')
This is sufficient for embedding MapProxy with ``mod_wsgi`` or for starting it with Python HTTP servers like ``gunicorn`` (see further below). You can extend this script to setup logging or to set environment variables.
This is sufficient for embedding MapProxy with ``mod_wsgi`` or for starting it with Python HTTP servers like ``waitress`` (see further below). You can extend this script to setup logging or to set environment variables.
You can enable MapProxy to automatically reload the configuration if it changes::
......@@ -133,49 +131,27 @@ There are Python HTTP servers available that can directly run MapProxy. Most of
Python HTTP Server
~~~~~~~~~~~~~~~~~~
You need start these servers in the background on start up. It is recommended to create an init script for that or to use tools like upstart_ or supervisord_.
You need start these servers in the background on start up. It is recommended to start it from systemd or upstart.
Gunicorn
Waitress
""""""""
Gunicorn_ is a Python WSGI HTTP server for UNIX. Gunicorn use multiple processes but the process number is fixed. The default worker is synchronous, meaning that a process is blocked while it requests data from another server for example. You need to choose an asynchronous worker like eventlet_.
Waitress_ is a production-quality pure-Python WSGI server with very acceptable performance. It runs on Unix and Windows.
You need a server script that creates the MapProxy application (see :ref:`above <server_script>`). The script needs to be in the directory from where you start ``gunicorn`` and it needs to end with ``.py``.
You need a server script that creates the MapProxy application (see :ref:`above <server_script>`). The script needs to be in the directory from where you start ``waitress`` and it needs to end with ``.py``.
To start MapProxy with the Gunicorn web server with four processes, the eventlet worker and our server script (without ``.py``)::
To start MapProxy with Waitress and our server script (without ``.py``)::
cd /path/of/config.py/
gunicorn -k eventlet -w 4 -b :8080 config:application --no-sendfile
An example upstart script (``/etc/init/mapproxy.conf``) might look like::
start on runlevel [2345]
stop on runlevel [!2345]
respawn
setuid mapproxy
setgid mapproxy
chdir /etc/opt/mapproxy
exec /opt/mapproxy/bin/gunicorn -k eventlet -w 8 -b :8080 \
--no-sendfile \
application \
>>/var/log/mapproxy/gunicorn.log 2>&1
waitress --listen 127.0.0.1:8080 config:application
Spawning
""""""""
Spawning_ is another Python WSGI HTTP server for UNIX that supports multiple processes and multiple threads.
uWSGI
"""""
::
uWSGI is another production-quality WSGI server. It is highly configurable and offers high performance (by running on multiple processors).
cd /path/of/config.py/
spawning config.application --threads=8 --processes=4 \
--port=8080
The `uWSGI documentation provides a quickstart <https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html>`_.
HTTP Proxy
......@@ -224,16 +200,6 @@ Here is an example for the Apache_ webserver with the included ``mod_proxy`` and
You need to make sure that both modules are loaded. The ``Host`` is already set to the right value by default.
Other deployment options
------------------------
Refer to http://wsgi.readthedocs.org/en/latest/servers.html for a list of some available WSGI servers.
FastCGI
~~~~~~~
.. note:: Running MapProxy as a FastCGI server behind HTTP server is no longer advised for new setups since the used Python package (flup) is no longer maintained. Please refer to the `MapProxy 1.5.0 deployment documentation for more information on FastCGI <http://mapproxy.org/docs/1.5.0/deployment.html>`_.
Performance
-----------
......@@ -259,17 +225,10 @@ With this setup the locking will only be effective when parallel requests for ti
.. _mod_proxy: http://httpd.apache.org/docs/current/mod/mod_proxy.html
.. _Varnish: http://www.varnish-cache.org/
.. _werkzeug: http://pypi.python.org/pypi/Werkzeug
.. _paste: http://pypi.python.org/pypi/Paste
.. _gunicorn: http://gunicorn.org/
.. _Spawning: http://pypi.python.org/pypi/Spawning
.. _uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/
.. _Waitress: https://docs.pylonsproject.org/projects/waitress/en/stable/
.. _FastCGI: http://www.fastcgi.com/
.. _flup: http://pypi.python.org/pypi/flup
.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
.. _mod_fcgid: http://httpd.apache.org/mod_fcgid/
.. _eventlet: http://pypi.python.org/pypi/eventlet
.. _Apache: http://httpd.apache.org/
.. _upstart: http://upstart.ubuntu.com/
.. _supervisord: http://supervisord.org/
Logging
-------
......