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

Edge release #30

Merged
merged 19 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv/
.vscode/
25 changes: 17 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
branches: ["**"]
pull_request:
branches: [develop, edge]
workflow_dispatch: {}

env:
DOCKER_IMAGE: ghcr.io/brewblox/brewblox-tilt

jobs:
build:
Expand All @@ -17,13 +21,13 @@ jobs:
- uses: docker/setup-buildx-action@v2
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.11"

- name: Get image metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ghcr.io/brewblox/brewblox-tilt
images: ${{ env.DOCKER_IMAGE }}

- name: ghcr.io login
uses: docker/login-action@v2
Expand All @@ -33,10 +37,15 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install dependencies
- name: Install Apt dependencies
run: >
sudo apt update &&
sudo apt install -y --no-install-recommends
libbluetooth-dev
libatlas-base-dev

- name: Install Python dependencies
run: |
sudo apt update
sudo apt install -y libbluetooth-dev
python -m pip install --upgrade pip
pip install poetry wheel
poetry install
Expand All @@ -46,9 +55,9 @@ jobs:
poetry run pytest
poetry run flake8

- name: Run setup script
- name: Build
run: |
bash docker/before_build.sh
poetry run invoke build

- name: Build Docker image
uses: docker/build-push-action@v4
Expand All @@ -57,4 +66,4 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
context: docker
context: .
7 changes: 4 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
"python.defaultInterpreterPath": ".venv/bin/python",
"python.terminal.activateEnvInCurrentTerminal": true,
"python.terminal.activateEnvironment": true,
"python.linting.flake8Enabled": true,
"python.linting.pylintEnabled": false,
"python.testing.pytestArgs": [
"--no-cov",
"."
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.languageServer": "Pylance"
"python.languageServer": "Pylance",
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8"
}
}
45 changes: 45 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
FROM python:3.11-bookworm as base

ENV PIP_EXTRA_INDEX_URL=https://www.piwheels.org/simple
ENV PIP_FIND_LINKS=/wheeley
ENV VENV=/app/.venv
ENV PATH="$VENV/bin:$PATH"

COPY ./dist /app/dist

RUN <<EOF
set -ex

mkdir /wheeley
python3 -m venv $VENV
pip3 install --upgrade pip wheel setuptools
pip3 wheel --wheel-dir=/wheeley -r /app/dist/requirements.txt
pip3 wheel --wheel-dir=/wheeley /app/dist/*.tar.gz
EOF

FROM python:3.11-slim-bookworm
WORKDIR /app

ENV PIP_FIND_LINKS=/wheeley
ENV VENV=/app/.venv
ENV PATH="$VENV/bin:$PATH"

COPY --from=base /wheeley /wheeley
COPY ./parse_appenv.py ./parse_appenv.py
COPY ./entrypoint.sh ./entrypoint.sh

RUN <<EOF
set -ex

apt-get update
apt-get install -y --no-install-recommends \
libopenblas-dev
rm -rf /var/cache/apt/archives /var/lib/apt/lists

python3 -m venv $VENV
pip3 install --no-index brewblox_tilt
pip3 freeze
rm -rf /wheeley
EOF

ENTRYPOINT ["bash", "./entrypoint.sh"]
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ sudo apt update && sudo apt install -y libbluetooth-dev
To build a local Docker image:

```bash
bash docker/before_build.sh
docker build --tag brewblox/brewblox-tilt:local docker
poetry run invoke image
```

A `docker-compose.yml` file that uses `brewblox/brewblox-tilt:local` is present in the repository root.
This builds the Python package and then the Dockerfile as `ghcr.io/brewblox/brewblox-tilt:local`.

A `docker-compose.yml` file that uses `ghcr.io/brewblox/brewblox-tilt:local` is present in the repository root.

To start it, run:

Expand Down
57 changes: 0 additions & 57 deletions brewblox_tilt/__main__.py

This file was deleted.

51 changes: 51 additions & 0 deletions brewblox_tilt/app_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import logging
from contextlib import AsyncExitStack, asynccontextmanager
from pprint import pformat

from fastapi import FastAPI

from . import broadcaster, mqtt, parser, scanner, stored, utils

LOGGER = logging.getLogger(__name__)


def setup_logging(debug: bool):
level = logging.DEBUG if debug else logging.INFO
unimportant_level = logging.INFO if debug else logging.WARN
format = '%(asctime)s.%(msecs)03d [%(levelname).1s:%(name)s:%(lineno)d] %(message)s'
datefmt = '%Y/%m/%d %H:%M:%S'

logging.basicConfig(level=level, format=format, datefmt=datefmt)
logging.captureWarnings(True)

logging.getLogger('gmqtt').setLevel(unimportant_level)
logging.getLogger('httpx').setLevel(unimportant_level)
logging.getLogger('httpcore').setLevel(logging.WARN)
logging.getLogger('uvicorn.access').setLevel(unimportant_level)
logging.getLogger('uvicorn.error').disabled = True
logging.getLogger('bleak.backends.bluezdbus.manager').setLevel(unimportant_level)


@asynccontextmanager
async def lifespan(app: FastAPI):
LOGGER.info(utils.get_config())
LOGGER.debug('LOGGERS:\n' + pformat(logging.root.manager.loggerDict))

async with AsyncExitStack() as stack:
await stack.enter_async_context(mqtt.lifespan())
await stack.enter_async_context(broadcaster.lifespan())
yield


def create_app() -> FastAPI:
config = utils.get_config()
setup_logging(config.debug)

# Call setup functions for modules
mqtt.setup()
stored.setup()
parser.setup()
scanner.setup()

app = FastAPI(lifespan=lifespan)
return app
Loading