Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serve static files #621

Merged
merged 11 commits into from
May 10, 2022
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 @@ -35,6 +39,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 @@ -48,7 +53,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