Skip to content

Commit

Permalink
Serve static files (#621)
Browse files Browse the repository at this point in the history
* Add static build dir to gitignore

* Proof of concept serving static files

* Add tests for static file

* Add a placeholder for copying frontend files to Dockerfile

* Add static file server to changelog

* Add docstrings

* Attempt to fix CI tests

* create an index page on startup if it doesn't exist

* update the changelog

* Consolidate calls to WEBAPP_INDEX

* Restore test

Co-authored-by: ThomasLaPiana <[email protected]>
  • Loading branch information
allisonking and ThomasLaPiana authored May 10, 2022
1 parent e2cfd00 commit 0fd1efb
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fidesapi/src/main/resources/application.conf
docs/fides/docs/api/openapi.json
docs/fides/docs/schemas/config_schema.json
fidesapi/build/static

## generic files to ignore
*~
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ The types of changes are:
* Added dependabot to keep dependencies updated
* Include a warning for any orphan datasets as part of the `apply` command.

### Changed

* Comparing server and CLI versions ignores `.dirty` only differences, and is quiet on success when running general CLI commands

### Developer Experience

* Replaced `make` with `nox`
Expand All @@ -37,6 +41,7 @@ The types of changes are:

* Resolved a failure with populating applicable data subject rights to a data map
* Updated `fideslog` to v1.1.5, resolving an issue where some exceptions thrown by the SDK were not handled as expected
* Host static files via fidesapi [#621](https://github.com/ethyca/fides/pull/621)

## [1.6.0](https://github.com/ethyca/fides/compare/1.5.3...1.6.0) - 2022-05-02

Expand All @@ -50,7 +55,6 @@ The types of changes are:

* added isort as a CI check
* Include `tests/` in all static code checks (e.g. `mypy`, `pylint`)
* Comparing server and CLI versions ignores `.dirty` only differences, and is quiet on success when running general CLI commands

### Changed

Expand Down
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ FROM --platform=linux/amd64 python:3.8-slim-buster as base
# Update pip in the base image since we'll use it everywhere
RUN pip install -U pip

####################
## Build frontend ##
####################
FROM base as frontend
# Placeholder until we have a frontend app scaffolded
RUN echo "<h1>Hello world!</h1>" > /tmp/index.html


#######################
## Tool Installation ##
#######################
Expand Down Expand Up @@ -76,6 +84,9 @@ ENV PYTHONUNBUFFERED=TRUE
# Enable detection of running within Docker
ENV RUNNING_IN_DOCKER=TRUE

# Make a static files directory
RUN mkdir -p src/fidesapi/build/static

EXPOSE 8080
CMD ["fidesctl", "webserver"]

Expand All @@ -97,3 +108,6 @@ FROM builder as prod
# Install without a symlink
RUN python setup.py sdist
RUN pip install dist/fidesctl-*.tar.gz

# Copy frontend build over
COPY --from=frontend /tmp/index.html src/fidesapi/build/static/
42 changes: 42 additions & 0 deletions src/fidesapi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
from datetime import datetime
from enum import Enum
from logging import WARNING
from pathlib import Path
from typing import Callable, Dict

from fastapi import FastAPI, Request, Response, status
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from loguru import logger as log
from uvicorn import Config, Server

Expand All @@ -18,6 +21,9 @@
from fidesapi.utils.logger import setup as setup_logging
from fidesctl.core.config import FidesctlConfig, get_config

WEBAPP_DIRECTORY = Path("src/fidesapi/build/static")
WEBAPP_INDEX = WEBAPP_DIRECTORY / "index.html"

app = FastAPI(title="fidesctl")
CONFIG: FidesctlConfig = get_config()

Expand All @@ -42,6 +48,18 @@ async def configure_db(database_url: str) -> None:
await database.init_db(database_url)


@app.on_event("startup")
async def create_webapp_dir_if_not_exists() -> None:
"""Creates the webapp directory if it doesn't exist."""

if not WEBAPP_INDEX.is_file():
WEBAPP_DIRECTORY.mkdir(parents=True, exist_ok=True)
with open(WEBAPP_DIRECTORY / "index.html", "w") as index_file:
index_file.write("<h1>Privacy is a Human Right!</h1>")

app.mount("/static", StaticFiles(directory=WEBAPP_DIRECTORY), name="static")


@app.on_event("startup")
async def setup_server() -> None:
"Run all of the required setup steps for the webserver."
Expand Down Expand Up @@ -114,6 +132,30 @@ async def db_action(action: DBActions) -> Dict:
return {"data": {"message": f"Fidesctl database {action_text}"}}


# Configure the static file paths last since otherwise it will take over all paths
@app.get("/")
def read_index() -> Response:
"""
Return an index.html at the root path
"""
return FileResponse(WEBAPP_INDEX)


@app.get("/{catchall:path}", response_class=FileResponse)
def read_other_paths(request: Request) -> FileResponse:
"""
Return related frontend files. Adapted from https://github.com/tiangolo/fastapi/issues/130
"""
# check first if requested file exists
path = request.path_params["catchall"]
file = WEBAPP_DIRECTORY / Path(path)
if file.exists():
return FileResponse(file)

# otherwise return the index
return FileResponse(WEBAPP_DIRECTORY / "index.html")


def start_webserver() -> None:
"Run the webserver."
server = Server(Config(app, host="0.0.0.0", port=8080, log_level=WARNING))
Expand Down
7 changes: 7 additions & 0 deletions tests/core/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,10 @@ def test_visualize(test_config: FidesctlConfig, resource_type: str) -> None:
f"{test_config.cli.server_url}/{resource_type}/visualize/graphs"
)
assert response.status_code == 200


@pytest.mark.integration
def test_static_sink(test_config: FidesctlConfig) -> None:
"""Make sure we are hosting something at / and not getting a 404"""
response = requests.get(f"{test_config.cli.server_url}")
assert response.status_code == 200

0 comments on commit 0fd1efb

Please sign in to comment.