From c67049687b3354ff1366d67714e32a83b8a44a82 Mon Sep 17 00:00:00 2001 From: the Date: Wed, 9 Oct 2024 16:17:26 +0400 Subject: [PATCH 1/2] Done --- bogdanov_dmitry_lab_3/.gitignore | 2 + bogdanov_dmitry_lab_3/compose.yaml | 27 ++++ .../messageService/Dockerfile | 11 ++ .../messageService/messageService.py | 138 ++++++++++++++++++ bogdanov_dmitry_lab_3/nginx.conf | 25 ++++ bogdanov_dmitry_lab_3/requirements.txt | 2 + bogdanov_dmitry_lab_3/userService/Dockerfile | 11 ++ .../userService/userService.py | 115 +++++++++++++++ 8 files changed, 331 insertions(+) create mode 100644 bogdanov_dmitry_lab_3/.gitignore create mode 100644 bogdanov_dmitry_lab_3/compose.yaml create mode 100644 bogdanov_dmitry_lab_3/messageService/Dockerfile create mode 100644 bogdanov_dmitry_lab_3/messageService/messageService.py create mode 100644 bogdanov_dmitry_lab_3/nginx.conf create mode 100644 bogdanov_dmitry_lab_3/requirements.txt create mode 100644 bogdanov_dmitry_lab_3/userService/Dockerfile create mode 100644 bogdanov_dmitry_lab_3/userService/userService.py diff --git a/bogdanov_dmitry_lab_3/.gitignore b/bogdanov_dmitry_lab_3/.gitignore new file mode 100644 index 0000000..d326756 --- /dev/null +++ b/bogdanov_dmitry_lab_3/.gitignore @@ -0,0 +1,2 @@ +/.idea +/.venv \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/compose.yaml b/bogdanov_dmitry_lab_3/compose.yaml new file mode 100644 index 0000000..edf8f36 --- /dev/null +++ b/bogdanov_dmitry_lab_3/compose.yaml @@ -0,0 +1,27 @@ +services: + + user_service: + container_name: userService + build: + context: . + dockerfile: ./userService/Dockerfile + expose: + - 20001 + + message_service: + container_name: messageService + build: + context: . + dockerfile: ./messageService/Dockerfile + expose: + - 20002 + + nginx: + image: nginx:latest + ports: + - "80:80" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - user_service + - message_service \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/messageService/Dockerfile b/bogdanov_dmitry_lab_3/messageService/Dockerfile new file mode 100644 index 0000000..af552f9 --- /dev/null +++ b/bogdanov_dmitry_lab_3/messageService/Dockerfile @@ -0,0 +1,11 @@ +FROM python:latest + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY messageService/messageService.py . + +CMD ["python", "messageService.py"] \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/messageService/messageService.py b/bogdanov_dmitry_lab_3/messageService/messageService.py new file mode 100644 index 0000000..537ec83 --- /dev/null +++ b/bogdanov_dmitry_lab_3/messageService/messageService.py @@ -0,0 +1,138 @@ +from flask import Flask, request, jsonify +from uuid import uuid4 +import uuid +import datetime +import requests + +class Message: + def __init__(self, text: str, datetime_sent: datetime, uuid_: uuid, user_id: uuid): + if uuid_ is None: + self.uuid_ = uuid4() + else: + self.uuid_ = uuid.UUID(uuid_) + self.text = text + self.datetime_sent = datetime_sent + self.user_id = uuid.UUID(user_id) + + def to_dict(self): + return { + 'text': self.text, + 'datetime_sent': self.datetime_sent, + 'user_id': self.user_id, + 'uuid': self.uuid_ + } + + def to_dict_for_users(self): + return { + 'title': self.text, + 'datetime_sent': self.datetime_sent, + 'uuid': self.uuid_ + } + + def to_dict_with_info(self, user: dict): + return { + 'title': self.text, + 'datetime_sent': self.datetime_sent, + 'user_id': self.user_id, + 'user_info': user, + 'uuid': self.uuid_ + } + +messages = [ + Message(text='Hi!', datetime_sent=datetime.datetime.now(), uuid_='4add0525-1857-477d-ad35-56790d400b72', user_id='94b171ea-39f6-4a67-9c67-061743f67cfd'), + Message(text='Hello this is a message', datetime_sent=datetime.datetime.now(), uuid_='dd69758d-89e8-49b5-86bf-54ae2adb64e8', user_id='724a3192-70dd-4909-9b0f-c9060a4ab1bd'), + Message(text='Test', datetime_sent=datetime.datetime.now(), uuid_='92389e8d-4365-457e-b37e-78abbc07f194', user_id='94b171ea-39f6-4a67-9c67-061743f67cfd'), + Message(text='Anyone here?', datetime_sent=datetime.datetime.now(), uuid_='f3a1c526-aca2-47e2-afd3-a1c2eac92458', user_id='724a3192-70dd-4909-9b0f-c9060a4ab1bd'), + Message(text='Mambo', datetime_sent=datetime.datetime.now(), uuid_='00abbdb5-e480-4842-bc32-f916894757eb', user_id='46672ea5-3d7b-4137-a0ac-efd898ca4db6') +] + +def list_jsonify(): + return jsonify([message.to_dict() for message in messages]) + + +app = Flask(__name__) +users_url = 'http://userService:20001/' + +@app.route('/', methods=['GET']) +def get_all(): + return list_jsonify(), 200 + +@app.route('/info', methods=['GET']) +def get_all_full(): + users: list[dict] = requests.get(users_url).json() + response = [] + for message in messages: + for user in users: + if message.user_id == uuid.UUID(user.get('uuid')): + response.append(message.to_dict_with_info(user)) + + return response, 200 + +@app.route('/by-user/', methods=['GET']) +def get_by_user_id(user_uuid): + return [message.to_dict_for_users() for message in messages if message.user_id == user_uuid], 200 + +@app.route('/info/', methods=['GET']) +def get_one_full(uuid_): + for message in messages: + if message.uuid_ == uuid_: + response = requests.get(users_url + str(message.user_id)) + return message.to_dict_with_info(response.json()), 200 + + return f'Сообщение с uuid {uuid_} не найдено', 404 + +@app.route('/', methods=['POST']) +def create(): + data = request.json + text = data.get('text', None) + datetime_sent = datetime.datetime.now() + user_id = data.get('user_id', None) + checking = requests.get(users_url + f'/check/{user_id}') + print(checking) + if checking.status_code == 200: + new_message = Message(text, datetime_sent, None, user_id) + messages.append(new_message) + return get_one(new_message.uuid_) + if checking.status_code == 404: + return f'Пользователь с uuid {user_id} не существует', 404 + + return 'Неизвестная ошибка', 500 + +@app.route('/', methods=['PUT']) +def update_by_id(uuid_): + data = request.json + new_text = data.get('text', None) + + for message in messages: + print(message.uuid_) + + if message.uuid_ == uuid_: + if new_text is not None: + message.text = new_text + return get_one(message.uuid_) + + return f'Сообщение с uuid {uuid_} не найдено', 404 + + +@app.route('/', methods=['DELETE']) +def delete(uuid_): + for message in messages: + if message.uuid_ == uuid_: + messages.remove(message) + return 'Сообщение успешно удалено', 200 + + return f'Сообщение с uuid {uuid_} не найдено', 404 + + + +@app.route('/', methods=['GET']) +def get_one(uuid_): + for message in messages: + if message.uuid_ == uuid_: + return message.to_dict(), 200 + + return f'Сообщение с uuid {uuid_} не найдено', 404 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=20002, debug=True) diff --git a/bogdanov_dmitry_lab_3/nginx.conf b/bogdanov_dmitry_lab_3/nginx.conf new file mode 100644 index 0000000..223f1b5 --- /dev/null +++ b/bogdanov_dmitry_lab_3/nginx.conf @@ -0,0 +1,25 @@ +events { worker_connections 1024; } + +http { + server { + listen 80; + listen [::]:80; + server_name localhost; + + location /userService/ { + proxy_pass http://userService:20001/; + 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 /messageService/ { + proxy_pass http://messageService:20002/; + 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; + } + } +} \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/requirements.txt b/bogdanov_dmitry_lab_3/requirements.txt new file mode 100644 index 0000000..494909e --- /dev/null +++ b/bogdanov_dmitry_lab_3/requirements.txt @@ -0,0 +1,2 @@ +Flask==3.0.3 +requests==2.32.3 \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/userService/Dockerfile b/bogdanov_dmitry_lab_3/userService/Dockerfile new file mode 100644 index 0000000..5821a33 --- /dev/null +++ b/bogdanov_dmitry_lab_3/userService/Dockerfile @@ -0,0 +1,11 @@ +FROM python:latest + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY userService/userService.py . + +CMD ["python", "userService.py"] \ No newline at end of file diff --git a/bogdanov_dmitry_lab_3/userService/userService.py b/bogdanov_dmitry_lab_3/userService/userService.py new file mode 100644 index 0000000..b38bcb2 --- /dev/null +++ b/bogdanov_dmitry_lab_3/userService/userService.py @@ -0,0 +1,115 @@ +from flask import Flask, jsonify, request +from uuid import uuid4 +import uuid +import requests + + +class User: + def __init__(self, name, surname, uuid_: uuid): + if uuid_ is None: + self.uuid_: uuid = uuid4() + else: + self.uuid_: uuid = uuid.UUID(uuid_) + self.name: str = name + self.surname: str = surname + + def to_dict(self): + return { + "uuid": self.uuid_, + "name": self.name, + "surname": self.surname + } + + def to_dict_with_messages(self, messages: list): + return { + "uuid": self.uuid_, + "name": self.name, + "surname": self.surname, + "messages": messages + } + + +app = Flask(__name__) + +users: list[User] = [ + User(name='Dr.', surname='Kino', uuid_='94b171ea-39f6-4a67-9c67-061743f67cfd'), + User(name='Caspian', surname='Holstrom', uuid_='724a3192-70dd-4909-9b0f-c9060a4ab1bd'), + User(name='Admin', surname='Admin', uuid_='46672ea5-3d7b-4137-a0ac-efd898ca4db6') +] + +messages_url = 'http://messageService:20002/' + + +def list_jsonify(): + return jsonify([user.to_dict() for user in users]) + +@app.route('/', methods=['GET']) +def get_all(): + return list_jsonify(), 200 + +@app.route('/', methods=['GET']) +def get_one(uuid_): + for user in users: + if user.uuid_ == uuid_: + return user.to_dict(), 200 + + return f'Пользователь с uuid {uuid_} не найден', 404 + +@app.route('/info/', methods=['GET']) +def get_one_with_messages(uuid_): + for user in users: + if user.uuid_ == uuid_: + response = requests.get(messages_url + f'by-user/{uuid_}') + print(response.json()) + return user.to_dict_with_messages(response.json()), 200 + + return f'Пользователь с uuid {uuid_} не найден', 404 + +@app.route('/check/', methods=['GET']) +def check_exist(uuid_): + for user in users: + if user.uuid_ == uuid_: + return '', 200 + return '', 404 + +@app.route('/', methods=['POST']) +def create(): + data = request.json + name = data.get('name', None) + surname = data.get('surname', None) + if name is None or surname is None: + return 'Недостаточно информации для создания пользователя', 404 + + new_user = User(name, surname, None) + users.append(new_user) + return get_one(new_user.uuid_) + +@app.route('/', methods=['PUT']) +def update_by_id(uuid_): + data = request.json + new_name = data.get('name', None) + new_surname = data.get('surname', None) + + for user in users: + if user.uuid_ == uuid_: + if new_name is not None: + user.name = new_name + if new_surname is not None: + user.surname = new_surname + return get_one(user.uuid_) + + return f'Пользователь с uuid {uuid_} не найден', 404 + + +@app.route('/', methods=['DELETE']) +def delete(uuid_): + for user in users: + if user.uuid_ == uuid_: + users.remove(user) + return 'Пользователь удален', 200 + + return f'Пользователь с uuid {uuid_} не найден', 404 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=20001, debug=True) From 735a40302720d8b8f19f66592ec6fab5a3d941bd Mon Sep 17 00:00:00 2001 From: the Date: Wed, 9 Oct 2024 16:38:42 +0400 Subject: [PATCH 2/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bogdanov_dmitry_lab_3/README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 bogdanov_dmitry_lab_3/README.md diff --git a/bogdanov_dmitry_lab_3/README.md b/bogdanov_dmitry_lab_3/README.md new file mode 100644 index 0000000..5c0a67d --- /dev/null +++ b/bogdanov_dmitry_lab_3/README.md @@ -0,0 +1,22 @@ +# Лабораторная работа №3 + +## Богданов Дмитрий ПИбд-42 + +### Для выполнения были выбраны следующие сущности: + +* Message - содержит uuid (генерируется), text, datetime_sent, user_id +* User - содержит uuid (генерируется), name, surname + +Одному пользователю может быть присвоено несколько сообщений. + +Соответственно были развернуты 2 сервиса для управления этими сущностями. + +### Запуск лабораторной: +Необходимо перейти в папку с файлом compose.yaml и ввести следующую команду: +``` +docker-compose up --build -d +``` + +## Видео с результатом запуска и тестами... + +...можно посмотреть по данной [ссылке](https://drive.google.com/file/d/1cJz0z4KduSz1oltmAuieUW7GxxVLNPNo/view). \ No newline at end of file