forked from Alexey/DAS_2024_1
Compare commits
3 Commits
vaksman_va
...
dozorova_a
| Author | SHA1 | Date | |
|---|---|---|---|
| 022e2dc49e | |||
| a54e13f7ee | |||
| 1bb988ea2f |
3
.gitignore → dozorova_alena_lab_6/.gitignore
vendored
3
.gitignore → dozorova_alena_lab_6/.gitignore
vendored
@@ -7,3 +7,6 @@
|
||||
/dozorova_alena_lab_2/ConsoleApp2/.vs
|
||||
/dozorova_alena_lab_2/ConsoleApp2/bin
|
||||
/dozorova_alena_lab_2/ConsoleApp2/obj
|
||||
/dozorova_alena_lab_6/ConsoleApp1/.vs
|
||||
/dozorova_alena_lab_6/ConsoleApp1/bin
|
||||
/dozorova_alena_lab_6/ConsoleApp1/obj
|
||||
10
dozorova_alena_lab_6/ConsoleApp1/ConsoleApp1.csproj
Normal file
10
dozorova_alena_lab_6/ConsoleApp1/ConsoleApp1.csproj
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
25
dozorova_alena_lab_6/ConsoleApp1/ConsoleApp1.sln
Normal file
25
dozorova_alena_lab_6/ConsoleApp1/ConsoleApp1.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35004.147
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1.csproj", "{29269567-7466-4C99-BEEF-F5766BDDFB24}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{29269567-7466-4C99-BEEF-F5766BDDFB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29269567-7466-4C99-BEEF-F5766BDDFB24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29269567-7466-4C99-BEEF-F5766BDDFB24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29269567-7466-4C99-BEEF-F5766BDDFB24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {EDED6E1D-0A86-43F9-94EA-6ADCC1FA1B42}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
55
dozorova_alena_lab_6/ConsoleApp1/Extention.cs
Normal file
55
dozorova_alena_lab_6/ConsoleApp1/Extention.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
public static class Extention
|
||||
{
|
||||
public static int[,] CreateMatrixWithoutColumn(this int[,] matrix, int column)
|
||||
{
|
||||
var result = new int[matrix.GetLength(0), matrix.GetLength(1) - 1];
|
||||
for (int i = 0; i < matrix.GetLength(0); i++)
|
||||
{
|
||||
for (int j = 0; j < matrix.GetLength(1) - 1; j++)
|
||||
{
|
||||
result[i, j] = j < column ? matrix[i, j] : matrix[i, j + 1];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[,] CreateMatrixWithoutRow(this int[,] matrix, int row)
|
||||
{
|
||||
var result = new int[matrix.GetLength(0) - 1, matrix.GetLength(1)];
|
||||
for (int i = 0; i < matrix.GetLength(0) - 1; i++)
|
||||
{
|
||||
for (int j = 0; j < matrix.GetLength(1); j++)
|
||||
{
|
||||
result[i, j] = i < row ? matrix[i, j] : matrix[i + 1, j];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static double CalculateDeterminant(this int[,] matrix)
|
||||
{
|
||||
if (matrix.GetLength(0) == 2)
|
||||
{
|
||||
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
|
||||
}
|
||||
double result = 0;
|
||||
for (var j = 0; j < matrix.GetLength(0); j++)
|
||||
{
|
||||
result += (j % 2 == 1 ? 1 : -1) * matrix[1, j] *
|
||||
matrix.CreateMatrixWithoutColumn(j).CreateMatrixWithoutRow(1).CalculateDeterminant();
|
||||
}
|
||||
//Console.WriteLine("Ко мне пришли с размером " + matrix.GetLength(0));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
dozorova_alena_lab_6/ConsoleApp1/Program.cs
Normal file
87
dozorova_alena_lab_6/ConsoleApp1/Program.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
using ConsoleApp1;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var value = new int[3] {100, 300, 500 };
|
||||
|
||||
foreach(var i in value)
|
||||
{
|
||||
var a = CreateMatrix(i, i);
|
||||
var b = CreateMatrix(i, i);
|
||||
|
||||
List<long> times = new() {};
|
||||
Console.WriteLine("Для пяти потоков: ");
|
||||
for (int j = 1; j <= 10; j++)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
Calculate(a, j);
|
||||
|
||||
sw.Stop();
|
||||
times.Add(sw.ElapsedTicks);
|
||||
}
|
||||
Console.WriteLine("Количество тиков для вычисления матрицы стороной "+i+": "+string.Join("\t", times));
|
||||
|
||||
Console.WriteLine("Для десяти потоков: ");
|
||||
for (int j = 1; j <= 10; j++)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
Calculate(a, j);
|
||||
|
||||
sw.Stop();
|
||||
times.Add(sw.ElapsedTicks);
|
||||
}
|
||||
Console.WriteLine("Количество тиков для вычисления матрицы стороной " + i + ": " + string.Join("\t", times));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static int[,] CreateMatrix(int x, int y)
|
||||
{
|
||||
var rnd = new Random();
|
||||
|
||||
var res = new int[y, x];
|
||||
|
||||
for (int i = 0; i < y; i++)
|
||||
{
|
||||
for (int j = 0; j < x; j++)
|
||||
{
|
||||
res[i, j] = rnd.Next(0, 100);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static double Calculate(int[,] matrix, int maxTask)
|
||||
{
|
||||
double res = 0;
|
||||
|
||||
var semaphore = new SemaphoreSlim(maxTask, maxTask);
|
||||
|
||||
for (var j = 0; j < matrix.GetLength(0) - 1; j++)
|
||||
{
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
semaphore.Wait();
|
||||
res += (j % 2 == 1 ? 1 : -1) * matrix[1, j] *
|
||||
matrix.CreateMatrixWithoutColumn(j).
|
||||
CreateMatrixWithoutRow(1).CalculateDeterminant();
|
||||
}
|
||||
finally { semaphore.Release(); }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
semaphore.Wait(maxTask);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
18
dozorova_alena_lab_6/README.md
Normal file
18
dozorova_alena_lab_6/README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Лабораторная работа 6
|
||||
В рамках данной работы мы изучаем выигрыш при распаралелливании процесса вычисления определителя матрицы
|
||||
## Описание
|
||||
Для вычисления определителя мы используем следующую формулу:
|
||||

|
||||
где  - определитель матрицы, полученной из исходной вырезанием 1 строки и j столбца.
|
||||
|
||||
## Запуск
|
||||
По опыту прошлой лабораторной работы, в консольном приложении был реализован алгоритм вычисление детерминанта и запущено сравнение затраченного времени (в тиках) для 5 и 10 потоков.
|
||||
## Результаты
|
||||
Результаты:
|
||||
<br/>
|
||||

|
||||
<br/>
|
||||
Как мы видим, подтверждаются выводы прошлой лабораторной работы: для небольших матриц выигрыш несущественнен из-за затраты времени на работу с потоком, а для больших эта разница в скорости уже существенна
|
||||
|
||||
## Видеодемонстрация
|
||||
Видеодемонстрация по [адресу](https://drive.google.com/file/d/1LFRNbTAOzg21Du60Ehy9u6HOp9D3sKPm/view?usp=sharing)
|
||||
BIN
dozorova_alena_lab_6/image-1.png
Normal file
BIN
dozorova_alena_lab_6/image-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 556 B |
BIN
dozorova_alena_lab_6/image-2.png
Normal file
BIN
dozorova_alena_lab_6/image-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
BIN
dozorova_alena_lab_6/image.png
Normal file
BIN
dozorova_alena_lab_6/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
@@ -1,64 +0,0 @@
|
||||
# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
|
||||
|
||||
## Задание
|
||||
|
||||
#### Цель:
|
||||
|
||||
Изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
|
||||
|
||||
#### Задачи:
|
||||
|
||||
* Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
|
||||
* Реализовать механизм синхронного обмена сообщениями между микросервисами.
|
||||
* Реализовать шлюз на основе прозрачного прокси-сервера nginx.
|
||||
|
||||
### Сервисы:
|
||||
1. ```product_server``` - сервис, отвечающий за продукты
|
||||
|
||||
2. ```document_server``` - сервис, отвечающий за документы, которые содержат в себе продукты
|
||||
|
||||
#### Связь между сервисами:
|
||||
```document (single) <- product (many)```
|
||||
|
||||
## Как запустить программу:
|
||||
```
|
||||
docker compose up
|
||||
```
|
||||
|
||||
## Файловая иерархия
|
||||
|
||||
```
|
||||
Лаба 3/
|
||||
|-- document_server/
|
||||
| |-- Dockerfile
|
||||
| |-- document_server.py
|
||||
|-- product_server/
|
||||
| |-- Dockerfile
|
||||
| |-- product_server.py
|
||||
|-- nginx.conf
|
||||
|-- docker-compose.yml
|
||||
|-- requirements.txt
|
||||
|-- Test_commands.txt
|
||||
```
|
||||
|
||||
## Описание работы:
|
||||
|
||||
Для разработки приложений был выбран язык программирования - ```python```
|
||||
|
||||
#### Синхронный обмен сообщениями
|
||||
`product_server` будет отправлять http-запрос на `document_server` при определенных crud операциях.
|
||||
|
||||
### Docker-compose
|
||||
|
||||
|
||||
Конфигурационный файл ```docker-сompose``` представляет собой многоконтейнерное приложение с тремя сервисами: ```product_server```, ```document_server``` и ```nginx```. Обязанности маршрутизатора возложены на сервер Nginx
|
||||
|
||||
|
||||
### Nginx
|
||||
|
||||
|
||||
Этот файл представляет собой конфигурацию для ```Nginx```, который является веб-сервером и обратным прокси.
|
||||
|
||||
|
||||
# ВК
|
||||
https://vk.com/video256017065_456239873
|
||||
@@ -1,24 +0,0 @@
|
||||
http://document_server:8008/documents/all/ - get
|
||||
|
||||
http://document_server:8008/documents/9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0 - get
|
||||
|
||||
http://document_server:8008/documents/full/9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0 - get
|
||||
|
||||
http://document_server:8008/documents/ - post
|
||||
title content manager
|
||||
|
||||
http://document_server:8008/ - /documents/9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0 title ПРОВЕРКА manager ПОЛЬЗОВАТЕЛЬ МЕНЕДЖЕР
|
||||
|
||||
http://document_server:8008documents/9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0
|
||||
|
||||
http://product_server:8009/products/all/ - get
|
||||
http://product_server:8009/products/085a7833-e486-4a55-9289-d253e21fe64e - get
|
||||
http://product_server:8009/products/full/085a7833-e486-4a55-9289-d253e21fe64e - get
|
||||
http://product_server:8009/products/list/documents/4a3f30c3-823f-4278-8f98-76177ad083bd - get
|
||||
|
||||
http://product_server:8009/products/ - post
|
||||
name price uuid_document
|
||||
|
||||
http://product_server:8009/products/085a7833-e486-4a55-9289-d253e21fe64e - put
|
||||
|
||||
http://product_server:8009/products/085a7833-e486-4a55-9289-d253e21fe64e - delete
|
||||
@@ -1,27 +0,0 @@
|
||||
services:
|
||||
|
||||
document_server:
|
||||
container_name: document_server
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./document_server/Dockerfile
|
||||
expose:
|
||||
- 8008
|
||||
|
||||
product_server:
|
||||
container_name: product_server
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./product_server/Dockerfile
|
||||
expose:
|
||||
- 8009
|
||||
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
depends_on:
|
||||
- document_server
|
||||
- product_server
|
||||
@@ -1,17 +0,0 @@
|
||||
# Использую базовый образ Python
|
||||
FROM python:3.10-slim
|
||||
|
||||
# Устанавливаю рабочую директорию внутри контейнера
|
||||
WORKDIR /app
|
||||
|
||||
# Копирую файл requirements.txt в контейнер
|
||||
COPY requirements.txt .
|
||||
|
||||
# Устанавливаю зависимости
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Копирую исполняемый файл
|
||||
COPY document_server/main.py .
|
||||
|
||||
# Команда для запуска Python-скрипта
|
||||
CMD ["python", "main.py"]
|
||||
@@ -1,115 +0,0 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel, Field
|
||||
from uuid import UUID, uuid4
|
||||
import requests
|
||||
|
||||
app = FastAPI(title="Document service")
|
||||
|
||||
product_url = 'http://product_server:8009'
|
||||
|
||||
# Добавили автогенерацию уникального идентификатора
|
||||
class Document(BaseModel):
|
||||
uuid_: UUID = Field(default_factory=uuid4)
|
||||
title: str | None
|
||||
content: str | None
|
||||
manager: str | None
|
||||
|
||||
|
||||
# Наше хранилище данных
|
||||
# Пару id указываем явно, остальные генерируются случайно
|
||||
DATA_LIST: list[Document] = [
|
||||
Document(uuid_="4a3f30c3-823f-4278-8f98-76177ad083bd", title="Document 1", content="Content 1", manager="Manager 1"),
|
||||
Document(uuid_="9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0", title="Document 2", content="Content 2", manager="Manager 2"),
|
||||
Document(title="Document 3", content="Content 3", manager="Manager 3"),
|
||||
Document(title="Document 4", content="Content 4", manager="Manager 4"),
|
||||
]
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def redirect_to_docs():
|
||||
return RedirectResponse(url="/docs")
|
||||
|
||||
@app.get("/documents/all/", tags=["Document"])
|
||||
def all_documents():
|
||||
return DATA_LIST
|
||||
|
||||
@app.get("/documents/{document_id}", tags=["Document"])
|
||||
def get_document(document_id: UUID):
|
||||
document = next((x for x in DATA_LIST if x.uuid_ == document_id), None)
|
||||
|
||||
if not document:
|
||||
return HTTPException(status_code=404, detail="Документ не найден")
|
||||
|
||||
return document
|
||||
|
||||
@app.get("/documents/full/{document_id}", tags=["Document"])
|
||||
def get_full_document(document_id: UUID):
|
||||
|
||||
document = next((x for x in DATA_LIST if x.uuid_ == document_id), None)
|
||||
|
||||
if not document:
|
||||
return HTTPException(status_code=404, detail="Продукт не найден")
|
||||
|
||||
result_dict = document.model_dump()
|
||||
|
||||
if type(result_dict['uuid_']) is UUID:
|
||||
products = requests.get(f"{product_url}/products/list/documents/{document_id}")
|
||||
|
||||
if not products:
|
||||
return HTTPException(status_code=404, detail="Продукты не найдены")
|
||||
|
||||
result_dict["products"] = products.json()
|
||||
|
||||
return result_dict
|
||||
|
||||
@app.post("/documents/", tags=["Document"])
|
||||
def create_document(title: str, content: str, manager: str):
|
||||
document = Document(title=title, content=content, manager=manager)
|
||||
|
||||
try:
|
||||
DATA_LIST.append(document)
|
||||
|
||||
return JSONResponse(content={"message": "Успешное создание документа"}, status_code=200)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
return HTTPException(status_code=404, detail={"Неудачная попытка добавления документа": str(e)})
|
||||
|
||||
|
||||
@app.put("/documents/{document_id}", tags=["Document"])
|
||||
def update_document(document_id: UUID, title: str = None, content: str = None, manager: str = None):
|
||||
document = get_document(document_id)
|
||||
|
||||
if type(document) is Document:
|
||||
index = DATA_LIST.index(document)
|
||||
|
||||
if title:
|
||||
DATA_LIST[index].title = title
|
||||
if content:
|
||||
DATA_LIST[index].content = content
|
||||
if manager:
|
||||
DATA_LIST[index].manager = manager
|
||||
|
||||
return JSONResponse(content={"message": "Успешное обновление документа"}, status_code=201)
|
||||
|
||||
else:
|
||||
return HTTPException(status_code=404, detail=document)
|
||||
|
||||
@app.delete("/documents/{document_id}", tags=["Document"])
|
||||
def delete_document(document_id: UUID):
|
||||
document = get_document(document_id)
|
||||
|
||||
if type(document) is Document:
|
||||
index = DATA_LIST.index(document)
|
||||
print(index)
|
||||
del DATA_LIST[index]
|
||||
|
||||
return JSONResponse(content={"message": "Успешное удаление документа"}, status_code=201)
|
||||
|
||||
return HTTPException(status_code=404, detail=document)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8008)
|
||||
@@ -1,25 +0,0 @@
|
||||
events { worker_connections 1024; }
|
||||
|
||||
http {
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
|
||||
location /document_server/ {
|
||||
proxy_pass http://document_server:8008/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /product_server/ {
|
||||
proxy_pass http://product_server:8009/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
# Использую базовый образ Python
|
||||
FROM python:3.10-slim
|
||||
|
||||
# Устанавливаю рабочую директорию внутри контейнера
|
||||
WORKDIR /app
|
||||
|
||||
# Копирую файл requirements.txt в контейнер
|
||||
COPY requirements.txt .
|
||||
|
||||
# Устанавливаю зависимости
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Копирую исполняемый файл
|
||||
COPY product_server/main.py .
|
||||
|
||||
# Команда для запуска Python-скрипта
|
||||
CMD ["python", "main.py"]
|
||||
@@ -1,136 +0,0 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.responses import RedirectResponse
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel, Field
|
||||
from uuid import UUID, uuid4
|
||||
import requests
|
||||
|
||||
app = FastAPI(title="Product service")
|
||||
|
||||
document_url = 'http://document_server:8008'
|
||||
|
||||
# Добавили автогенерацию уникального идентификатора
|
||||
class Product(BaseModel):
|
||||
uuid_: UUID = Field(default_factory=uuid4)
|
||||
name: str | None
|
||||
price: int | None
|
||||
uuid_document: UUID | None
|
||||
|
||||
|
||||
# Наше хранилище данных
|
||||
DATA_LIST: list[Product] = [
|
||||
Product(uuid_="085a7833-e486-4a55-9289-d253e21fe64e",name="Товар 1", price=100, uuid_document="4a3f30c3-823f-4278-8f98-76177ad083bd"),
|
||||
Product(name="Товар 2", price=200, uuid_document="4a3f30c3-823f-4278-8f98-76177ad083bd"),
|
||||
Product(name="Товар 3", price=300, uuid_document="9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0"),
|
||||
Product(name="Товар 4", price=400, uuid_document="9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0"),
|
||||
Product(name="Товар 5", price=500, uuid_document="9c7f1ecb-1aac-4337-bcd0-f863cc73aeb0"),
|
||||
]
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def redirect_to_docs():
|
||||
return RedirectResponse(url="/docs")
|
||||
|
||||
@app.get("/products/all/", tags=["Product"])
|
||||
def all_products():
|
||||
return DATA_LIST
|
||||
|
||||
@app.get("/products/{product_id}", tags=["Product"])
|
||||
def get_product(product_id: UUID):
|
||||
product = next((x for x in DATA_LIST if x.uuid_ == product_id), None)
|
||||
|
||||
if not product:
|
||||
return HTTPException(status_code=404, detail="Продукт не найден")
|
||||
|
||||
return product
|
||||
|
||||
@app.get("/products/full/{product_id}", tags=["Product"])
|
||||
def get_full_product(product_id: UUID):
|
||||
|
||||
product = next((x for x in DATA_LIST if x.uuid_ == product_id), None)
|
||||
|
||||
if not product:
|
||||
return HTTPException(status_code=404, detail="Продукт не найден")
|
||||
|
||||
result_dict = product.model_dump()
|
||||
|
||||
if type(result_dict['uuid_document']) is UUID:
|
||||
document = requests.get(f"{document_url}/documents/{result_dict['uuid_document']}")
|
||||
|
||||
if not document:
|
||||
return HTTPException(status_code=404, detail="Документ не найден")
|
||||
|
||||
result_dict["document"] = document.json()
|
||||
|
||||
del result_dict['uuid_document']
|
||||
|
||||
return result_dict
|
||||
|
||||
@app.get("/products/list/documents/{document_id}", tags=["Product"])
|
||||
def get_list_product_document(document_id: UUID):
|
||||
|
||||
products = (x for x in DATA_LIST if x.uuid_document == document_id)
|
||||
|
||||
if not products:
|
||||
return HTTPException(status_code=404, detail="Продукты не найдены")
|
||||
|
||||
return products
|
||||
|
||||
@app.get("/products/{product_id}", tags=["Product"])
|
||||
def get_product(product_id: UUID):
|
||||
product = next((x for x in DATA_LIST if x.uuid_ == product_id), None)
|
||||
|
||||
if not product:
|
||||
return HTTPException(status_code=404, detail="Продукт не найден")
|
||||
|
||||
return product
|
||||
|
||||
@app.post("/products/", tags=["Product"])
|
||||
def create_product(name: str, price: int, uuid_document: UUID):
|
||||
product = Product(name=name, price=price, uuid_document=uuid_document)
|
||||
|
||||
try:
|
||||
DATA_LIST.append(product)
|
||||
|
||||
return JSONResponse(content={"message": "Успешное создание продукта"}, status_code=200)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
return HTTPException(status_code=404, detail={"Неудачная попытка добавления продукта": str(e)})
|
||||
|
||||
|
||||
@app.put("/products/{product_id}", tags=["Product"])
|
||||
def update_product(product_id: UUID, name: str = None, price: int = None, uuid_document: UUID = None):
|
||||
product = get_product(product_id)
|
||||
|
||||
if type(product) is Product:
|
||||
index = DATA_LIST.index(product)
|
||||
|
||||
if name:
|
||||
DATA_LIST[index].name = name
|
||||
if price:
|
||||
DATA_LIST[index].price = price
|
||||
if uuid_document:
|
||||
DATA_LIST[index].uuid_document = uuid_document
|
||||
|
||||
return JSONResponse(content={"message": "Успешное обновление продукта"}, status_code=201)
|
||||
|
||||
else:
|
||||
return HTTPException(status_code=404, detail=product)
|
||||
|
||||
@app.delete("/products/{product_id}", tags=["Product"])
|
||||
def delete_product(product_id: UUID):
|
||||
product = get_product(product_id)
|
||||
|
||||
if type(product) is Product:
|
||||
index = DATA_LIST.index(product)
|
||||
print(index)
|
||||
del DATA_LIST[index]
|
||||
|
||||
return JSONResponse(content={"message": "Успешное удаление продукта"}, status_code=201)
|
||||
|
||||
return HTTPException(status_code=404, detail=product)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8009)
|
||||
@@ -1,17 +0,0 @@
|
||||
annotated-types==0.7.0
|
||||
anyio==4.6.0
|
||||
certifi==2024.8.30
|
||||
charset-normalizer==3.4.0
|
||||
click==8.1.7
|
||||
exceptiongroup==1.2.2
|
||||
fastapi==0.115.0
|
||||
h11==0.14.0
|
||||
idna==3.10
|
||||
pydantic==2.9.2
|
||||
pydantic_core==2.23.4
|
||||
requests==2.32.3
|
||||
sniffio==1.3.1
|
||||
starlette==0.38.6
|
||||
typing_extensions==4.12.2
|
||||
urllib3==2.2.3
|
||||
uvicorn==0.31.0
|
||||
Reference in New Issue
Block a user