From 8db51ba6db8cd07b9276b71e855461bc96c4211c Mon Sep 17 00:00:00 2001 From: nick gondek Date: Sat, 6 Jan 2024 21:51:13 +0000 Subject: [PATCH] serving w/ algorithm --- .../tofu/modules/burn_backend/outputs.tf | 4 ++ .deployment/tofu/modules/sftp/main.tf | 19 +++++++++ .deployment/tofu/outputs.tf | 5 +++ app.py | 38 ++++++++++++++--- src/index.html | 41 +++++++++++++------ src/util/sftp.py | 14 +++++-- 6 files changed, 98 insertions(+), 23 deletions(-) diff --git a/.deployment/tofu/modules/burn_backend/outputs.tf b/.deployment/tofu/modules/burn_backend/outputs.tf index e69de29b..e658c1eb 100644 --- a/.deployment/tofu/modules/burn_backend/outputs.tf +++ b/.deployment/tofu/modules/burn_backend/outputs.tf @@ -0,0 +1,4 @@ +output "burn_backend_server_endpoint" { + description = "The endpoint of the Cloud Run burn-backend service" + value = google_cloud_run_v2_service.tf-rest-burn-severity.uri +} \ No newline at end of file diff --git a/.deployment/tofu/modules/sftp/main.tf b/.deployment/tofu/modules/sftp/main.tf index e375d337..355af56f 100644 --- a/.deployment/tofu/modules/sftp/main.tf +++ b/.deployment/tofu/modules/sftp/main.tf @@ -105,6 +105,25 @@ resource "aws_s3_bucket" "burn-severity-backend" { bucket = "burn-severity-backend" # replace with your bucket name } +data "aws_iam_policy_document" "burn-severity-backend-policy" { + statement { + sid = "PublicReadGetObject" + effect = "Allow" + actions = ["s3:GetObject"] + resources = ["${aws_s3_bucket.burn-severity-backend.arn}/*"] + + principals { + type = "*" + identifiers = ["*"] + } + } +} + +resource "aws_s3_bucket_policy" "burn-severity-backend-policy" { + bucket = aws_s3_bucket.burn-severity-backend.id + policy = data.aws_iam_policy_document.burn-severity-backend-policy.json +} + resource "aws_s3_bucket_ownership_controls" "burn-severity-backend" { bucket = aws_s3_bucket.burn-severity-backend.id rule { diff --git a/.deployment/tofu/outputs.tf b/.deployment/tofu/outputs.tf index 6a58f18e..81078cf1 100644 --- a/.deployment/tofu/outputs.tf +++ b/.deployment/tofu/outputs.tf @@ -6,4 +6,9 @@ output "sftp_server_endpoint" { output "sftp_admin_username" { description = "The username of the SFTP admin user" value = module.sftp.sftp_admin_username +} + +output "gcp_cloud_run_endpoint" { + description = "The endpoint of the Cloud Run burn-backend service" + value = module.burn_backend.burn_backend_server_endpoint } \ No newline at end of file diff --git a/app.py b/app.py index 18cf3bb0..9be314d5 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,5 @@ -from fastapi import FastAPI, Depends, HTTPException -from fastapi.responses import HTMLResponse import os +import json from pathlib import Path import uvicorn from pydantic import BaseModel @@ -11,6 +10,9 @@ import requests from fastapi import HTTPException +from fastapi import FastAPI, Depends, HTTPException, Request +from fastapi.responses import HTMLResponse +from fastapi.templating import Jinja2Templates from titiler.core.factory import TilerFactory from titiler.core.errors import DEFAULT_STATUS_CODES, add_exception_handlers @@ -27,6 +29,8 @@ app.include_router(cog.router, prefix='/cog', tags=["Cloud Optimized GeoTIFF"]) add_exception_handlers(app, DEFAULT_STATUS_CODES) +templates = Jinja2Templates(directory="src/") + logging_client = logging.Client(project='dse-nps') log_name = "burn-backend" logger = logging_client.logger(log_name) @@ -68,6 +72,16 @@ def get_sftp_client(): return SFTPClient(SFTP_SERVER_ENDPOINT, SFTP_ADMIN_USERNAME, SSH_SECRET) +def get_manifest(sfpt_client: SFTPClient = Depends(get_sftp_client)): + try: + sfpt_client.connect() + manifest = sfpt_client.get_manifest() + sfpt_client.disconnect() + return manifest + except Exception as e: + logger.log_text(f"Error: {e}") + return f"Error: {e}", 400 + @app.get("/available-cogs") def available_cogs(sftp_client: SFTPClient = Depends(get_sftp_client)): try: @@ -130,7 +144,19 @@ def analyze_burn(body: AnaylzeBurnPOSTBody, sftp_client: SFTPClient = Depends(ge return f"Error: {e}", 400 @app.get("/map/{fire_event_name}", response_class=HTMLResponse) -def serve_map(fire_event_name: str): - html_content = Path("src/index.html").read_text() - logger.log_text(f"Serving map for {fire_event_name}") - return html_content \ No newline at end of file +def serve_map(request: Request, fire_event_name: str, manifest: dict = Depends(get_manifest)): + # tileserver_endpoint = 'https://tf-rest-burn-severity-ohi6r6qs2a-uc.a.run.app' + tileserver_endpoint = 'http://localhost:5050' + cog_url = f"https://burn-severity-backend.s3.us-east-2.amazonaws.com/public/{fire_event_name}/rbr.tif" + cog_tileserver_url_prefix = tileserver_endpoint + f"/cog/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}.png?url={cog_url}&nodata=0&algorithm=classify&algorithm_params=" + # cog_tileserver_url_prefix = tileserver_endpoint + f"/cog/tiles/WebMercatorQuad/{{z}}/{{x}}/{{y}}.png?url={cog_url}" + + fire_metadata = manifest[fire_event_name] + fire_metadata_json = json.dumps(fire_metadata) + + return templates.TemplateResponse("index.html", { + "request": request, + "fire_event_name": fire_event_name, + "fire_metadata_json": fire_metadata_json, + "cog_tileserver_url_prefix": cog_tileserver_url_prefix + }) \ No newline at end of file diff --git a/src/index.html b/src/index.html index d02e9f2f..0d4207e4 100644 --- a/src/index.html +++ b/src/index.html @@ -2,6 +2,7 @@ Leaflet Map + @@ -25,19 +26,33 @@
- + \ No newline at end of file diff --git a/src/util/sftp.py b/src/util/sftp.py index 47319cae..57025fd7 100644 --- a/src/util/sftp.py +++ b/src/util/sftp.py @@ -140,9 +140,8 @@ def upload_cogs(self, metrics_stack, fire_event_name, prefire_date_range, postfi def update_manifest(self, fire_event_name, bounds, prefire_date_range, postfire_date_range): with tempfile.TemporaryDirectory() as tmpdir: - self.download('manifest.json', '/tmp_manifest.json') - self.logger.log_text(f"Downloaded manifest.json") - manifest = json.load(open('/tmp_manifest.json', 'r')) + + manifest = self.get_manifest() if fire_event_name in manifest: self.logger.log_text(f"Fire event {fire_event_name} already exists in manifest. Overwriting.") @@ -182,4 +181,11 @@ def upload_fire_event(self, metrics_stack, fire_event_name, prefire_date_range, bounds=bounds, prefire_date_range=prefire_date_range, postfire_date_range=postfire_date_range - ) \ No newline at end of file + ) + + def get_manifest(self): + with tempfile.TemporaryDirectory() as tmpdir: + self.download('manifest.json', tmpdir + 'tmp_manifest.json') + self.logger.log_text(f"Got manifest.json") + manifest = json.load(open(tmpdir + 'tmp_manifest.json', 'r')) + return manifest \ No newline at end of file