Skip to content

Commit

Permalink
Merge pull request #307 from DHI-GRAS/fix-explicit-cmap-doc
Browse files Browse the repository at this point in the history
Fix explicit cmap example in apidoc (#306)
  • Loading branch information
dionhaefner authored May 15, 2023
2 parents 17d4789 + c94cb2a commit 35f0f23
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 26 deletions.
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
_static/generated/*
!_static/generated/EMPTY
Empty file added docs/_static/generated/EMPTY
Empty file.
4 changes: 4 additions & 0 deletions docs/apidoc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Server API
==========

This file is intentionally left blank
40 changes: 37 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand All @@ -81,6 +81,40 @@
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# -- Render apidoc -------------------------------------------------------------

# Get swagger.json from terracotta server
from terracotta.server.app import app as terracotta_app

with terracotta_app.test_client() as client:
swagger_json = client.get('/swagger.json').data.decode('utf-8')

with open('_static/generated/swagger.json', 'w') as f:
f.write(swagger_json)

templates_path.append('../terracotta/server/templates')
html_static_path.append('../terracotta/server/static')

html_additional_pages = {
'apidoc': 'apidoc.html',
}


def _url_for(endpoint, filename=None):
if filename is not None:
assert endpoint == 'static'
return f'_static/{filename}'

assert endpoint == '.specification'
return '_static/generated/swagger.json'


# Inject Jinja variables defined by Flask
html_context = {
'url_for': _url_for
}


# -- Extension settings --------------------------------------------------------

intersphinx_mapping = {
Expand Down Expand Up @@ -108,12 +142,12 @@
'body_text': '#000',
'sidebar_header': '#4B4032',
'sidebar_text': '#49443E',
'github_banner': 'true',
'github_banner': 'false',
'github_user': 'DHI-GRAS',
'github_repo': 'terracotta',
'github_button': 'true',
'github_type': 'star',
'travis_button': 'true',
'travis_button': 'false',
'codecov_button': 'true',
'logo': 'logo.svg'
}
Expand Down
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ respectively. This is the best way to find out which API *your*
deployment of Terracotta uses.

To catch a first glance,
`feel free to explore the API of our demo server <https://2truhxo59g.execute-api.eu-central-1.amazonaws.com/production/apidoc>`__.
:doc:`feel free to explore the API of this Terracotta version <apidoc>`.


Contents
Expand All @@ -70,6 +70,7 @@ Contents
settings
cli
api
apidoc
tutorial
reference
issues
2 changes: 1 addition & 1 deletion terracotta/server/singleband.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Meta:
explicit_color_map = fields.Dict(
keys=fields.Number(),
values=fields.List(fields.Number, validate=validate.Length(min=3, max=4)),
example="{0: (255, 255, 255)}",
example='{"0": [255, 255, 255]}',
description="Explicit value-color mapping to use, encoded as JSON object. "
"Must be given together with `colormap=explicit`. Color values can be "
"specified either as RGB or RGBA tuple (in the range of [0, 255]), or as "
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,9 @@ def testdb(raster_file, tmpdir_factory):
return dbpath


@pytest.fixture(scope="session")
@pytest.fixture()
def v07_db(tmpdir_factory):
"""A read-only, pre-populated test database"""
"""A read-only, pre-populated test database at terracotta v0.7"""
import shutil

dbpath = tmpdir_factory.mktemp("db").join("db-outdated.sqlite")
Expand Down
46 changes: 40 additions & 6 deletions tests/scripts/test_migrate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from click.testing import CliRunner


Expand All @@ -9,6 +10,38 @@ def parse_version(verstr):


def test_migrate(v07_db, monkeypatch, force_reload):
"""Test database migration to this major version."""
import terracotta
from terracotta import get_driver
from terracotta.scripts import cli

current_version = parse_version(terracotta.__version__)

# run migration
runner = CliRunner()
result = runner.invoke(
cli.cli,
[
"migrate",
str(v07_db),
"--from",
"v0.7",
"--to",
f"v{current_version[0]}.{current_version[1]}",
"--yes",
],
)

assert result.exit_code == 0
assert "Upgrade path found" in result.output

driver_updated = get_driver(str(v07_db), provider="sqlite")

# key_names did not exist in v0.7
assert driver_updated.key_names == ("key1", "akey", "key2")


def test_migrate_next(v07_db, monkeypatch, force_reload):
"""Test database migration to next major version if one is available."""
with monkeypatch.context() as m:
# pretend we are at the next major version
Expand All @@ -18,22 +51,23 @@ def test_migrate(v07_db, monkeypatch, force_reload):
next_major_version = (current_version[0], current_version[1] + 1, 0)
m.setattr(terracotta, "__version__", ".".join(map(str, next_major_version)))

# run migration
from terracotta import get_driver
from terracotta.scripts import cli
from terracotta.migrations import MIGRATIONS

if next_major_version[:2] not in [m.up_version for m in MIGRATIONS.values()]:
pytest.skip("No migration available for next major version")

# run migration
runner = CliRunner()
result = runner.invoke(
cli.cli, ["migrate", str(v07_db), "--from", "v0.7", "--yes"]
)
assert result.exit_code == 0

if next_major_version[:2] not in [m.up_version for m in MIGRATIONS.values()]:
assert "Unknown target version" in result.output
return

assert result.exit_code == 0
assert "Upgrade path found" in result.output

driver_updated = get_driver(str(v07_db), provider="sqlite")

# key_names did not exist in v0.7
assert driver_updated.key_names == ("key1", "akey", "key2")
19 changes: 6 additions & 13 deletions tests/server/test_flask_api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from io import BytesIO
import json
import urllib.parse
from collections import OrderedDict

from PIL import Image
import numpy as np
Expand Down Expand Up @@ -94,40 +93,34 @@ def test_get_metadata_nonexisting(client, use_testdb):
def test_get_datasets(client, use_testdb):
rv = client.get("/datasets")
assert rv.status_code == 200
datasets = json.loads(rv.data, object_pairs_hook=OrderedDict)["datasets"]
datasets = json.loads(rv.data)["datasets"]
assert len(datasets) == 4
assert (
OrderedDict([("key1", "val11"), ("akey", "x"), ("key2", "val12")]) in datasets
)
assert dict([("key1", "val11"), ("akey", "x"), ("key2", "val12")]) in datasets


def test_get_datasets_pagination(client, use_testdb):
# no page (implicit 0)
rv = client.get("/datasets?limit=2")
assert rv.status_code == 200
response = json.loads(rv.data, object_pairs_hook=OrderedDict)
response = json.loads(rv.data)
assert response["limit"] == 2
assert response["page"] == 0

first_datasets = response["datasets"]
assert len(first_datasets) == 2
assert (
OrderedDict([("key1", "val11"), ("akey", "x"), ("key2", "val12")])
in first_datasets
)
assert dict([("key1", "val11"), ("akey", "x"), ("key2", "val12")]) in first_datasets

# second page
rv = client.get("/datasets?limit=2&page=1")
assert rv.status_code == 200
response = json.loads(rv.data, object_pairs_hook=OrderedDict)
response = json.loads(rv.data)
assert response["limit"] == 2
assert response["page"] == 1

last_datasets = response["datasets"]
assert len(last_datasets) == 2
assert (
OrderedDict([("key1", "val11"), ("akey", "x"), ("key2", "val12")])
not in last_datasets
dict([("key1", "val11"), ("akey", "x"), ("key2", "val12")]) not in last_datasets
)

# page out of range
Expand Down

0 comments on commit 35f0f23

Please sign in to comment.