Skip to content

Commit

Permalink
Make static dir configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
mattupstate committed Feb 2, 2024
1 parent 3aeffaa commit 923442d
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ venv/
ENV/
env.bak/
venv.bak/
dist/

# mypy
.mypy_cache/
Expand Down
8 changes: 5 additions & 3 deletions CI.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ async def test():
".venv",
".vscode",
"**/*/__pycache__",
"dist",
"node_modules",
"test-results",
"example_app/static/bundles",
".gitgnore",
"CI.py",
"docker-compose.yaml",
"webpack-stats.json",
],
)
Expand Down Expand Up @@ -50,8 +52,8 @@ async def test():
.with_exec(["poetry", "run", "playwright", "install", "chromium"])
.with_directory("/src", source_code)
.with_directory(
"/src/example_app/static/bundles",
javascript.directory("/src/example_app/static/bundles"),
"/opt/app/static/js",
javascript.directory("/src/dist/js"),
)
.with_exec(["poetry", "install", "--without", "playwright"])
.with_exec(["poetry", "run", "pytest"])
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ RUN apt-get update \
ADD pyproject.toml poetry.lock /usr/src/
RUN pip install poetry
RUN poetry config virtualenvs.in-project true
RUN poetry install --no-ansi --no-dev && rm pyproject.toml poetry.lock
RUN poetry install --no-ansi --without playwright,dev && rm pyproject.toml poetry.lock


FROM python:3.12-slim
WORKDIR /app
COPY --from=python-build /usr/src /app
COPY --from=static-build /usr/src/example_app/static/bundles /app/example_app/static/bundles
COPY --from=static-build /usr/src/dist/js /opt/app/static/js
ADD ./example_app /app/example_app
RUN addgroup --gid 1000 app
RUN adduser app -h /app -u 1000 -G app -DH
USER 1000
EXPOSE 8000
ENTRYPOINT [".venv/bin/python", "-m", "example_app"]
ENTRYPOINT [".venv/bin/python", "-m", "example_app", "run", "--debug", "--log-level", "debug"]
13 changes: 11 additions & 2 deletions example_app/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ def cli():
@click.option("--debug", is_flag=True, default=False, help="Enable debug mode")
@click.option("--reload", is_flag=True, default=False, help="Reload code on changes")
@click.option("--log-level", default="info", help="Log level")
def run(host: str, port: int, debug: bool, reload: bool, log_level: str):
@click.option(
"--static-dir",
default="/opt/app/static",
help="Filesystem path to static files directory",
)
def run(
host: str, port: int, debug: bool, reload: bool, log_level: str, static_dir: str
):
configure_logging(log_level)
run_server(host, port, reload, log_level, AppConfig(debug=debug))
run_server(
host, port, reload, log_level, AppConfig(debug=debug, static_dir=static_dir)
)
22 changes: 15 additions & 7 deletions example_app/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
from litestar.channels.backends.redis import RedisChannelsPubSubBackend
from litestar.static_files import StaticFilesConfig
from redis.asyncio import Redis

from example_app.etc import app_resource

from example_app.routes import index, ws
from example_app.templates import template_config
from example_app.templates import create_template_config


def create_redis_client(uri: str):
Expand All @@ -19,22 +19,30 @@ def create_redis_client(uri: str):
class AppConfig:
debug: bool = False
redis_uri: str = "redis://redis:6379/0"
static_dir: str = "/opt/app/static"


def create_app(options: AppConfig):
redis = create_redis_client(options.redis_uri)
def create_app(config: AppConfig):
redis = create_redis_client(config.redis_uri)

channels_plugin = ChannelsPlugin(
backend=RedisChannelsPubSubBackend(redis=redis),
arbitrary_channels_allowed=True,
create_ws_route_handlers=False,
)

template_config = create_template_config(
app_resource("templates"), config.static_dir
)

static_files_config = StaticFilesConfig(
directories=[config.static_dir], path="/static"
)

return Litestar(
[index, ws],
debug=config.debug,
template_config=template_config,
static_files_config=[
StaticFilesConfig(directories=[app_resource("static")], path="/static"),
],
static_files_config=[static_files_config],
plugins=[channels_plugin],
)
35 changes: 20 additions & 15 deletions example_app/templates.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import json

import structlog

from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.template.config import TemplateConfig
from pathlib import Path

from example_app.etc import app_resource
log: structlog.BoundLogger = structlog.get_logger()


def webpack_bundle(_, name: str):
manifest_file = app_resource("static/bundles/manifest.json")
webpack_bundles = json.load(open(manifest_file))
return webpack_bundles[name]
def make_callback(static_dir: str):
def webpack_bundle(_, name: str):
manifest_file = Path(static_dir) / "js/manifest.json"
webpack_bundles = json.load(open(manifest_file))
return webpack_bundles[name]

def callback(engine: JinjaTemplateEngine) -> None:
engine.register_template_callable(
key="webpack_bundle",
template_callable=webpack_bundle,
)

def register_template_callables(engine: JinjaTemplateEngine) -> None:
engine.register_template_callable(
key="webpack_bundle",
template_callable=webpack_bundle,
)
return callback


template_config = TemplateConfig(
directory=Path(__file__).parent / "templates",
engine=JinjaTemplateEngine,
engine_callback=register_template_callables,
)
def create_template_config(template_dir: str, static_dir: str):
return TemplateConfig(
directory=template_dir,
engine=JinjaTemplateEngine,
engine_callback=make_callback(static_dir),
)
11 changes: 11 additions & 0 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from litestar.status_codes import HTTP_200_OK
from litestar.testing import TestClient
from example_app.factory import AppConfig, create_app


def test_index_page():
config = AppConfig(debug=True)
app = create_app(config)
with TestClient(app=app) as client:
response = client.get("/")
assert response.status_code == HTTP_200_OK
54 changes: 27 additions & 27 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
const path = require("path");
const webpack = require("webpack");
const BundleTracker = require("webpack-bundle-tracker");
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");

module.exports = {
context: __dirname,
entry: {
"main": "./static/js/index.js",
},
output: {
path: path.resolve(__dirname, "example_app/static/bundles/"),
filename: "[name]-[contenthash].js",
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.ttf$/,
type: 'asset/resource'
}
]
},
plugins: [
new BundleTracker({ path: __dirname, filename: "webpack-stats.json" }),
new WebpackManifestPlugin({
publicPath: "static/bundles"
}),
context: __dirname,
entry: {
main: "./static/js/index.js",
},
output: {
path: path.resolve(__dirname, "./dist/js"),
filename: "[name]-[contenthash].js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.ttf$/,
type: "asset/resource",
},
],
};
},
plugins: [
new BundleTracker({ path: __dirname, filename: "webpack-stats.json" }),
new WebpackManifestPlugin({
publicPath: "static/js",
}),
],
};

0 comments on commit 923442d

Please sign in to comment.