Skip to content

Commit

Permalink
feat: develop the rest api
Browse files Browse the repository at this point in the history
  • Loading branch information
billsioros committed Jul 23, 2024
1 parent a01d36a commit 3f27a6e
Show file tree
Hide file tree
Showing 21 changed files with 315 additions and 170 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/devcontainers/python:1-3.11-bullseye
FROM mcr.microsoft.com/devcontainers/python:3.11-bullseye

# Set up zsh
RUN apt-get update && \
Expand Down
1 change: 0 additions & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->

- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.

---

Expand Down
55 changes: 40 additions & 15 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
version: "3.8"
services:
frontend:
env_file: .env
# build: ../fe/
restart: unless-stopped
container_name: frontend
ports:
- 3000:3000
networks:
- network
depends_on:
backend:
condition: service_healthy
notifications:
condition: service_started
# frontend:
# env_file: .env
# build: ../fe/
# restart: unless-stopped
# container_name: frontend
# ports:
# - 3000:3000
# networks:
# - network
# depends_on:
# backend:
# condition: service_healthy
# notifications:
# condition: service_started
backend:
env_file: .env
# build: .
build:
context: .
dockerfile: ./src/heartbeat/Dockerfile
restart: unless-stopped
container_name: backend
ports:
Expand All @@ -31,6 +33,29 @@ services:
interval: 5s
timeout: 10s
retries: 10
database:
env_file: .env
container_name: database
image: postgres:15-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- pgdata:/var/lib/postgresql/data
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
ports:
- "5432:5432"
networks:
- network
restart: on-failure
healthcheck:
test: pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}
interval: 5s
timeout: 10s
retries: 10
volumes:
pgdata:
networks:
network:
driver: bridge
40 changes: 1 addition & 39 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 20 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core>=1"]
requires = [
"poetry-core>=1",
]

