Skip to content
Open
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
97 changes: 96 additions & 1 deletion hw1/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,96 @@
from typing import Any, Awaitable, Callable
from http import HTTPStatus
from typing import List
import math, json


def fibonacci(n: int) -> int:
if n in (0, 1):
return n
a, b = 0, 1
for _ in range(2, n):
a, b = b, a + b
return b


async def parse_endpoint(
scope, receive: Callable[[], Awaitable[dict[str, Any]]], status=200
):
path = scope.get("path", None)
if not path:
return 404, None

query_string = scope.get("query_string", b"")

if path.startswith("/fibonacci/"):
try:
n = int(path.split("/fibonacci/")[1])
if n < 0:
return 400, None
return status, fibonacci(n)
except (IndexError, ValueError):
return 422, None

elif path == "/factorial":
query_string = query_string.decode("utf-8")
try:
n = int(query_string.split("n=")[1])
if n < 0:
return 400, None
return status, math.factorial(n)
except (IndexError, ValueError):
return 422, None

elif path == "/mean":

query_string = query_string.decode("utf-8")
event = await receive()
event = event.get("body", b"")

event = json.loads(event.decode())

if event is None:
return 422, None
if len(event) == 0:
return 400, None
try:
numbers = event
numbers = sum(numbers) / len(numbers)
return status, numbers
except (IndexError, ValueError):
return 422, None

return 404, None


async def processor(
scope,
send,
receive: Callable[[], Awaitable[dict[str, Any]]],
):
status, res = await parse_endpoint(scope, receive)

if res is None:
await send(
{
"type": "http.response.start",
"status": status,
"headers": [[b"content-type", b"application/json"]],
}
)
return await send({"type": "http.response.body", "body": b"Not found"})

res = {"result": f"{res}"}
await send(
{
"type": "http.response.start",
"status": status,
"headers": [
[b"content-type", b"application/json"],
],
}
)
return await send({"type": "http.response.body", "body": json.dumps(res).encode()})


async def application(
Expand All @@ -12,8 +104,11 @@ async def application(
receive: Корутина для получения сообщений от клиента
send: Корутина для отправки сообщений клиенту
"""
# TODO: Ваша реализация здесь
# assert scope["type"] == "http"
await processor(scope, send, receive)


if __name__ == "__main__":
import uvicorn

uvicorn.run("app:application", host="0.0.0.0", port=8000, reload=True)
28 changes: 28 additions & 0 deletions hw2/hw/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Use an official Python runtime as a parent image
FROM python:3.9-alpine AS base
ARG PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PIP_NO_CACHE_DIR=on \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=500

RUN python -m pip install --upgrade pip

# Set the working directory in the container
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt
RUN pip install "fastapi[standard]"
RUN pip install sqlalchemy
# Make port 8000 available to the world outside this container
EXPOSE 8080

# Run app.py when the container launches
# CMD ["python", "app.py"]
FROM base AS local
CMD ["fastapi", "dev", "/app/shop_api/main.py", "--port", "8080", "--host", "0.0.0.0"]
Binary file added hw2/hw/assets/hw3.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions hw2/hw/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: "3"

services:

local:
image: hw3/grafana:2025
restart: always
ports:
- 8080:8080

grafana:
image: grafana/grafana:latest
ports:
- 3000:3000
restart: always

prometheus:
image: prom/prometheus
volumes:
- ./settings/prometheus/:/etc/prometheus/
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
ports:
- 9090:9090
restart: always
4 changes: 2 additions & 2 deletions hw2/hw/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Основные зависимости для ASGI приложения
fastapi>=0.117.1
uvicorn>=0.24.0

# Зависимости для тестирования
pytest>=7.4.0
pytest-asyncio>=0.21.0
httpx>=0.27.2
Faker>=37.8.0
pydantic==2.11.10
prometheus-fastapi-instrumentator
10 changes: 10 additions & 0 deletions hw2/hw/settings/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
global:
scrape_interval: 10s
evaluation_interval: 10s

scrape_configs:
- job_name: demo-service-local
metrics_path: /metrics
static_configs:
- targets:
- local:8080
Loading
Loading