5 Commits
logic ... main

Author SHA1 Message Date
Nicolas Sebastian Schuler
8763e7f741 (fix) add logic to test for message forwarding 2025-07-18 09:58:48 +02:00
8d1f6774b2 app/test_main.py aktualisiert
(fix) remove unnecessary print statement
2025-07-16 17:48:32 +00:00
Nicolas Sebastian Schuler
eaa96ef6ce (feat) add Dockerfile 2025-07-16 10:48:46 +02:00
Nicolas Sebastian Schuler
7f1034a22f (doc,chore) added readme, pin python version 2025-07-16 10:31:57 +02:00
Nicolas Sebastian Schuler
7cbcafbf6e (fix) test case should through error only in range[400,500) 2025-07-16 10:11:48 +02:00
4 changed files with 80 additions and 4 deletions

View File

@@ -1 +1 @@
3.12 3.12.6

16
Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM python:3.12.6
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
ENV UV_COMPILE_BYTECODE=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Copy the project into the image
ADD . /app
# Sync the project into a new environment, asserting the lockfile is up to date
WORKDIR /app
RUN uv sync --locked
ENV PATH="/app/.venv/bin:$PATH"
CMD ["fastapi", "run", "app/main.py", "--port", "80"]

View File

@@ -0,0 +1,39 @@
# Simple Notification Forwarding Application
This Application is a simple REST-API for forwarding notifications.
## Preperations for Virtual Environment
```bash
git clone https://git.n-schuler.dev/nicolas/challenge_cloud_accelerator.git
cd challenge_cloud_accelerator
uv venv .venv && source .venv/bin/activate
uv sync
```
## Usage
```bash
fastapi run app/main.py
```
## Build Docker Image
```bash
docker build -t stack:latest .
```
## Use Docker Image
```bash
docker run -d --name mycontainer -p 80:80 stack:latest
```
## Testing
```bash
source .venv/bin/activate
pytest
```
## Documentation
The OpenAPI Documentation is available at `0.0.0.0:8000/docs`.

View File

@@ -1,8 +1,13 @@
import pytest import pytest
import logging
import json
from httpx import ASGITransport, AsyncClient from httpx import ASGITransport, AsyncClient
from pydantic import ValidationError
from .main import app from .main import app
from .base_types import NotificationType, Notification
LOGGER = logging.getLogger(__name__)
forward_notification_success_req = { forward_notification_success_req = {
"warning": { "warning": {
@@ -49,15 +54,29 @@ forward_notification_fail_req = {
@pytest.mark.anyio @pytest.mark.anyio
async def test_forward_notification_success(): async def test_forward_notification_success(caplog):
for description, req in forward_notification_success_req.items(): for description, req in forward_notification_success_req.items():
async with AsyncClient( async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test" transport=ASGITransport(app=app), base_url="http://test"
) as ac: ) as ac:
print(req)
response = await ac.post("/notification", json=req) response = await ac.post("/notification", json=req)
assert response.status_code == 204, description assert response.status_code == 204, description
match req["Type"]:
case NotificationType.INFO:
pass
case NotificationType.WARNING:
# Check forwarding to logger
try:
res = Notification.model_validate_json(
json_data=json.dumps(req)
)
except ValidationError:
raise Exception(
"Model could not be serialized. Check dummy data"
)
assert str(res) in caplog.text
@pytest.mark.anyio @pytest.mark.anyio
async def test_forward_notification_failure(): async def test_forward_notification_failure():
@@ -66,4 +85,6 @@ async def test_forward_notification_failure():
transport=ASGITransport(app=app), base_url="http://test" transport=ASGITransport(app=app), base_url="http://test"
) as ac: ) as ac:
response = await ac.post("/notification", json=req) response = await ac.post("/notification", json=req)
assert not response.status_code == 204, description assert response.status_code >= 400 and response.status_code < 500, (
description
)