Skip to content

Commit

Permalink
Limit flask and bug fixes (#178)
Browse files Browse the repository at this point in the history
* Limit flask

* Fix CRS serialization issue

* Shamelessly remove ROI support for REST client

* Shamelessly drop support for histograms
  • Loading branch information
banesullivan committed Oct 9, 2023
1 parent 70e1a22 commit 2753554
Show file tree
Hide file tree
Showing 8 changed files with 7 additions and 174 deletions.
62 changes: 0 additions & 62 deletions localtileserver/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,10 +410,6 @@ def pixel(self, y: float, x: float, units: str = "pixels", projection: Optional[
"""
raise NotImplementedError # pragma: no cover

def histogram(self, bins: int = 256, density: bool = False):
"""Get a histoogram for each band."""
raise NotImplementedError # pragma: no cover

@property
def default_zoom(self):
m = self.metadata_safe()
Expand Down Expand Up @@ -671,10 +667,6 @@ def pixel(self, y: float, x: float, units: str = "pixels"):
region = {"left": x, "top": y, "units": units}
return self.tile_source.getPixel(region=region)

def histogram(self, bins: int = 256, density: bool = False):
result = self.tile_source.histogram(bins=bins, density=density)
return result["histogram"]


class BaseRestfulTileClient(BaseTileClientInterface):
"""Connect to a localtileserver instance.
Expand All @@ -691,51 +683,6 @@ def get_tile(self, z: int, x: int, y: int, *args, output_path=None, **kwargs):
return save_file_from_request(r, output_path)
return ImageBytes(r.content, mimetype=r.headers["Content-Type"])

def extract_roi(
self,
left: float,
right: float,
bottom: float,
top: float,
units: str = "EPSG:4326",
encoding: str = "TILED",
output_path: pathlib.Path = None,
return_bytes: bool = False,
return_path: bool = False,
):
path = f"api/world/region.tif?units={units}&encoding={encoding}&left={left}&right={right}&bottom={bottom}&top={top}"
r = requests.get(self.create_url(path))
r.raise_for_status()
if return_bytes:
return ImageBytes(r.content, mimetype=r.headers["Content-Type"])
output_path = save_file_from_request(r, output_path)
if return_path:
return output_path
return TileClient(output_path)

def extract_roi_pixel(
self,
left: int,
right: int,
bottom: int,
top: int,
encoding: str = "TILED",
output_path: pathlib.Path = None,
return_bytes: bool = False,
return_path: bool = False,
):
path = f"/api/pixel/region.tif?encoding={encoding}&left={left}&right={right}&bottom={bottom}&top={top}"
r = requests.get(self.create_url(path))
r.raise_for_status()
if return_bytes:
return ImageBytes(r.content, mimetype=r.headers["Content-Type"])
output_path = save_file_from_request(r, output_path)
if return_path:
return output_path
return TileClient(
output_path, default_projection="EPSG:3857" if encoding == "TILED" else None
)

def metadata(self, projection: Optional[str] = ""):
if projection not in self._metadata:
if projection == "":
Expand Down Expand Up @@ -820,15 +767,6 @@ def pixel(self, y: float, x: float, units: str = "pixels", projection: Optional[
r.raise_for_status()
return r.json()

def histogram(self, bins: int = 256, density: bool = False):
params = {}
params["density"] = density
params["bins"] = bins
url = add_query_parameters(self.create_url("api/histogram"), params)
r = requests.get(url)
r.raise_for_status()
return r.json()


class RemoteTileClient(BaseRestfulTileClient):
"""Connect to a remote localtileserver instance at a given host URL.
Expand Down
3 changes: 3 additions & 0 deletions localtileserver/tiler/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import large_image
from large_image_source_rasterio import RasterioFileTileSource
from rasterio import CRS

from localtileserver.tiler.data import clean_url, get_data_path, get_pine_gulch_url

Expand Down Expand Up @@ -139,6 +140,8 @@ def get_meta_data(tile_source: RasterioFileTileSource):
meta.update(tile_source.getInternalMetadata())
# Override bounds for EPSG:4326
meta["bounds"] = get_tile_bounds(tile_source)
if isinstance(meta["projection"], CRS):
meta["projection"] = meta["projection"].to_string()
return meta


Expand Down
33 changes: 0 additions & 33 deletions localtileserver/web/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,36 +497,3 @@ def get(self):
pixel.pop("value", None)
pixel.update(region)
return pixel


@api.doc(
params={
"bins": {
"type": "int",
"default": 256,
},
"density": {
"type": "bool",
"default": False,
},
}
)
class HistogramView(BasePixelOperation):
"""Returns histogram."""

def get(self):
kwargs = dict(
bins=int(request.args.get("bins", 256)),
density=str_to_bool(request.args.get("density", "False")),
)
tile_source = self.get_tile_source(projection=None)
result = tile_source.histogram(**kwargs)
result = result["histogram"]
for entry in result:
for key in {"bin_edges", "hist", "range"}:
if key in entry:
entry[key] = [float(val) for val in list(entry[key])]
for key in {"min", "max", "samples"}:
if key in entry:
entry[key] = float(entry[key])
return result
5 changes: 0 additions & 5 deletions localtileserver/web/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@
"/pixel",
endpoint="pixel",
)
rest.api.add_resource(
rest.HistogramView,
"/histogram",
endpoint="histogram",
)
rest.api.add_resource(
rest.ListTileSources,
"/sources",
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
click
flask>=2.0.0
flask>=2.0.0,<3
Flask-Caching
flask-cors
flask-restx>=0.5.0
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
long_description = ""

# major, minor, patch
version_info = 0, 7, 1
version_info = 0, 7, 2
# Nice string for the version
__version__ = ".".join(map(str, version_info))

Expand Down Expand Up @@ -42,7 +42,7 @@
python_requires=">=3.7",
install_requires=[
"click",
"flask>=2.0.0",
"flask>=2.0.0,<3",
"Flask-Caching",
"flask-cors",
"flask-restx>=0.5.0",
Expand Down
6 changes: 0 additions & 6 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,6 @@ def test_pixel(bahamas):
assert "bands" in pix


@pytest.mark.skip
def test_histogram(bahamas):
hist = bahamas.histogram()
assert len(hist)


@pytest.mark.parametrize("encoding", ["PNG", "JPEG", "JPG"])
def test_thumbnail_encodings(bahamas, encoding):
# large-image's rasterio source cannot handle: "TIF", "TIFF"
Expand Down
66 changes: 1 addition & 65 deletions tests/test_client_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@
from server_thread import ServerDownError, ServerManager

from localtileserver.client import RestTileClient
from localtileserver.tiler import get_clean_filename, get_tile_bounds, get_tile_source
from localtileserver.tiler import get_clean_filename
from localtileserver.utilities import ImageBytes

skip_shapely = False
try:
from shapely.geometry import box
except ImportError:
skip_shapely = True

skip_mac_arm = pytest.mark.skipif(
platform.system() == "Darwin" and platform.processor() == "arm", reason="MacOS Arm issues."
)
Expand Down Expand Up @@ -97,57 +91,6 @@ def test_client_force_shutdown(bahamas_file):
# assert get_content(thumb_url_a) != get_content(thumb_url_b)


def test_extract_roi_world(bahamas_file):
bahamas = RestTileClient(bahamas_file)
# -78.047, -77.381, 24.056, 24.691
path = bahamas.extract_roi(-78.047, -77.381, 24.056, 24.691, return_path=True)
assert path.exists()
source = get_tile_source(path, projection="EPSG:3857")
assert source.getMetadata()["geospatial"]
e = get_tile_bounds(source, projection="EPSG:4326")
assert e["xmin"] == pytest.approx(-78.047, abs=TOLERANCE)
assert e["xmax"] == pytest.approx(-77.381, abs=TOLERANCE)
assert e["ymin"] == pytest.approx(24.056, abs=TOLERANCE)
assert e["ymax"] == pytest.approx(24.691, abs=TOLERANCE)
roi = bahamas.extract_roi(-78.047, -77.381, 24.056, 24.691, return_bytes=True)
assert isinstance(roi, ImageBytes)
assert roi.mimetype == "image/tiff"
roi = bahamas.extract_roi(-78.047, -77.381, 24.056, 24.691)
assert roi.metadata()["geospatial"]


@pytest.mark.skipif(skip_shapely, reason="shapely not installed")
def test_extract_roi_world_shape(bahamas_file):
bahamas = RestTileClient(bahamas_file)
poly = box(-78.047, 24.056, -77.381, 24.691)
path = bahamas.extract_roi_shape(poly, return_path=True)
assert path.exists()
source = get_tile_source(path, projection="EPSG:3857")
assert source.getMetadata()["geospatial"]
e = get_tile_bounds(source, projection="EPSG:4326")
assert e["xmin"] == pytest.approx(-78.047, abs=TOLERANCE)
assert e["xmax"] == pytest.approx(-77.381, abs=TOLERANCE)
assert e["ymin"] == pytest.approx(24.056, abs=TOLERANCE)
assert e["ymax"] == pytest.approx(24.691, abs=TOLERANCE)
path = bahamas.extract_roi_shape(poly.wkt, return_path=True)
assert path.exists()


@pytest.mark.skip
def test_extract_roi_pixel(bahamas_file):
bahamas = RestTileClient(bahamas_file)
path = bahamas.extract_roi_pixel(100, 500, 300, 600, return_path=True)
assert path.exists()
source = get_tile_source(path)
assert source.getMetadata()["geospatial"]
assert source.getMetadata()["sizeX"] == 400
assert source.getMetadata()["sizeY"] == 300
roi = bahamas.extract_roi_pixel(100, 500, 300, 600)
assert roi.metadata()["geospatial"]
roi = bahamas.extract_roi_pixel(100, 500, 300, 600, return_bytes=True)
assert isinstance(roi, ImageBytes)


def test_caching_query_params(bahamas_file):
bahamas = RestTileClient(bahamas_file)
thumb_url_a = bahamas.create_url("api/thumbnail.png")
Expand Down Expand Up @@ -215,13 +158,6 @@ def test_pixel(bahamas_file):
assert "bands" in pix


@pytest.mark.skip
def test_histogram(bahamas_file):
bahamas = RestTileClient(bahamas_file)
hist = bahamas.histogram()
assert len(hist)


@pytest.mark.parametrize("encoding", ["PNG", "JPEG", "JPG"])
def test_thumbnail_encodings(bahamas_file, encoding):
bahamas = RestTileClient(bahamas_file)
Expand Down

0 comments on commit 2753554

Please sign in to comment.