developmentseed / titiler Goto Github PK
View Code? Open in Web Editor NEWBuild your own Raster dynamic map tile services
Home Page: https://developmentseed.org/titiler/
License: MIT License
Build your own Raster dynamic map tile services
Home Page: https://developmentseed.org/titiler/
License: MIT License
I'm wondering if there are alternative deployment scenarios without CDN for titiler.
We've deployed titiler on a large single machine and the performance are of course not a good as your endpoint.
What would be the alternative deployment scenario for acceptable performance on a private cloud? Our use-cases include using titiler for restricted access data in a private cloud deployment.
titiler/titiler/endpoints/cog.py
Line 369 in 24ec8b6
request.url_for
fails to find the correct route when titiler is mounted as a sub application (https://github.com/developmentseed/titiler/blob/nonTMSReader/titiler/endpoints/factory.py#L1013):
from fastapi import FastAPI
from titiler.endpoints.stac import STACTiler
app = FastAPI()
titiler_app = FastAPI()
titiler_app.include_router(STACTiler().router)
app.mount("/titiler", titiler_app)
This is because request.url_for
uses the router of the request's current scope which in this case is app
and not titiler_app
. Because sub applications are independent of the parent app, the titiler routes are not actually registered on app
, so starlette can't find the route and raises starlette.routing.NoMatchFound
.
A solution that works is replacing calls to request.url_for
with self.router.url_path_for
which has the same signature (its called under the hood by request.url_for
) but only searches the specific router, ensuring that route resolution will always work no matter how the app is mounted.
Forgot that @geospatial-jeff warned me about this ๐คฆ
Lines 6 to 15 in 97a5901
Line 50 in 97a5901
having the possibility to manage settings with .env
is still a nice feature and I think we shoud also move the API config to pydantic.BaseSettings
Ref #40 (comment)
The fastapi router defined in titiler.api.api
doesn't really add much. I can see a use case for using an intermediary router if that router used a particular custom defined route class etc. but that isn't the case here. It would be better to attach the routes directly to the fastapi app defined in titiler.main
, remove titiler.api.api
, and maybe rename titiler.main
-> titiler.app
to be more standard with fastapi conventions.
we need better docs
Section/topic
earlier I choose to host the viewer in each endpoints
(e.g stac.py, cog.py) but now I changed my mind ๐ฌ I think the viewer are a nice feature for DEMO purposes but the end goal of titiler is to be an API.
The main goal is to let user do
from fastapi import APIRouter
from titiler.endpoints import cog
api_router = APIRouter()
api_router.include_router(cog.router, prefix="/cog", tags=["Cloud Optimized GeoTIFF"])
I've run into an interesting race condition using titiler with arturo-stac-api. For my use case, I am trying to mount titiler's stac and demo routers onto my stac application. In the stac application I have an endpoint (/collections/{collectionId}/items/{itemId}/tiles
) which, when called with a text/html
accept header, sends a redirect request to the titiler's stac viewer. The call chain looks like:
/collections/{collectionId}/items/{itemId}/tiles
./stac/viewer
/info
/tilejson.json
/tiles
(as tiles render in the browser).**Each request in the browser (2a/2b/2c) does its own GET request to /collections/{collectionId}/items/{itemId}
using the blocking requests
library.
The race condition arises because the application is blocked during 2a/2b/2c as these requests require sending a GET request to the application to fetch the stac item which the application cannot process because it is currently blocked.
Switching all of the appropriate routes in titiler's stac router from async def
to def
fixed this issue, as the blocking call to requests.get
to fetch the stac item is no longer blocking the main thread but instead run in an external threadpool.
Hello,
the README.md says:
:endpoint:/v1/{z}/{x}/{y}[@{scale}x][.{ext}]
(...)
- **url**: Cloud Optimized GeoTIFF URL. **REQUIRED**
I don't quite get where and how the url and the rest of the parameters are specified. Could you provide a specific example?
By the way, the tool seems awesome thanks :)
For sake of code simplicity we will remove those to block
titiler/titiler/endpoints/mosaic.py
Lines 198 to 216 in b6c8132
titiler/titiler/endpoints/mosaic.py
Lines 265 to 301 in b6c8132
The new MosaicBackends has a .tile
and .point
method that will take care of the data fetching directly. This is not async but we plan to make a AsyncMosaicBackends at one point
Users often want to see metadata information on the client about the imagery shown. This is especially true for mosaics, but also desirable for single-scene COG viewing.
I propose adding a response header like X-ASSETS
that returns a comma-separated or JSON-encoded list of asset ids that were used to create the response tile. For many sources, the asset id includes enough information to extract a date range and other helpful metadata.
I forget to update the docs in #32
A recent change in FastAPI/Starlette is breaking some routes (those with escape characters).
I'm going to fix it and pin fastapi version so it doesn't happen again ;-)
Currently the app either returns a 200 on successful request or server error (500) on unsuccessful request. I think there is a lot of value in explicitly raising exceptions for error cases. Most important in my opinion is FileNotFound
and TileNotFound
errors which both should return a 404
status code indicating that the particular file/tile was not found. These status codes, if raised, may be used by the client to infer that there is no imagery available for the particular request and to fall back to another data source or provider.
I think the best way to do this is global exception handlers which return a particular status code whenever a specific exception is raised. This is inline with having standardized exceptions within the app (which is already implemented, although they aren't currently used anywhere).
We are now really close to the next TiTiler release. ๐
We have refactored the code to create a proper python module with helper classes like the new titiler.endpoint.factory.TilerFactory
which will help users to integrate COG/STAC/MosaicJSON tilers (FastAPI router) directly to thier applications
from titiler.endpoints.factory import TilerFactory
from fastapi import FastAPI
app = FastAPI()
cog = TilerFactory()
print([r.path for r in cog.router.routes])
> [
'/openapi.json',
'/docs',
'/docs/oauth2-redirect',
'/redoc',
'/bounds',
'/info',
'/metadata',
'/tiles/{TileMatrixSetId}/{z}/{x}/{y}@{scale}x.{format}',
'/tiles/{TileMatrixSetId}/{z}/{x}/{y}@{scale}x',
'/tiles/{TileMatrixSetId}/{z}/{x}/{y}.{format}',
'/tiles/{TileMatrixSetId}/{z}/{x}/{y}',
'/tiles/{z}/{x}/{y}@{scale}x.{format}',
'/tiles/{z}/{x}/{y}@{scale}x',
'/tiles/{z}/{x}/{y}.{format}',
'/tiles/{z}/{x}/{y}',
'/{TileMatrixSetId}/tilejson.json',
'/tilejson.json',
'/{TileMatrixSetId}/WMTSCapabilities.xml',
'/WMTSCapabilities.xml',
'/point/{lon},{lat}',
'/preview.{format}',
'/preview',
]
app.include_router(cog.router, tags=["Cloud Optimized GeoTIFF"])
Because of the PyPi release I think it makes sense to start the release at version 0.0.1 and get rid of old tags
Right now the autoscaling is based on the number of requests per ecs task
Lines 74 to 81 in 89d8d64
This should enable fast scaling UP when number of user are loading tiles, but there might be better configuration.
setting 1 worker per cpu https://github.com/developmentseed/titiler/blob/master/stack/app.py#L64 seems to resolve this
titiler is built around FastAPI with the idea of using it with ECS, but it seems that with https://github.com/erm/mangum we could also create a lambda handler easily.
right now there is a mismatch between rio-tiler version and it's leading the CI to fail!
In
titiler/titiler/api/endpoints/cog.py
Lines 299 to 308 in 725da5f
dst_crs
) so by default rio-tiler-crs will use the file CRS: https://github.com/cogeotiff/rio-tiler-crs/blob/master/rio_tiler_crs/reader.py#L307-L335
The problem is when passing width and height, we might loose the information about the actual data transform (because the width and height will be relative to the data in the output crs).
We should force the dst_crs
to be the same as the bounds_crs (wgs84) by default on the API side!
titiler/titiler/dependencies.py
Lines 98 to 99 in 97a5901
Having this force to have some custom code which I believe should be left to the user to do (it's really easy to create and pass a PathParams dependency to the factory)
Titiler fails to find location of html templates when installed as a python library because the current template paths are relative and not absolute (ex. https://github.com/developmentseed/titiler/blob/master/titiler/endpoints/stac.py#L35). Using absolute paths to load html templates would fix this issue.
a new rio-tiler version was released today (2.0b1) but there is a lot of breaking changes. For now we should pin rio-tiler to 2.0a11 while waiting to make other changes
let's try morecantile to support more projection
at least for CI and Pypi publish (we could do AWS deploy later)
It looks like most routes which don't implement ImgResponse
are manually setting cache-ttl response headers:
All of these routes (I think) are JSON responses, and should implement a similar JSONResponse
object which automatically sets cache-control rather than defining within the scope of each request. The JSONResponse
object would be very similar to ImgResponse
, but of course implementing a different protocol.
explore deployment using EKS https://aws.amazon.com/fr/eks/
When deploying a new Lambda instance, CDK app has to create the package. We currently use python docker API to run the docker container and create the package
Lines 87 to 101 in 3233807
The process is really slow and caching doesn't seem to be used ๐ค
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.