From b118e1d539b852d80ed1c50b6d1b51210544c430 Mon Sep 17 00:00:00 2001 From: M1000 Date: Fri, 13 Nov 2026 02:27:15 +0300 Subject: [PATCH] Initial FastAPI application --- Dockerfile | 13 +++++++++++++ app/__init__.py | 0 app/main.py | 26 ++++++++++++++++++++++++++ compose.yml | 7 +++++++ requirements.txt | 29 +++++++++++++++++++++++++++++ tests/test_main.py | 23 +++++++++++++++++++++++ 6 files changed, 98 insertions(+) create mode 100644 Dockerfile create mode 100644 app/__init__.py create mode 100644 app/main.py create mode 100644 compose.yml create mode 100644 requirements.txt create mode 100644 tests/test_main.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..efa0c52 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM python:3.12-slim + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY ./app ./app + +EXPOSE 8000 + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..0b1a894 --- /dev/null +++ b/app/main.py @@ -0,0 +1,26 @@ +from fastapi import FastAPI + +app = FastAPI( + title="FastAPI Demo", + description="My first application with FastAPI", + version="1.0.0", +) + + +@app.get("/") +async def root(): + return { + "message": "Hello from FastAPI!", + "application": "fastapi-demo", + "version": "1.0.0", + } + + +@app.get("/health") +async def health(): + return {"status": "ok"} + + +@app.get("/hello/{name}") +async def hello(name: str): + return {"message": f"Hello, {name}!"} diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..921fd00 --- /dev/null +++ b/compose.yml @@ -0,0 +1,7 @@ +services: + app: + build: . + container_name: fastapi-demo + restart: unless-stopped + ports: + - "8000:8000" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..494591e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,29 @@ +annotated-doc==0.0.5 +annotated-types==0.7.0 +anyio==4.12.1 +certifi==2026.10.23 +click==8.1.8 +exceptiongroup==1.3.1 +fastapi==0.128.8 +h11==0.16.0 +httpcore==1.0.9 +httptools==0.9.0 +httpx==0.28.1 +idna==3.20 +iniconfig==2.1.0 +packaging==26.3 +pluggy==1.6.0 +pydantic==2.13.5 +pydantic_core==2.46.5 +Pygments==2.21.0 +pytest==8.4.2 +python-dotenv==1.2.1 +PyYAML==6.0.3 +starlette==0.49.3 +tomli==2.5.0 +typing-inspection==0.4.2 +typing_extensions==4.16.0 +uvicorn==0.39.0 +uvloop==0.23.0 +watchfiles==1.1.1 +websockets==15.0.1 diff --git a/tests/test_main.py b/tests/test_main.py new file mode 100644 index 0000000..f8599e2 --- /dev/null +++ b/tests/test_main.py @@ -0,0 +1,23 @@ +from fastapi.testclient import TestClient + +from app.main import app + +client = TestClient(app) + + +def test_root(): + response = client.get("/") + assert response.status_code == 200 + assert response.json()["message"] == "Hello from FastAPI!" + + +def test_health(): + response = client.get("/health") + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + + +def test_hello(): + response = client.get("/hello/Artem") + assert response.status_code == 200 + assert response.json() == {"message": "Hello, Artem!"}