zinovev_vladimir_lab_3 id ready
This commit is contained in:
78
zinovev_vladimir_lab_3/README.md
Normal file
78
zinovev_vladimir_lab_3/README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Лабораторная работа 3
|
||||
**Цель:** изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
|
||||
|
||||
**Задачи:**
|
||||
|
||||
1. Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
|
||||
2. Реализовать механизм синхронного обмена сообщениями между микросервисами.
|
||||
3. Реализовать шлюз на основе прозрачного прокси-сервера nginx.
|
||||
## Как запустить лабораторную работу
|
||||
1. Установить и запустить Docker Desktop
|
||||
2. Открыть папку с проектом и запустить в ней терминал
|
||||
3. Запустить сервисы командой `docker-compose up --build`.
|
||||
4. Перейти по локальным адресам для работы в Swagger:
|
||||
* localhost:8080/glamping_service/docs/ - **Сервис для управления размещениями в глэмпингах**
|
||||
* localhost:8080/reservation_service/docs/ - **Сервис для управления бронированиями глэмпингов**
|
||||
5. Выполнить CRUD-операции.
|
||||
|
||||
## Какие технологии использовали
|
||||
|
||||
1. Docker - контейнеризация приложений.
|
||||
2. Docker Compose - оркестратор для сбора контейнеров.
|
||||
3. Dockerfile - стандартизированная сборка образов.
|
||||
4. Python - язык программирования для реализации логики сервисов.
|
||||
5. Nginx - API Gateway и прокси-сервер.
|
||||
6. Swagger UI - развёртывание REST API.
|
||||
|
||||
## Особенности реализации
|
||||
|
||||
* При запросе `GET /reservation_service/full/{uuid}` сервис бронирований выполняет синхронный HTTP-запрос к сервису глэмпингов для получения дополнительной информации о размещении.
|
||||
* Nginx выполняет роль API Gateway и проксирует запросы к соответствующим сервисам:
|
||||
-Запросы `/glamping_service/` → glamping_service:8080
|
||||
-Запросы `/reservation_service/` → reservation_service:8081
|
||||
* Для упрощения демонстрации данные хранятся в оперативной памяти в списках.
|
||||
|
||||
## API Endpoints
|
||||
### Glamping Service
|
||||
| Метод | Endpoint | Описание |
|
||||
|--------|-------------------------|-----------------------------------------------------------|
|
||||
|GET | /glamping_service/ | Получение списка глэмпингов |
|
||||
|GET | /glamping_service/{uuid}| Получение глэмпинга по UUID |
|
||||
|GET | /glamping_service/full | Получение всех глэмпингов с информацией о бронированиях |
|
||||
|GET | ..service/full/{uuid} | Получение глэмпинга с информацией о бронированиях по UUID |
|
||||
|GET | ../by-reservation/{uuid}| Получение глэмпинга по UUID бронирования |
|
||||
|GET | ..service/check/{uuid} | Проверка существования глэмпинга по UUID |
|
||||
|POST | /glamping_service/ | Создание нового глэмпинга |
|
||||
|PUT | /glamping_service/{uuid}| Обновление глэмпинга по UUID |
|
||||
|DELETE | /glamping_service/{uuid}| Удаление глэмпинга по UUID |
|
||||
|
||||
### Reservation Service
|
||||
| Метод | Endpoint | Описание |
|
||||
|--------|-------------------------|-----------------------------------------------------------|
|
||||
|GET | /reservation_service/ | Получение списка бронирований |
|
||||
|GET | ..service/{uuid} | Получение бронирования по UUID |
|
||||
|GET | ..service/full | Получение всех бронирований с информацией о глэмпингах |
|
||||
|GET | ..service/full/{uuid} | Получение бронирования с информацией о глэмпинге по UUID |
|
||||
|GET | ../by-glamping/{uuid} | Получение бронирований по размещению в глэмпинге |
|
||||
|POST | /reservation_service/ | Создание нового бронирования |
|
||||
|PUT | ..service/{uuid} | Обновление бронирования по UUID |
|
||||
|DELETE | /..service/{uuid} | Удаление бронирования по UUID |
|
||||
|
||||
**Пример POST-Запроса** для глэмпинга по адресу http://localhost/glamping_service/
|
||||
|
||||
```
|
||||
{
|
||||
"title": "Романтическая юрта",
|
||||
"description": "Уютная юрта для пар с видом на горы",
|
||||
"type": "Юрта",
|
||||
"price_per_night": 200.00,
|
||||
"capacity": 2,
|
||||
"amenities": ["Камин", "Джакузи", "Завтрак"],
|
||||
"location": "Алтай, горный район"
|
||||
}
|
||||
```
|
||||
|
||||
## Тесты
|
||||
|
||||
**Видео:**
|
||||
[Ссылка](https://vk.com/video271933856_456242103?list=ln-Si7duYrJUv89MlSJIt)
|
||||
28
zinovev_vladimir_lab_3/docker-compose.yml
Normal file
28
zinovev_vladimir_lab_3/docker-compose.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
glamping_service:
|
||||
container_name: glamping_service
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./glamping_service/Dockerfile
|
||||
expose:
|
||||
- 8080
|
||||
|
||||
reservation_service:
|
||||
container_name: reservation_service
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./reservation_service/Dockerfile
|
||||
expose:
|
||||
- 8081
|
||||
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
depends_on:
|
||||
- glamping_service
|
||||
- reservation_service
|
||||
12
zinovev_vladimir_lab_3/glamping_service/Dockerfile
Normal file
12
zinovev_vladimir_lab_3/glamping_service/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY glamping_service/glamping_service.py .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["python", "glamping_service.py"]
|
||||
155
zinovev_vladimir_lab_3/glamping_service/glamping_service.py
Normal file
155
zinovev_vladimir_lab_3/glamping_service/glamping_service.py
Normal file
@@ -0,0 +1,155 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional
|
||||
from uuid import UUID, uuid4
|
||||
from datetime import datetime
|
||||
import requests
|
||||
import uvicorn
|
||||
|
||||
app = FastAPI(
|
||||
root_path="/glamping_service",
|
||||
title="Сервис Глэмпингов",
|
||||
description="Сервис для управления размещениями в глэмпингах",
|
||||
version="1.0.0"
|
||||
)
|
||||
|
||||
reservations_url = "http://reservation_service:8081/"
|
||||
|
||||
class Glamping(BaseModel):
|
||||
uuid: UUID
|
||||
title: str
|
||||
description: str
|
||||
type: str
|
||||
price_per_night: float
|
||||
capacity: int
|
||||
amenities: List[str]
|
||||
location: str
|
||||
created_at: datetime
|
||||
|
||||
class GlampingCreate(BaseModel):
|
||||
title: str
|
||||
description: str
|
||||
type: str
|
||||
price_per_night: float
|
||||
capacity: int
|
||||
amenities: List[str] = []
|
||||
location: str
|
||||
|
||||
glamping_accommodations: List[Glamping] = [
|
||||
Glamping(
|
||||
uuid=UUID("89fa1e7a-7e88-445e-a4d8-6d4497ea8f19"),
|
||||
title="Звездный купол",
|
||||
description="Панорамный купол с видом на звезды",
|
||||
type="Геодом",
|
||||
price_per_night=250.00,
|
||||
capacity=2,
|
||||
amenities=["Джакузи", "Кондиционер", "Мини-бар"],
|
||||
location="Карелия, берег озера",
|
||||
created_at=datetime(2023, 10, 18, 5, 41, 0)
|
||||
),
|
||||
Glamping(
|
||||
uuid=UUID("0351ee11-f11b-4d83-b2c8-1075b0c357dc"),
|
||||
title="Лесной люкс",
|
||||
description="Домик на дереве с камином",
|
||||
type="Домик на дереве",
|
||||
price_per_night=180.00,
|
||||
capacity=4,
|
||||
amenities=["Камин", "Терраса", "Гидромассажная ванна"],
|
||||
location="Сибирь, тайга",
|
||||
created_at=datetime(2023, 9, 12, 10, 30, 0)
|
||||
),
|
||||
Glamping(
|
||||
uuid=UUID("dfc17619-7690-47aa-ae8e-6a5068f8ddec"),
|
||||
title="Сафари-палатка",
|
||||
description="Роскошная палатка в стиле сафари",
|
||||
type="Палатка",
|
||||
price_per_night=150.00,
|
||||
capacity=3,
|
||||
amenities=["Собственный бассейн", "Терраса", "Барбекю"],
|
||||
location="Краснодарский край",
|
||||
created_at=datetime(2023, 8, 25, 14, 15, 0)
|
||||
),
|
||||
]
|
||||
|
||||
@app.get("/", response_model=List[Glamping], summary="Получить все домики", description="Получить список всех размещений.")
|
||||
def get_all_glampings():
|
||||
return glamping_accommodations
|
||||
|
||||
@app.get("/full", summary="Получить все глэмпинги с информацией о бронированиях", description="Получить все размещения в глэмпингах с дополнительной информацией о бронированиях.")
|
||||
def get_all_glampings_with_reservations():
|
||||
reservations = requests.get(reservations_url).json()
|
||||
response = []
|
||||
for glamping in glamping_accommodations:
|
||||
glamping_reservations = [r for r in reservations if str(r["glamping_uuid"]) == str(glamping.uuid)]
|
||||
if glamping_reservations:
|
||||
response.append({**glamping.dict(), "reservations_info": glamping_reservations})
|
||||
return response
|
||||
|
||||
@app.get("/by-reservation/{reservation_uuid}", response_model=Optional[Glamping], summary="Получить глэмпинг по бронированию", description="Получить размещение в глэмпинге для заданного бронирования.")
|
||||
def get_glamping_by_reservation(reservation_uuid: UUID):
|
||||
try:
|
||||
reservation = requests.get(f"{reservations_url}{reservation_uuid}").json()
|
||||
if reservation:
|
||||
glamping_uuid = UUID(reservation["glamping_uuid"])
|
||||
glamping = next((g for g in glamping_accommodations if g.uuid == glamping_uuid), None)
|
||||
return glamping
|
||||
except:
|
||||
return None
|
||||
return None
|
||||
|
||||
@app.get("/{glamping_uuid}", response_model=Glamping, summary="Получить глэмпинг по ID", description="Получить одно размещение в глэмпинге по его ID.")
|
||||
def get_glamping_by_id(glamping_uuid: UUID):
|
||||
glamping = next((glamping for glamping in glamping_accommodations if glamping.uuid == glamping_uuid), None)
|
||||
if not glamping:
|
||||
raise HTTPException(status_code=404, detail="Размещение не найдено")
|
||||
return glamping
|
||||
|
||||
@app.get("/full/{glamping_uuid}", summary="Получить глэмпинг с информацией о бронированиях", description="Получить размещение в глэмпинге с дополнительной информацией о бронированиях.")
|
||||
def get_glamping_with_reservation_info(glamping_uuid: UUID):
|
||||
glamping = next((glamping for glamping in glamping_accommodations if glamping.uuid == glamping_uuid), None)
|
||||
if not glamping:
|
||||
raise HTTPException(status_code=404, detail="Размещение не найдено")
|
||||
|
||||
glamping_reservations = requests.get(f"{reservations_url}by-glamping/{glamping_uuid}").json()
|
||||
return {**glamping.dict(), "reservations_info": glamping_reservations}
|
||||
|
||||
@app.post("/", response_model=Glamping, summary="Создать новый глэмпинг", description="Добавить новое размещение в глэмпинге в бд.")
|
||||
def create_glamping(glamping: GlampingCreate):
|
||||
new_glamping = Glamping(
|
||||
uuid=uuid4(),
|
||||
created_at=datetime.now(),
|
||||
**glamping.dict()
|
||||
)
|
||||
glamping_accommodations.append(new_glamping)
|
||||
return new_glamping
|
||||
|
||||
@app.put("/{glamping_uuid}", response_model=Glamping, summary="Обновить глэмпинг", description="Обновить существующее размещение по его ID.")
|
||||
def update_glamping(glamping_uuid: UUID, glamping_update: GlampingCreate):
|
||||
glamping = next((glamping for glamping in glamping_accommodations if glamping.uuid == glamping_uuid), None)
|
||||
if not glamping:
|
||||
raise HTTPException(status_code=404, detail="Размещение не найдено")
|
||||
|
||||
glamping.title = glamping_update.title
|
||||
glamping.description = glamping_update.description
|
||||
glamping.type = glamping_update.type
|
||||
glamping.price_per_night = glamping_update.price_per_night
|
||||
glamping.capacity = glamping_update.capacity
|
||||
glamping.amenities = glamping_update.amenities
|
||||
glamping.location = glamping_update.location
|
||||
return glamping
|
||||
|
||||
@app.delete("/{glamping_uuid}", summary="Удалить глэмпинг", description="Удалить размещение в глэмпинге по его ID.")
|
||||
def delete_glamping(glamping_uuid: UUID):
|
||||
global glamping_accommodations
|
||||
glamping_accommodations = [glamping for glamping in glamping_accommodations if glamping.uuid != glamping_uuid]
|
||||
return {"detail": "Размещение успешно удалено"}
|
||||
|
||||
@app.get("/check/{glamping_uuid}", summary="Проверить существование глэмпинга", description="Проверить существование размещения в глэмпинге.")
|
||||
def check_glamping_exists(glamping_uuid: UUID):
|
||||
glamping = next((glamping for glamping in glamping_accommodations if glamping.uuid == glamping_uuid), None)
|
||||
if not glamping:
|
||||
raise HTTPException(status_code=404, detail="Глэмпинг не существует")
|
||||
return {"detail": "Глэмпинг существует"}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("glamping_service:app", host="0.0.0.0", port=8080, reload=True)
|
||||
54
zinovev_vladimir_lab_3/nginx.conf
Normal file
54
zinovev_vladimir_lab_3/nginx.conf
Normal file
@@ -0,0 +1,54 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream glamping_service {
|
||||
server glamping_service:8080;
|
||||
}
|
||||
|
||||
upstream reservation_service {
|
||||
server reservation_service:8081;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# Glamping service routes
|
||||
location /glamping_service/ {
|
||||
proxy_pass http://glamping_service/;
|
||||
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;
|
||||
}
|
||||
|
||||
# Reservation service routes
|
||||
location /reservation_service/ {
|
||||
proxy_pass http://reservation_service/;
|
||||
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;
|
||||
}
|
||||
|
||||
# Documentation routes
|
||||
location /glamping_service/docs {
|
||||
proxy_pass http://glamping_service/docs;
|
||||
}
|
||||
|
||||
location /reservation_service/docs {
|
||||
proxy_pass http://reservation_service/docs;
|
||||
}
|
||||
|
||||
# OpenAPI routes
|
||||
location /glamping_service/openapi.json {
|
||||
proxy_pass http://glamping_service/openapi.json;
|
||||
}
|
||||
|
||||
location /reservation_service/openapi.json {
|
||||
proxy_pass http://reservation_service/openapi.json;
|
||||
}
|
||||
}
|
||||
}
|
||||
4
zinovev_vladimir_lab_3/requirements.txt
Normal file
4
zinovev_vladimir_lab_3/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
fastapi==0.104.1
|
||||
uvicorn[standard]==0.24.0
|
||||
pydantic==2.5.0
|
||||
requests==2.31.0
|
||||
12
zinovev_vladimir_lab_3/reservation_service/Dockerfile
Normal file
12
zinovev_vladimir_lab_3/reservation_service/Dockerfile
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY reservation_service/reservation_service.py .
|
||||
|
||||
EXPOSE 8081
|
||||
|
||||
CMD ["python", "reservation_service.py"]
|
||||
@@ -0,0 +1,196 @@
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional
|
||||
from uuid import UUID, uuid4
|
||||
from datetime import datetime, date
|
||||
import requests
|
||||
import uvicorn
|
||||
|
||||
app = FastAPI(
|
||||
root_path="/reservation_service",
|
||||
title="Сервис Бронирований",
|
||||
description="Сервис для управления бронированиями глэмпингов",
|
||||
version="1.0.0"
|
||||
)
|
||||
|
||||
# URL для доступа к сервису глэмпингов
|
||||
glampings_url = "http://glamping_service:8080/"
|
||||
|
||||
class Reservation(BaseModel):
|
||||
uuid: UUID
|
||||
client_full_name: str
|
||||
client_email: str
|
||||
client_phone: str
|
||||
check_in_date: date
|
||||
check_out_date: date
|
||||
guests_count: int
|
||||
status: str
|
||||
total_price: float
|
||||
glamping_uuid: UUID
|
||||
created_at: datetime
|
||||
|
||||
class ReservationCreate(BaseModel):
|
||||
client_full_name: str
|
||||
client_email: str
|
||||
client_phone: str
|
||||
check_in_date: date
|
||||
check_out_date: date
|
||||
guests_count: int
|
||||
glamping_uuid: UUID
|
||||
|
||||
class GlampingInfo(BaseModel):
|
||||
title: str
|
||||
type: str
|
||||
price_per_night: float
|
||||
capacity: int
|
||||
location: str
|
||||
|
||||
reservations: List[Reservation] = [
|
||||
Reservation(
|
||||
uuid=UUID("8f036445-a5bd-401c-926e-840f9de795cd"),
|
||||
client_full_name="Иванов Иван Иванович",
|
||||
client_email="ivanov@example.com",
|
||||
client_phone="+79161234567",
|
||||
check_in_date=date(2024, 7, 15),
|
||||
check_out_date=date(2024, 7, 20),
|
||||
guests_count=2,
|
||||
status="подтверждено",
|
||||
total_price=1250.00,
|
||||
glamping_uuid=UUID("89fa1e7a-7e88-445e-a4d8-6d4497ea8f19"),
|
||||
created_at=datetime(2024, 6, 1, 10, 0, 0)
|
||||
),
|
||||
Reservation(
|
||||
uuid=UUID("8740d660-b251-4272-8535-be7ec3748d4b"),
|
||||
client_full_name="Петрова Мария Сергеевна",
|
||||
client_email="petrova@example.com",
|
||||
client_phone="+79169876543",
|
||||
check_in_date=date(2024, 8, 1),
|
||||
check_out_date=date(2024, 8, 7),
|
||||
guests_count=4,
|
||||
status="ожидает подтверждения",
|
||||
total_price=1080.00,
|
||||
glamping_uuid=UUID("0351ee11-f11b-4d83-b2c8-1075b0c357dc"),
|
||||
created_at=datetime(2024, 6, 5, 14, 30, 0)
|
||||
),
|
||||
Reservation(
|
||||
uuid=UUID("a1b2c3d4-e29b-41d4-a716-446655440001"),
|
||||
client_full_name="Сидоров Алексей Петрович",
|
||||
client_email="sidorov@example.com",
|
||||
client_phone="+79165554433",
|
||||
check_in_date=date(2024, 9, 10),
|
||||
check_out_date=date(2024, 9, 15),
|
||||
guests_count=3,
|
||||
status="подтверждено",
|
||||
total_price=750.00,
|
||||
glamping_uuid=UUID("dfc17619-7690-47aa-ae8e-6a5068f8ddec"),
|
||||
created_at=datetime(2024, 7, 20, 9, 15, 0)
|
||||
),
|
||||
]
|
||||
|
||||
@app.get("/", response_model=List[Reservation], summary="Получить все бронирования", description="Получить список всех бронирований.")
|
||||
def get_all_reservations():
|
||||
return reservations
|
||||
|
||||
@app.get("/full", summary="Получить все бронирования с информацией о глэмпингах", description="Получить все бронирования с дополнительной информацией о глэмпингах.")
|
||||
def get_all_reservations_with_glamping_info():
|
||||
glampings = requests.get(glampings_url).json()
|
||||
response = []
|
||||
for reservation in reservations:
|
||||
glamping_info = next((g for g in glampings if g["uuid"] == str(reservation.glamping_uuid)), None)
|
||||
if glamping_info:
|
||||
response.append({
|
||||
**reservation.dict(),
|
||||
"glamping_info": {
|
||||
"title": glamping_info["title"],
|
||||
"type": glamping_info["type"],
|
||||
"price_per_night": glamping_info["price_per_night"],
|
||||
"capacity": glamping_info["capacity"],
|
||||
"location": glamping_info["location"]
|
||||
}
|
||||
})
|
||||
return response
|
||||
|
||||
@app.get("/by-glamping/{glamping_uuid}", response_model=List[Reservation], summary="Получить бронирования по глэмпингу", description="Получить все бронирования для указанного глэмпинга.")
|
||||
def get_reservations_by_glamping(glamping_uuid: UUID):
|
||||
return [reservation for reservation in reservations if reservation.glamping_uuid == glamping_uuid]
|
||||
|
||||
@app.get("/{reservation_uuid}", response_model=Reservation, summary="Получить бронирование по ID", description="Получить одно бронирование по его ID.")
|
||||
def get_reservation_by_id(reservation_uuid: UUID):
|
||||
reservation = next((reservation for reservation in reservations if reservation.uuid == reservation_uuid), None)
|
||||
if not reservation:
|
||||
raise HTTPException(status_code=404, detail="Бронирование не найдено")
|
||||
return reservation
|
||||
|
||||
@app.get("/full/{reservation_uuid}", summary="Получить бронирование с информацией о глэмпинге", description="Получить бронирование с дополнительной информацией о глэмпинге.")
|
||||
def get_reservation_with_glamping_info(reservation_uuid: UUID):
|
||||
reservation = next((reservation for reservation in reservations if reservation.uuid == reservation_uuid), None)
|
||||
if not reservation:
|
||||
raise HTTPException(status_code=404, detail="Бронирование не найдено")
|
||||
|
||||
# Синхронный обмен с glamping-service
|
||||
glamping_info = requests.get(f"{glampings_url}{reservation.glamping_uuid}").json()
|
||||
return {
|
||||
**reservation.dict(),
|
||||
"glamping_info": {
|
||||
"title": glamping_info["title"],
|
||||
"type": glamping_info["type"],
|
||||
"price_per_night": glamping_info["price_per_night"],
|
||||
"capacity": glamping_info["capacity"],
|
||||
"location": glamping_info["location"]
|
||||
}
|
||||
}
|
||||
|
||||
@app.post("/", response_model=Reservation, summary="Создать новое бронирование", description="Добавить новое бронирование в базу данных.")
|
||||
def create_reservation(reservation: ReservationCreate):
|
||||
# Проверяем существование глэмпинга
|
||||
response = requests.get(f"{glampings_url}check/{reservation.glamping_uuid}")
|
||||
if response.status_code == 404:
|
||||
raise HTTPException(status_code=404, detail="Размещение в глэмпинге не найдено")
|
||||
|
||||
# Получаем информацию о глэмпинге для расчета цены
|
||||
glamping_info = requests.get(f"{glampings_url}{reservation.glamping_uuid}").json()
|
||||
|
||||
# Рассчитываем общую стоимость
|
||||
nights = (reservation.check_out_date - reservation.check_in_date).days
|
||||
total_price = glamping_info["price_per_night"] * nights
|
||||
|
||||
# Создаем новое бронирование
|
||||
new_reservation = Reservation(
|
||||
uuid=uuid4(),
|
||||
status="ожидает подтверждения",
|
||||
total_price=total_price,
|
||||
created_at=datetime.now(),
|
||||
**reservation.dict()
|
||||
)
|
||||
reservations.append(new_reservation)
|
||||
return new_reservation
|
||||
|
||||
@app.put("/{reservation_uuid}", response_model=Reservation, summary="Обновить бронирование", description="Обновить существующее бронирование по его ID.")
|
||||
def update_reservation(reservation_uuid: UUID, reservation_update: ReservationCreate):
|
||||
reservation = next((reservation for reservation in reservations if reservation.uuid == reservation_uuid), None)
|
||||
if not reservation:
|
||||
raise HTTPException(status_code=404, detail="Бронирование не найдено")
|
||||
|
||||
reservation.client_full_name = reservation_update.client_full_name
|
||||
reservation.client_email = reservation_update.client_email
|
||||
reservation.client_phone = reservation_update.client_phone
|
||||
reservation.check_in_date = reservation_update.check_in_date
|
||||
reservation.check_out_date = reservation_update.check_out_date
|
||||
reservation.guests_count = reservation_update.guests_count
|
||||
reservation.glamping_uuid = reservation_update.glamping_uuid
|
||||
|
||||
# Пересчитываем цену
|
||||
glamping_info = requests.get(f"{glampings_url}{reservation.glamping_uuid}").json()
|
||||
nights = (reservation.check_out_date - reservation.check_in_date).days
|
||||
reservation.total_price = glamping_info["price_per_night"] * nights
|
||||
|
||||
return reservation
|
||||
|
||||
@app.delete("/{reservation_uuid}", summary="Удалить бронирование", description="Удалить бронирование по его ID.")
|
||||
def delete_reservation(reservation_uuid: UUID):
|
||||
global reservations
|
||||
reservations = [reservation for reservation in reservations if reservation.uuid != reservation_uuid]
|
||||
return {"detail": "Бронирование успешно удалено"}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("reservation_service:app", host="0.0.0.0", port=8081, reload=True)
|
||||
Reference in New Issue
Block a user