From 81a06185d5060d7b7f18d3a413bb6f7405c683f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A7=D0=B5=D1=80?= =?UTF-8?q?=D0=BD=D1=8B=D1=88=D0=BE=D0=B2?= Date: Wed, 11 Dec 2024 21:51:40 +0400 Subject: [PATCH 1/2] Chernyshov Nikita Lab2 is Ready --- chernyshov_nikita_lab_2/README.md | 22 +++++++++++ chernyshov_nikita_lab_2/app_1/Dockerfile | 20 ++++++++++ chernyshov_nikita_lab_2/app_1/main.py | 38 +++++++++++++++++++ chernyshov_nikita_lab_2/app_2/Dockerfile | 7 ++++ chernyshov_nikita_lab_2/app_2/main.py | 25 ++++++++++++ chernyshov_nikita_lab_2/docker-compose.yml | 22 +++++++++++ .../generator_of_data/Dockerfile | 7 ++++ .../generator_of_data/generate_data.py | 27 +++++++++++++ 8 files changed, 168 insertions(+) create mode 100644 chernyshov_nikita_lab_2/README.md create mode 100644 chernyshov_nikita_lab_2/app_1/Dockerfile create mode 100644 chernyshov_nikita_lab_2/app_1/main.py create mode 100644 chernyshov_nikita_lab_2/app_2/Dockerfile create mode 100644 chernyshov_nikita_lab_2/app_2/main.py create mode 100644 chernyshov_nikita_lab_2/docker-compose.yml create mode 100644 chernyshov_nikita_lab_2/generator_of_data/Dockerfile create mode 100644 chernyshov_nikita_lab_2/generator_of_data/generate_data.py diff --git a/chernyshov_nikita_lab_2/README.md b/chernyshov_nikita_lab_2/README.md new file mode 100644 index 0000000..d1b8854 --- /dev/null +++ b/chernyshov_nikita_lab_2/README.md @@ -0,0 +1,22 @@ +## Лабораторная работа №2 + + +**App 1: Программа 4 - Количество символов в именах файлов из каталога /var/data** + +- Формирует файл /var/result/data.txt так, что каждая строка файла - количество символов в именах файлов из каталога /var/data. + +**App 2: Программа 3 - Количество чисел в последовательности** + +- Ищет набольшее число из файла /var/result/data.txt и сохраняет количество таких чисел из последовательности в /var/result/result.txt. + +**Структура проекта:** + +1. В папках app_1, app_2 лежат выполняемые файлы .py и Dockerfile с нужным кодом. +2. В папке generator_of_data лежат выполняемые файлы для создания данных. +3. В папке data лежат файлы, длину имен которых нужно посчитать. +4. В папке result лежат файлы с результатами выполнения программ. data.txt - результат выполнения main.py (app_1), result.txt - результат выполнения main.py (app_2). Данные в result рассчитываются из данных data. +5. docker-compose.yml - для определения и управления контейнерами Docker. + +**Команда для запуска** - docker-compose up + +**Ссылка на видео:** https://vkvideo.ru/video286865610_456239225?list=ln-Xqg7SupM1CohXsGRZK \ No newline at end of file diff --git a/chernyshov_nikita_lab_2/app_1/Dockerfile b/chernyshov_nikita_lab_2/app_1/Dockerfile new file mode 100644 index 0000000..0690732 --- /dev/null +++ b/chernyshov_nikita_lab_2/app_1/Dockerfile @@ -0,0 +1,20 @@ +# Используем образ Python 3.9-slim как основу для нашего контейнера. +# slim-версия образа более компактная, что делает контейнер меньше. +FROM python:3.9-slim +# Устанавливаем рабочую директорию в контейнере как /app. +# Все последующие команды будут выполняться в этой директории. +WORKDIR /app +# Копируем файл main.py из текущей директории в директорию /app в контейнере. +COPY . /app +# Определяем команду, которая будет выполняться при запуске контейнера. +# В данном случае запускается Python-скрипт main.py. +CMD ["python", "main.py"] + + + + + + + + + diff --git a/chernyshov_nikita_lab_2/app_1/main.py b/chernyshov_nikita_lab_2/app_1/main.py new file mode 100644 index 0000000..5e945ea --- /dev/null +++ b/chernyshov_nikita_lab_2/app_1/main.py @@ -0,0 +1,38 @@ +import os + +def get_file_with_most_lines(directory): + max_lines = 0 + target_file = "" + + for filename in os.listdir(directory): + filepath = os.path.join(directory, filename) + if os.path.isfile(filepath): + with open(filepath, 'r') as f: + line_count = sum(1 for _ in f) + if line_count > max_lines: + max_lines = line_count + target_file = filename + + return target_file + +def copy_file(src_directory, dest_directory, filename): + src_filepath = os.path.join(src_directory, filename) + dest_filepath = os.path.join(dest_directory, 'data.txt') + + os.makedirs(dest_directory, exist_ok=True) + + with open(src_filepath, 'r') as src_file: + with open(dest_filepath, 'w') as dest_file: + dest_file.write(src_file.read()) + +def main(): + src_directory = '/var/data' + dest_directory = '/var/result' + + target_file = get_file_with_most_lines(src_directory) + if target_file: + copy_file(src_directory, dest_directory, target_file) + print(f"File {target_file} copied to {dest_directory}/data.txt") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/chernyshov_nikita_lab_2/app_2/Dockerfile b/chernyshov_nikita_lab_2/app_2/Dockerfile new file mode 100644 index 0000000..946d3a7 --- /dev/null +++ b/chernyshov_nikita_lab_2/app_2/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . /app + +CMD ["python", "main.py"] \ No newline at end of file diff --git a/chernyshov_nikita_lab_2/app_2/main.py b/chernyshov_nikita_lab_2/app_2/main.py new file mode 100644 index 0000000..b25deb9 --- /dev/null +++ b/chernyshov_nikita_lab_2/app_2/main.py @@ -0,0 +1,25 @@ +import os + +def get_largest_number_from_file(filepath): + with open(filepath, 'r') as f: + numbers = [int(line.strip()) for line in f.readlines()] + return max(numbers) + +def save_square_of_number(number, output_filepath): + result = number ** 2 + with open(output_filepath, 'w') as f: + f.write(str(result)) + +def main(): + input_filepath = '/var/result/data.txt' + output_filepath = '/var/result/result.txt' + + if os.path.exists(input_filepath): + largest_number = get_largest_number_from_file(input_filepath) + save_square_of_number(largest_number, output_filepath) + print(f"Largest number squared: {largest_number}^2 saved to {output_filepath}") + else: + print(f"Input file {input_filepath} not found!") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/chernyshov_nikita_lab_2/docker-compose.yml b/chernyshov_nikita_lab_2/docker-compose.yml new file mode 100644 index 0000000..5f2cb34 --- /dev/null +++ b/chernyshov_nikita_lab_2/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3' +services: + generator_of_data: + build: + context: ./generator_of_data + volumes: + - ./data:/var/data + app_1: + build: + context: ./app_1 + volumes: + - ./data:/var/data + - ./result:/var/result + depends_on: + - generator_of_data + app_2: + build: + context: ./app_2 + volumes: + - ./result:/var/result + depends_on: + - app_1 diff --git a/chernyshov_nikita_lab_2/generator_of_data/Dockerfile b/chernyshov_nikita_lab_2/generator_of_data/Dockerfile new file mode 100644 index 0000000..9ce2be9 --- /dev/null +++ b/chernyshov_nikita_lab_2/generator_of_data/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . /app + +CMD ["python", "generate_data.py"] \ No newline at end of file diff --git a/chernyshov_nikita_lab_2/generator_of_data/generate_data.py b/chernyshov_nikita_lab_2/generator_of_data/generate_data.py new file mode 100644 index 0000000..913ba85 --- /dev/null +++ b/chernyshov_nikita_lab_2/generator_of_data/generate_data.py @@ -0,0 +1,27 @@ +import os +import random + +def generate_random_files(directory, num_files, num_lines_per_file, min_value, max_value): + os.makedirs(directory, exist_ok=True) + + for i in range(num_files): + file_path = os.path.join(directory, f"file_{i + 1}.txt") + with open(file_path, 'w') as f: + for _ in range(num_lines_per_file): + random_number = random.randint(min_value, max_value) + f.write(f"{random_number}\n") + print(f"Generated file: {file_path}") + +def main(): + data_directory = '/var/data' + num_files = 10 + num_lines_per_file = 12 + min_value = 1 + max_value = 100 + + generate_random_files(data_directory, num_files, num_lines_per_file, min_value, max_value) + print(f"Generated {num_files} files in {data_directory}") + + +if __name__ == "__main__": + main() \ No newline at end of file -- 2.25.1 From 6abb0ee2635b928427baafea59a15b40588491b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A7=D0=B5=D1=80?= =?UTF-8?q?=D0=BD=D1=8B=D1=88=D0=BE=D0=B2?= Date: Fri, 13 Dec 2024 15:11:06 +0400 Subject: [PATCH 2/2] Chernyshov Nikita Lab3 is Ready --- chernyshov_nikita_lab_3/README.md | 36 +++++++++++++ chernyshov_nikita_lab_3/docker-compose.yml | 26 +++++++++ .../games_service/Dockerfile | 10 ++++ chernyshov_nikita_lab_3/games_service/main.py | 53 +++++++++++++++++++ .../games_service/requirements.txt | 1 + .../genres_service/Dockerfile | 10 ++++ .../genres_service/main.py | 51 ++++++++++++++++++ .../genres_service/requirements.txt | 1 + chernyshov_nikita_lab_3/nginx/nginx.conf | 11 ++++ 9 files changed, 199 insertions(+) create mode 100644 chernyshov_nikita_lab_3/README.md create mode 100644 chernyshov_nikita_lab_3/docker-compose.yml create mode 100644 chernyshov_nikita_lab_3/games_service/Dockerfile create mode 100644 chernyshov_nikita_lab_3/games_service/main.py create mode 100644 chernyshov_nikita_lab_3/games_service/requirements.txt create mode 100644 chernyshov_nikita_lab_3/genres_service/Dockerfile create mode 100644 chernyshov_nikita_lab_3/genres_service/main.py create mode 100644 chernyshov_nikita_lab_3/genres_service/requirements.txt create mode 100644 chernyshov_nikita_lab_3/nginx/nginx.conf diff --git a/chernyshov_nikita_lab_3/README.md b/chernyshov_nikita_lab_3/README.md new file mode 100644 index 0000000..c097b0f --- /dev/null +++ b/chernyshov_nikita_lab_3/README.md @@ -0,0 +1,36 @@ + +## Лабораторная работа №3 + +### Цель: +* Реализовать два микросервиса, которые взаимодействуют друг с другом через синхронный обмен сообщениями (HTTP-запросы). Для доступа к микросервисам используется шлюз Nginx, реализованный с помощью Docker Compose. + +### Технологии: + +* Python: Язык программирования для реализации микросервисов. +* Flask: Фреймворк Python для создания веб-приложений, использован для создания REST API микросервисов. +* requests: Библиотека Python для отправки HTTP-запросов, использован для синхронного обмена сообщениями между микросервисами. +* flask_cors: Расширение Flask, которое позволяет микросервисам получать доступ к данным из других доменов. +* Docker: Технология контейнеризации для упаковки и запуска микросервисов. +* Docker Compose: Инструмент для определения и управления многоконтейнерными приложениями, использован для запуска микросервисов и шлюза Nginx. +* Nginx: Сетевой прокси-сервер, использован как шлюз для доступа к микросервисам. + +### Функциональность: + +#### Микросервис games-service: +* Реализует CRUD операции для игр (GET, POST, PUT, DELETE). +* Сохраняет данные о играх в памяти (в словаре games). +* Получает информацию о жанре из микросервиса genres-service через HTTP-запрос. +* Включает информацию о жанре в ответ JSON для игры. +#### Микросервис genres-service: +* Реализует CRUD операции для жанров (GET, POST, PUT, DELETE). +* Сохраняет данные о жанре в памяти (в словаре genres). +#### Шлюз Nginx: +* Перенаправляет HTTP-запросы на соответствующие микросервисы. +* Предоставляет единую точку входа для доступа к микросервисам. + +### Запуск программы: + +* Запуск команды docker-compose up --build + +### Ссылка на видео: +https://vkvideo.ru/video286865610_456239226?list=ln-U577n85GB3sBxUtF34 \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/docker-compose.yml b/chernyshov_nikita_lab_3/docker-compose.yml new file mode 100644 index 0000000..4c732d2 --- /dev/null +++ b/chernyshov_nikita_lab_3/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3.8' + +services: + games_service: + build: + context: ./games_service + dockerfile: Dockerfile + ports: + - "5000:5000" + + genres_service: + build: + context: ./genres_service + dockerfile: Dockerfile + ports: + - "5001:5001" + + nginx: + image: nginx:latest + volumes: + - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf + ports: + - "80:80" + depends_on: + - games_service + - genres_service diff --git a/chernyshov_nikita_lab_3/games_service/Dockerfile b/chernyshov_nikita_lab_3/games_service/Dockerfile new file mode 100644 index 0000000..851c5df --- /dev/null +++ b/chernyshov_nikita_lab_3/games_service/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.11 + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["python", "main.py"] \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/games_service/main.py b/chernyshov_nikita_lab_3/games_service/main.py new file mode 100644 index 0000000..3bf68bf --- /dev/null +++ b/chernyshov_nikita_lab_3/games_service/main.py @@ -0,0 +1,53 @@ +from flask import Flask, jsonify, request +import uuid + +app = Flask(__name__) + +games = {} + + +@app.route('/games', methods=['GET']) +def get_games(): + return jsonify(list(games.values())) + +@app.route('/games/', methods=['GET']) +def get_game(game_uuid): + game = games.get(str(game_uuid)) + if game: + return jsonify(game) + return jsonify({'error': 'Not found'}), 404 + +@app.route('/games', methods=['POST']) +def create_game(): + data = request.get_json() + game_uuid = str(uuid.uuid4()) + game = { + 'uuid': game_uuid, + 'name': data['name'], + 'developer': data['developer'], + 'genres': data.get('genres', []) # List of genre UUIDs + } + games[game_uuid] = game + return jsonify(game), 201 + +@app.route('/games/', methods=['PUT']) +def update_game(game_uuid): + game = games.get(str(game_uuid)) + if not game: + return jsonify({'error': 'Not found'}), 404 + data = request.get_json() + game['name'] = data['name'] + game['developer'] = data['developer'] + game['genres'] = data.get('genres', []) + return jsonify(game) + +@app.route('/games/', methods=['DELETE']) +def delete_game(game_uuid): + if str(game_uuid) in games: + del games[str(game_uuid)] + return '', 204 + return jsonify({'error': 'Not found'}), 404 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/games_service/requirements.txt b/chernyshov_nikita_lab_3/games_service/requirements.txt new file mode 100644 index 0000000..2077213 --- /dev/null +++ b/chernyshov_nikita_lab_3/games_service/requirements.txt @@ -0,0 +1 @@ +Flask \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/genres_service/Dockerfile b/chernyshov_nikita_lab_3/genres_service/Dockerfile new file mode 100644 index 0000000..851c5df --- /dev/null +++ b/chernyshov_nikita_lab_3/genres_service/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.11 + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD ["python", "main.py"] \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/genres_service/main.py b/chernyshov_nikita_lab_3/genres_service/main.py new file mode 100644 index 0000000..f652c60 --- /dev/null +++ b/chernyshov_nikita_lab_3/genres_service/main.py @@ -0,0 +1,51 @@ +from flask import Flask, jsonify, request +import uuid + +app = Flask(__name__) + +genres = {} + + +@app.route('/genres', methods=['GET']) +def get_genres(): + return jsonify(list(genres.values())) + +@app.route('/genres/', methods=['GET']) +def get_genre(genre_uuid): + genre = genres.get(str(genre_uuid)) + if genre: + return jsonify(genre) + return jsonify({'error': 'Not found'}), 404 + +@app.route('/genres', methods=['POST']) +def create_genre(): + data = request.get_json() + genre_uuid = str(uuid.uuid4()) + genre = { + 'uuid': genre_uuid, + 'name': data['name'], + 'description': data['description'] + } + genres[genre_uuid] = genre + return jsonify(genre), 201 + +@app.route('/genres/', methods=['PUT']) +def update_genre(genre_uuid): + genre = genres.get(str(genre_uuid)) + if not genre: + return jsonify({'error': 'Not found'}), 404 + data = request.get_json() + genre['name'] = data['name'] + genre['description'] = data['description'] + return jsonify(genre) + +@app.route('/genres/', methods=['DELETE']) +def delete_genre(genre_uuid): + if str(genre_uuid) in genres: + del genres[str(genre_uuid)] + return '', 204 + return jsonify({'error': 'Not found'}), 404 + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5001) \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/genres_service/requirements.txt b/chernyshov_nikita_lab_3/genres_service/requirements.txt new file mode 100644 index 0000000..2077213 --- /dev/null +++ b/chernyshov_nikita_lab_3/genres_service/requirements.txt @@ -0,0 +1 @@ +Flask \ No newline at end of file diff --git a/chernyshov_nikita_lab_3/nginx/nginx.conf b/chernyshov_nikita_lab_3/nginx/nginx.conf new file mode 100644 index 0000000..d3cc7f0 --- /dev/null +++ b/chernyshov_nikita_lab_3/nginx/nginx.conf @@ -0,0 +1,11 @@ +server { + listen 80; + + location /games { + proxy_pass http://games_service:5000; + } + + location /genres { + proxy_pass http://genres_service:5001; + } +} \ No newline at end of file -- 2.25.1