[tool.poetry]
name = "heartbeat"
version = "0.1.0"
description = "A heart failure detection system"
readme = "README.md"
authors = ["Vassilis Sioros <[email protected]>"]
authors = [ "Vassilis Sioros <[email protected]>" ]
license = "MIT"
homepage = "https://billsioros.github.io/heartbeat"
repository = "https://github.com/billsioros/heartbeat"
keywords = []
keywords = [ ]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
Expand All @@ -22,6 +24,9 @@ classifiers = [
"Bug Tracker" = "https://github.com/billsioros/heartbeat/issues"
"Changelog" = "https://github.com/billsioros/heartbeat/releases"

[tool.poetry.scripts]
manage = "heartbeat.cli.manage:cli"

[tool.poetry.dependencies]
python = "^3.11"
pydantic = "^2.8.2"
Expand All @@ -31,7 +36,8 @@ uvicorn = "^0.30.3"
gunicorn = "^22.0.0"
sqlalchemy = "^2.0.31"
psycopg2-binary = "^2.9.9"
alembic = "^1.13.2"
typer = "^0.12.3"
rich = "^13.7.1"

[tool.poetry.group.dev.dependencies]
python-semantic-release = "7.34.6"
Expand Down Expand Up @@ -114,7 +120,7 @@ select = [
"UP",
"YTT",
]
ignore = []
ignore = [ ]

fixable = [
"A",
Expand Down Expand Up @@ -162,7 +168,7 @@ fixable = [
"UP",
"YTT",
]
unfixable = []
unfixable = [ ]

per-file-ignores = {}

Expand All @@ -175,12 +181,12 @@ pydocstyle.convention = "google"
[tool.docformatter]
black = true
non-strict = true
non-cap = ["heartbeat"]
non-cap = [ "heartbeat" ]
recursive = true
in-place = true

[tool.mypy]
files = ["src/api"]
files = [ "src/api" ]
warn_unused_configs = true
warn_return_any = true
ignore_missing_imports = true
Expand All @@ -199,7 +205,7 @@ upload_to_pypi = false

[tool.vulture]
min_confidence = 95
paths = ["src/api"]
paths = [ "src/api" ]

[tool.poe.tasks]

Expand All @@ -223,6 +229,10 @@ cmd = "poetry run mypy"
help = "Lint your code for errors"
cmd = "poetry run ruff ."

[tool.poe.tasks.manage]
help = "Manage the application"
cmd = "poetry run manage"

[tool.bandit]
recursive = true
exclude_dirs = ["tests"]
exclude_dirs = [ "tests" ]
4 changes: 2 additions & 2 deletions src/heartbeat/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ENV PYTHONFAULTHANDLER=1 \
POETRY_HOME=/opt/poetry \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=0 \
POETRY_VERSION=1.2.2
POETRY_VERSION=1.6.1

ENV POETRY_CACHE_DIR=${POETRY_HOME}/.cache \
PATH=${POETRY_HOME}/bin:${PATH}
Expand Down Expand Up @@ -53,7 +53,7 @@ ENV PORT=8000

COPY --from=build-base ${WORKSPACE} ${WORKSPACE}

COPY src ${WORKSPACE}
COPY ./src ${WORKSPACE}

EXPOSE ${PORT}

Expand Down
6 changes: 3 additions & 3 deletions src/heartbeat/app.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import functools

import uvicorn
from fastapi import APIRouter, FastAPI

from heartbeat.controllers.monitor_controller import api as monitor_controller
from heartbeat.controllers.user_controller import api as user_controller
from heartbeat.settings import Settings


def initialize_api() -> FastAPI:
return FastAPI(
title="heartbeat",
title="HeartBeat",
description="A heart failure detection system",
version="1.0.0",
contact={
Expand All @@ -30,6 +29,7 @@ def register_controllers(app: FastAPI, prefix: str = "") -> FastAPI:
api = APIRouter(prefix=f"/api{prefix}")

api.include_router(user_controller)
api.include_router(monitor_controller)

app.include_router(api)

Expand Down
Empty file added src/heartbeat/cli/__init__.py
Empty file.
Empty file.
44 changes: 44 additions & 0 deletions src/heartbeat/cli/commands/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from typing import TYPE_CHECKING

import typer

from heartbeat.cli.utils.gui import show_error, show_table

if TYPE_CHECKING:
from heartbeat.resources.database import Database

group: typer.Typer = typer.Typer()


@group.callback()
def db():
"""Database related commands."""


@group.command()
def create(ctx: typer.Context):
"""Create the database."""
db: Database = ctx.obj["database"]

db.create_database()


@group.command()
def show(ctx: typer.Context):
"""List all the tables."""
db: Database = ctx.obj["database"]

for model_class, entries in db.list_all_tables():
show_table(model_class.__name__, entries)


@group.command()
def drop(ctx: typer.Context):
"""Drop all the tables."""
db: Database = ctx.obj["database"]

answer = typer.prompt(f"Drop all tables in '{db._engine.url}' (yes/no) ?")

if answer.lower() == "yes":
for error in db.drop_all_tables():
show_error(error)
43 changes: 43 additions & 0 deletions src/heartbeat/cli/manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import subprocess
import webbrowser
from typing import Optional

import typer

from heartbeat.cli.commands.database import group as database
from heartbeat.resources.database import Database
from heartbeat.settings import Settings

cli: typer.Typer = typer.Typer()


@cli.callback(name="heartbeat")
def main(ctx: typer.Context):
"""NotOnMyWatch CLI."""

settings = Settings()
database = Database(str(settings.database.uri))

ctx.obj = {"settings": settings, "database": database}


cli.add_typer(database, name="database")


@cli.command()
def serve(port: int = 8000, build: bool = False):
"""Serve the application on localhost."""
cmd = ["docker-compose", "up", "--force-recreate", "-d"]
if build:
cmd = ["docker-compose", "up", "--force-recreate", "--build", "-d"]

try:
subprocess.run(cmd)
except subprocess.CalledProcessError as e:
raise typer.Exit(code=e.returncode)

webbrowser.open(f"http://localhost:{port}")


if __name__ == "__main__":
cli()
Empty file.
19 changes: 19 additions & 0 deletions src/heartbeat/cli/utils/gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from collections.abc import Iterable
from typing import Any

from rich.console import Console
from rich.table import Table

console: Console = Console()
error_console = Console(stderr=True, style="bold red")


def show_table(title: str, rows: Iterable[Any]) -> None:
table = Table(title)
for row in rows:
table.add_row(repr(row))
console.print(table)


def show_error(error: str):
error_console.print(error)
Loading

0 comments on commit 3f27a6e

Please sign in to comment.