From 5aa2cae670df9ea408691eb5ce10ab2fa63e1ef2 Mon Sep 17 00:00:00 2001 From: maksim Date: Sat, 5 Oct 2024 01:24:02 +0400 Subject: [PATCH 1/5] init --- kashin_maxim_lab_3/readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 kashin_maxim_lab_3/readme.md diff --git a/kashin_maxim_lab_3/readme.md b/kashin_maxim_lab_3/readme.md new file mode 100644 index 0000000..fdb5ef7 --- /dev/null +++ b/kashin_maxim_lab_3/readme.md @@ -0,0 +1 @@ +# Тут будет отчёт. \ No newline at end of file From 1e9bdf28067b453daed62713c5f8bae967849d41 Mon Sep 17 00:00:00 2001 From: maksim Date: Sat, 5 Oct 2024 22:02:08 +0400 Subject: [PATCH 2/5] =?UTF-8?q?=D0=9F=D0=BE=D1=87=D1=82=D0=B8=20=D1=81?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D0=BE.=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20=D1=81=D0=B2=D1=8F=D0=B7?= =?UTF-8?q?=D0=B8=20=D0=B8=20=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?readme.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kashin_maxim_lab_3/.gitignore | 1 + kashin_maxim_lab_3/docker-compose.yml | 53 +++++++++++++++++++ kashin_maxim_lab_3/faculty_service/Dockerfile | 22 ++++++++ kashin_maxim_lab_3/faculty_service/app.py | 42 +++++++++++++++ kashin_maxim_lab_3/faculty_service/db.py | 15 ++++++ kashin_maxim_lab_3/faculty_service/init.sql | 5 ++ .../faculty_service/requirements.txt | 3 ++ kashin_maxim_lab_3/faculty_service/service.py | 28 ++++++++++ kashin_maxim_lab_3/nginx.conf | 27 ++++++++++ kashin_maxim_lab_3/readme.md | 4 +- .../university_service/Dockerfile | 22 ++++++++ kashin_maxim_lab_3/university_service/app.py | 42 +++++++++++++++ kashin_maxim_lab_3/university_service/db.py | 16 ++++++ .../university_service/init.sql | 4 ++ .../university_service/requirements.txt | 3 ++ .../university_service/service.py | 30 +++++++++++ 16 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 kashin_maxim_lab_3/.gitignore create mode 100644 kashin_maxim_lab_3/docker-compose.yml create mode 100644 kashin_maxim_lab_3/faculty_service/Dockerfile create mode 100644 kashin_maxim_lab_3/faculty_service/app.py create mode 100644 kashin_maxim_lab_3/faculty_service/db.py create mode 100644 kashin_maxim_lab_3/faculty_service/init.sql create mode 100644 kashin_maxim_lab_3/faculty_service/requirements.txt create mode 100644 kashin_maxim_lab_3/faculty_service/service.py create mode 100644 kashin_maxim_lab_3/nginx.conf create mode 100644 kashin_maxim_lab_3/university_service/Dockerfile create mode 100644 kashin_maxim_lab_3/university_service/app.py create mode 100644 kashin_maxim_lab_3/university_service/db.py create mode 100644 kashin_maxim_lab_3/university_service/init.sql create mode 100644 kashin_maxim_lab_3/university_service/requirements.txt create mode 100644 kashin_maxim_lab_3/university_service/service.py diff --git a/kashin_maxim_lab_3/.gitignore b/kashin_maxim_lab_3/.gitignore new file mode 100644 index 0000000..b694934 --- /dev/null +++ b/kashin_maxim_lab_3/.gitignore @@ -0,0 +1 @@ +.venv \ No newline at end of file diff --git a/kashin_maxim_lab_3/docker-compose.yml b/kashin_maxim_lab_3/docker-compose.yml new file mode 100644 index 0000000..b4887c5 --- /dev/null +++ b/kashin_maxim_lab_3/docker-compose.yml @@ -0,0 +1,53 @@ +version: '3.8' +services: + university_service: + build: + context: ./university_service + depends_on: + - university_db + environment: + - FLASK_APP=app.py + expose: + - 8081 + + faculty_service: + build: + context: ./faculty_service + depends_on: + - faculty_db + environment: + - FLASK_APP=app.py + expose: + - 8082 + + university_db: + image: postgres + environment: + POSTGRES_USER: university_user + POSTGRES_PASSWORD: password + POSTGRES_DB: universitydb + ports: + - "5433:5432" + volumes: + - ./university_service/init.sql:/docker-entrypoint-initdb.d/init.sql + + faculty_db: + image: postgres + environment: + POSTGRES_USER: faculty_user + POSTGRES_PASSWORD: password + POSTGRES_DB: facultydb + ports: + - "5434:5432" + volumes: + - ./faculty_service/init.sql:/docker-entrypoint-initdb.d/init.sql + + nginx: + image: nginx + ports: + - 8086:8086 + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - university_service + - faculty_service diff --git a/kashin_maxim_lab_3/faculty_service/Dockerfile b/kashin_maxim_lab_3/faculty_service/Dockerfile new file mode 100644 index 0000000..aa1488a --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.9-slim + +# Установка зависимостей +RUN apt-get update && apt-get install -y \ + gcc \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +# Установка рабочей директории +WORKDIR /app + +# Копирование файлов +COPY requirements.txt requirements.txt + +# Установка Python-зависимостей +RUN pip install --no-cache-dir -r requirements.txt + +# Копирование всех файлов приложения +COPY . . + +# Запуск приложения +CMD ["python", "app.py"] diff --git a/kashin_maxim_lab_3/faculty_service/app.py b/kashin_maxim_lab_3/faculty_service/app.py new file mode 100644 index 0000000..2b77b2e --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/app.py @@ -0,0 +1,42 @@ +from flask import Flask, jsonify, request, Response +from service import FacultyService +from db import db + +app = Flask(__name__) +app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://faculty_user:password@faculty_db:5432/facultydb' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db.init_app(app) + +faculty_service = FacultyService() + + +@app.route('/faculties', methods=['GET', 'POST']) +def handle_faculties(): + if request.method == 'POST': + dto = request.get_json()['dto'] + faculty = faculty_service.create_faculty(dto['name'], dto['university_id']) + return jsonify({"id": faculty.id, "name": faculty.name, "university_id": faculty.university_id}) + + return jsonify(faculty_service.get_all_faculties()) + + +@app.route('/faculties/', methods=['GET', 'PUT', 'DELETE']) +def handle_faculty(faculty_id): + if request.method == 'PUT': + dto = request.get_json()['dto'] + updated_faculty = faculty_service.update_faculty(faculty_id, dto['name']) + if updated_faculty: + return jsonify(updated_faculty) + else: + return Response(status=404) + + elif request.method == 'DELETE': + faculty_service.delete_faculty(faculty_id) + return Response(status=200) + + university = faculty_service.get_faculty(faculty_id) + return jsonify({"id": university.id, "name": university.name, "university_id": university.university_id}) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', use_reloader=False, port=8082) diff --git a/kashin_maxim_lab_3/faculty_service/db.py b/kashin_maxim_lab_3/faculty_service/db.py new file mode 100644 index 0000000..ce7cbb2 --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/db.py @@ -0,0 +1,15 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + +class Faculty(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100), nullable=False) + university_id = db.Column(db.Integer, nullable=False) + + def to_dict(self): + return { + "id": self.id, + "name": self.name, + "university_id": self.university_id + } \ No newline at end of file diff --git a/kashin_maxim_lab_3/faculty_service/init.sql b/kashin_maxim_lab_3/faculty_service/init.sql new file mode 100644 index 0000000..d45c502 --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/init.sql @@ -0,0 +1,5 @@ +CREATE TABLE IF NOT EXISTS faculty ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + university_id INT NOT NULL +); diff --git a/kashin_maxim_lab_3/faculty_service/requirements.txt b/kashin_maxim_lab_3/faculty_service/requirements.txt new file mode 100644 index 0000000..c9b3f66 --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/requirements.txt @@ -0,0 +1,3 @@ +flask +flask_sqlalchemy +psycopg2 \ No newline at end of file diff --git a/kashin_maxim_lab_3/faculty_service/service.py b/kashin_maxim_lab_3/faculty_service/service.py new file mode 100644 index 0000000..35bbd94 --- /dev/null +++ b/kashin_maxim_lab_3/faculty_service/service.py @@ -0,0 +1,28 @@ +from db import db, Faculty + +class FacultyService: + def get_all_faculties(self): + return [faculty.to_dict() for faculty in Faculty.query.all()] + + def get_faculty(self, faculty_id): + return Faculty.query.get(faculty_id) + + def create_faculty(self, name, university_id): + faculty = Faculty(name=name, university_id=university_id) + db.session.add(faculty) + db.session.commit() + return faculty.to_dict() + + def update_faculty(self, faculty_id, name): + faculty = self.get_faculty(faculty_id) + if faculty: + faculty.name = name + db.session.commit() + return faculty.to_dict() + return None + + def delete_faculty(self, faculty_id): + faculty = self.get_faculty(faculty_id) + if faculty: + db.session.delete(faculty) + db.session.commit() diff --git a/kashin_maxim_lab_3/nginx.conf b/kashin_maxim_lab_3/nginx.conf new file mode 100644 index 0000000..492592f --- /dev/null +++ b/kashin_maxim_lab_3/nginx.conf @@ -0,0 +1,27 @@ +events { + worker_connections 1024; +} + +http { + server { + listen 8086; + listen [::]:8086; + server_name localhost; + + location /university_service/ { + proxy_pass http://university_service:8081/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Prefix $scheme; + } + + location /faculty_service/ { + proxy_pass http://faculty_service:8082/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Prefix $scheme; + } + } +} \ No newline at end of file diff --git a/kashin_maxim_lab_3/readme.md b/kashin_maxim_lab_3/readme.md index fdb5ef7..0a1c85d 100644 --- a/kashin_maxim_lab_3/readme.md +++ b/kashin_maxim_lab_3/readme.md @@ -1 +1,3 @@ -# Тут будет отчёт. \ No newline at end of file +# Кашин Максим ПИбд-42 + +# Тематика: Учебная групп и студенты \ No newline at end of file diff --git a/kashin_maxim_lab_3/university_service/Dockerfile b/kashin_maxim_lab_3/university_service/Dockerfile new file mode 100644 index 0000000..aa1488a --- /dev/null +++ b/kashin_maxim_lab_3/university_service/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.9-slim + +# Установка зависимостей +RUN apt-get update && apt-get install -y \ + gcc \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +# Установка рабочей директории +WORKDIR /app + +# Копирование файлов +COPY requirements.txt requirements.txt + +# Установка Python-зависимостей +RUN pip install --no-cache-dir -r requirements.txt + +# Копирование всех файлов приложения +COPY . . + +# Запуск приложения +CMD ["python", "app.py"] diff --git a/kashin_maxim_lab_3/university_service/app.py b/kashin_maxim_lab_3/university_service/app.py new file mode 100644 index 0000000..9b64131 --- /dev/null +++ b/kashin_maxim_lab_3/university_service/app.py @@ -0,0 +1,42 @@ +from flask import Flask, jsonify, request, Response +from service import UniversityService +from db import db + +app = Flask(__name__) +app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://university_user:password@university_db:5432/universitydb' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db.init_app(app) + +university_service = UniversityService() + + +@app.route('/universities', methods=['GET', 'POST']) +def handle_universities(): + if request.method == 'POST': + dto = request.get_json()['dto'] + university = university_service.create_university(dto['name']) + return jsonify({"id": university.id, "name": university.name, "established_at": university.established_at}) + + universities = university_service.get_all_universities() + return jsonify(universities) + + +@app.route('/universities/', methods=['GET', 'PUT', 'DELETE']) +def handle_university(university_id): + if request.method == 'PUT': + dto = request.get_json()['dto'] + updated_university = university_service.update_university(university_id, dto['name']) + return jsonify(updated_university) if updated_university else Response(status=404) + + elif request.method == 'DELETE': + university_service.delete_university(university_id) + return Response(status=200) + + university = university_service.get_university(university_id) + if university is None: + return Response(status=404) + return jsonify(university) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', use_reloader=False, port=8081) diff --git a/kashin_maxim_lab_3/university_service/db.py b/kashin_maxim_lab_3/university_service/db.py new file mode 100644 index 0000000..ae44985 --- /dev/null +++ b/kashin_maxim_lab_3/university_service/db.py @@ -0,0 +1,16 @@ +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime + +db = SQLAlchemy() + +class University(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100), nullable=False) + established_at = db.Column(db.DateTime, default=datetime.utcnow) + + def to_dict(self): + return { + "id": self.id, + "name": self.name, + "established_at": self.established_at.isoformat() + } diff --git a/kashin_maxim_lab_3/university_service/init.sql b/kashin_maxim_lab_3/university_service/init.sql new file mode 100644 index 0000000..c95328c --- /dev/null +++ b/kashin_maxim_lab_3/university_service/init.sql @@ -0,0 +1,4 @@ +CREATE TABLE IF NOT EXISTS university ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL +); \ No newline at end of file diff --git a/kashin_maxim_lab_3/university_service/requirements.txt b/kashin_maxim_lab_3/university_service/requirements.txt new file mode 100644 index 0000000..c9b3f66 --- /dev/null +++ b/kashin_maxim_lab_3/university_service/requirements.txt @@ -0,0 +1,3 @@ +flask +flask_sqlalchemy +psycopg2 \ No newline at end of file diff --git a/kashin_maxim_lab_3/university_service/service.py b/kashin_maxim_lab_3/university_service/service.py new file mode 100644 index 0000000..9f55e03 --- /dev/null +++ b/kashin_maxim_lab_3/university_service/service.py @@ -0,0 +1,30 @@ +from db import db, University + +class UniversityService: + def get_all_universities(self): + return [university.to_dict() for university in University.query.all()] + + def get_university(self, university_id): + university = University.query.get(university_id) + return university.to_dict() if university else None + + def create_university(self, name): + university = University(name=name) + db.session.add(university) + db.session.commit() + return university.to_dict() + + def update_university(self, university_id, name): + university = self.get_university(university_id) + if university: + university_obj = University.query.get(university_id) + university_obj.name = name + db.session.commit() + return university_obj.to_dict() + return None + + def delete_university(self, university_id): + university = self.get_university(university_id) + if university: + db.session.delete(University.query.get(university_id)) + db.session.commit() From 4699fda79733706230cc4fd157f53ee0d15b8e5d Mon Sep 17 00:00:00 2001 From: maksim Date: Sat, 5 Oct 2024 23:40:53 +0400 Subject: [PATCH 3/5] =?UTF-8?q?=D0=A4=D1=83=D1=85,=20=D0=B3=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE.=20=D0=9E=D1=81=D1=82=D0=B0=D0=BB=D0=BE?= =?UTF-8?q?=D1=81=D1=8C=20=D1=80=D0=B8=D0=B4=D0=BC=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kashin_maxim_lab_3/faculty_service/app.py | 18 +++++++++++++++++- kashin_maxim_lab_3/faculty_service/db.py | 6 +++++- kashin_maxim_lab_3/faculty_service/init.sql | 11 +++++++++++ kashin_maxim_lab_3/faculty_service/service.py | 17 ++++++++++++++--- kashin_maxim_lab_3/university_service/app.py | 14 +++++++++++++- kashin_maxim_lab_3/university_service/db.py | 4 ++++ kashin_maxim_lab_3/university_service/init.sql | 15 ++++++++++++++- .../university_service/service.py | 14 +++++++++++++- 8 files changed, 91 insertions(+), 8 deletions(-) diff --git a/kashin_maxim_lab_3/faculty_service/app.py b/kashin_maxim_lab_3/faculty_service/app.py index 2b77b2e..4845397 100644 --- a/kashin_maxim_lab_3/faculty_service/app.py +++ b/kashin_maxim_lab_3/faculty_service/app.py @@ -15,11 +15,15 @@ def handle_faculties(): if request.method == 'POST': dto = request.get_json()['dto'] faculty = faculty_service.create_faculty(dto['name'], dto['university_id']) + + # Проверьте, является ли faculty словарем или объектом + if isinstance(faculty, dict): + return jsonify({"id": faculty['id'], "name": faculty['name'], "university_id": faculty['university_id']}) + return jsonify({"id": faculty.id, "name": faculty.name, "university_id": faculty.university_id}) return jsonify(faculty_service.get_all_faculties()) - @app.route('/faculties/', methods=['GET', 'PUT', 'DELETE']) def handle_faculty(faculty_id): if request.method == 'PUT': @@ -37,6 +41,18 @@ def handle_faculty(faculty_id): university = faculty_service.get_faculty(faculty_id) return jsonify({"id": university.id, "name": university.name, "university_id": university.university_id}) +@app.route('/faculties//universities', methods=['POST']) +def add_university(faculty_id): + dto = request.get_json() + university_id = dto['university_id'] + faculty_service.add_university_to_faculty(faculty_id, university_id) + return Response(status=204) + +@app.route('/faculties//universities/', methods=['DELETE']) +def remove_university(faculty_id, university_id): + faculty_service.remove_university_from_faculty(faculty_id, university_id) + return Response(status=204) + if __name__ == '__main__': app.run(host='0.0.0.0', use_reloader=False, port=8082) diff --git a/kashin_maxim_lab_3/faculty_service/db.py b/kashin_maxim_lab_3/faculty_service/db.py index ce7cbb2..23e6b0d 100644 --- a/kashin_maxim_lab_3/faculty_service/db.py +++ b/kashin_maxim_lab_3/faculty_service/db.py @@ -12,4 +12,8 @@ class Faculty(db.Model): "id": self.id, "name": self.name, "university_id": self.university_id - } \ No newline at end of file + } + +class FacultyUniversity(db.Model): + faculty_id = db.Column(db.Integer, db.ForeignKey('faculty.id'), primary_key=True) + university_id = db.Column(db.Integer, db.ForeignKey('university.id'), primary_key=True) diff --git a/kashin_maxim_lab_3/faculty_service/init.sql b/kashin_maxim_lab_3/faculty_service/init.sql index d45c502..6a6319e 100644 --- a/kashin_maxim_lab_3/faculty_service/init.sql +++ b/kashin_maxim_lab_3/faculty_service/init.sql @@ -3,3 +3,14 @@ CREATE TABLE IF NOT EXISTS faculty ( name VARCHAR(100) NOT NULL, university_id INT NOT NULL ); + +CREATE TABLE IF NOT EXISTS university ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL +); + +CREATE TABLE IF NOT EXISTS faculty_university ( + faculty_id INT REFERENCES faculty(id), + university_id INT REFERENCES university(id), + PRIMARY KEY (faculty_id, university_id) +); diff --git a/kashin_maxim_lab_3/faculty_service/service.py b/kashin_maxim_lab_3/faculty_service/service.py index 35bbd94..65d98db 100644 --- a/kashin_maxim_lab_3/faculty_service/service.py +++ b/kashin_maxim_lab_3/faculty_service/service.py @@ -1,4 +1,5 @@ -from db import db, Faculty +from db import db, Faculty, FacultyUniversity + class FacultyService: def get_all_faculties(self): @@ -11,7 +12,7 @@ class FacultyService: faculty = Faculty(name=name, university_id=university_id) db.session.add(faculty) db.session.commit() - return faculty.to_dict() + return faculty def update_faculty(self, faculty_id, name): faculty = self.get_faculty(faculty_id) @@ -24,5 +25,15 @@ class FacultyService: def delete_faculty(self, faculty_id): faculty = self.get_faculty(faculty_id) if faculty: - db.session.delete(faculty) + db.session.delete(Faculty.query.get(faculty_id)) db.session.commit() + def add_university_to_faculty(self, faculty_id, university_id): + association = FacultyUniversity(faculty_id=faculty_id, university_id=university_id) + db.session.add(association) + db.session.commit() + + def remove_university_from_faculty(self, faculty_id, university_id): + association = FacultyUniversity.query.filter_by(faculty_id=faculty_id, university_id=university_id).first() + if association: + db.session.delete(association) + db.session.commit() \ No newline at end of file diff --git a/kashin_maxim_lab_3/university_service/app.py b/kashin_maxim_lab_3/university_service/app.py index 9b64131..ccc9a72 100644 --- a/kashin_maxim_lab_3/university_service/app.py +++ b/kashin_maxim_lab_3/university_service/app.py @@ -15,7 +15,7 @@ def handle_universities(): if request.method == 'POST': dto = request.get_json()['dto'] university = university_service.create_university(dto['name']) - return jsonify({"id": university.id, "name": university.name, "established_at": university.established_at}) + return jsonify(university) universities = university_service.get_all_universities() return jsonify(universities) @@ -37,6 +37,18 @@ def handle_university(university_id): return Response(status=404) return jsonify(university) +@app.route('/universities//faculties', methods=['POST']) +def add_faculty(university_id): + dto = request.get_json() + faculty_id = dto['faculty_id'] + university_service.add_faculty_to_university(university_id, faculty_id) + return Response(status=204) + +@app.route('/universities//faculties/', methods=['DELETE']) +def remove_faculty(university_id, faculty_id): + university_service.remove_faculty_from_university(university_id, faculty_id) + return Response(status=204) + if __name__ == '__main__': app.run(host='0.0.0.0', use_reloader=False, port=8081) diff --git a/kashin_maxim_lab_3/university_service/db.py b/kashin_maxim_lab_3/university_service/db.py index ae44985..4c218b1 100644 --- a/kashin_maxim_lab_3/university_service/db.py +++ b/kashin_maxim_lab_3/university_service/db.py @@ -14,3 +14,7 @@ class University(db.Model): "name": self.name, "established_at": self.established_at.isoformat() } + +class FacultyUniversity(db.Model): + faculty_id = db.Column(db.Integer, db.ForeignKey('faculty.id'), primary_key=True) + university_id = db.Column(db.Integer, db.ForeignKey('university.id'), primary_key=True) diff --git a/kashin_maxim_lab_3/university_service/init.sql b/kashin_maxim_lab_3/university_service/init.sql index c95328c..4bfd43b 100644 --- a/kashin_maxim_lab_3/university_service/init.sql +++ b/kashin_maxim_lab_3/university_service/init.sql @@ -1,4 +1,17 @@ CREATE TABLE IF NOT EXISTS university ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + established_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE IF NOT EXISTS faculty ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL -); \ No newline at end of file +); + +CREATE TABLE IF NOT EXISTS faculty_university ( + faculty_id INT REFERENCES faculty(id), + university_id INT REFERENCES university(id), + PRIMARY KEY (faculty_id, university_id) +); diff --git a/kashin_maxim_lab_3/university_service/service.py b/kashin_maxim_lab_3/university_service/service.py index 9f55e03..2884c38 100644 --- a/kashin_maxim_lab_3/university_service/service.py +++ b/kashin_maxim_lab_3/university_service/service.py @@ -1,4 +1,5 @@ -from db import db, University +from db import db, University, FacultyUniversity + class UniversityService: def get_all_universities(self): @@ -28,3 +29,14 @@ class UniversityService: if university: db.session.delete(University.query.get(university_id)) db.session.commit() + + def add_faculty_to_university(self, university_id, faculty_id): + association = FacultyUniversity(university_id=university_id, faculty_id=faculty_id) + db.session.add(association) + db.session.commit() + + def remove_faculty_from_university(self, university_id, faculty_id): + association = FacultyUniversity.query.filter_by(university_id=university_id, faculty_id=faculty_id).first() + if association: + db.session.delete(association) + db.session.commit() \ No newline at end of file From 761cc83ebd7a3ede0af8b7ff512d2b25ddc3661c Mon Sep 17 00:00:00 2001 From: maksim Date: Sun, 6 Oct 2024 00:33:30 +0400 Subject: [PATCH 4/5] =?UTF-8?q?=D0=9F=D0=B0=D0=B1=D0=B5=D0=B4=D0=B0...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kashin_maxim_lab_3/readme.md | 104 ++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/kashin_maxim_lab_3/readme.md b/kashin_maxim_lab_3/readme.md index 0a1c85d..0dab095 100644 --- a/kashin_maxim_lab_3/readme.md +++ b/kashin_maxim_lab_3/readme.md @@ -1,3 +1,105 @@ # Кашин Максим ПИбд-42 -# Тематика: Учебная групп и студенты \ No newline at end of file +# Проект "Университеты и Факультеты" + +## Часть 1: Создание Docker + +### Установка Docker и Docker Compose +Перед началом нужно проверить, что Docker работает, иначе использовать инструцию для 1-ой лабораторной. + +### 1.1 Файл `docker-compose.yml` +В корне проекта файл `docker-compose.yml`. Этот файл будет описывать, как должны быть организованы сервисы. В данном случае рассматриваем только университет, в факультетах анологично. + +```yaml +version: '3.8' +services: + university_service: + build: + context: ./university_service + depends_on: + - university_db + environment: + - FLASK_APP=app.py + expose: + - 8081 + university_db: + image: postgres:13 + environment: + POSTGRES_USER: university_user + POSTGRES_PASSWORD: password + POSTGRES_DB: universitydb + ports: + - "5432:5432" +``` + +Объяснение: +- `version`: Указывает версию Docker Compose. +- `services`: Определяет микросервисы. В данном случае, мы начинаем с `university_service`. +- `build`: Указывает, что нужно построить образ для этого сервиса, используя Dockerfile из указанной директории. +- `depends_on`: Указывает, что этот сервис зависит от `university_db` (базы данных), которая будет запущена первой. +- `environment`: Определяет переменные окружения для сервиса, в данном случае указывая файл Flask. +- `expose`: Указывает, что сервис будет доступен на порту 8081 внутри Docker-сети. + +### 1.2 Файл Dockerfile для сервиса университетов +В каталоге `university_service` файл `Dockerfile`. Этот файл будет содержать инструкции для сборки образа сервиса университетов. В данном случае рассматриваем только университет, в факультетах анологично. + +```dockerfile +FROM python:3.9-slim + +# Установка зависимостей +RUN apt-get update && apt-get install -y \ + gcc \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +# Установка рабочей директории +WORKDIR /app + +# Копирование файлов +COPY requirements.txt requirements.txt + +# Установка Python-зависимостей +RUN pip install --no-cache-dir -r requirements.txt + +# Копирование всех файлов приложения +COPY . . + +# Запуск приложения +CMD ["python", "app.py"] +``` + + +### 1.3 Создание файла requirements.txt +В каталоге `university_service` файл `requirements.txt`, в котором перечислите все необходимые библиотеки для приложения. В данном случае рассматриваем только университет, в факультетах анологично. + +```txt +flask +flask_sqlalchemy +psycopg2 +``` + +### 1.5 Запуск Docker Compose +Когда все файлы созданы, можно запустить сервисы с помощью команды: + +```bash +docker-compose up +``` + +Эта команда создаст и запустит все указанные в `docker-compose.yml` сервисы. + +## Часть 2: Реализация функциональности + +### 2.1 Создание сервиса для университетов +В каталоге `university_service` файл `app.py`,`service.py`,`db.py`. Этb файлы будут содержать код Flask приложения для управления университетами и базы данных для него. + +### 2.2 Создание сервиса для факультетов +Каталог `faculty_service` и в нем файл `app.py`,`service.py`,`db.py`. Эти файлы будут содержать код для управления факультетами и базы данных для него. + +### 2.3 Создание таблиц базы данных +Нужно создать таблицы базы данных для университетов и факультетов. Для этого созданы файлы init.sql для университета и для факультетов. + +### 2.4 Тестирование API +Тестирование производится через расширение RestMan. В нем мы можем убедиться, что весь CRUD работает исправно. + +## Часть 3: Ссылка на видео +[Видео-отчёт Кашин Максим ПИбд-42](https://disk.yandex.ru/i/F0Dh7RnpVL1Stg) \ No newline at end of file From bde242318f6f73b7acc5780706a5f205e0a79794 Mon Sep 17 00:00:00 2001 From: maksim Date: Sun, 6 Oct 2024 00:35:20 +0400 Subject: [PATCH 5/5] =?UTF-8?q?=D0=A1=D1=82=D1=80=D0=B0=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D0=B0=D1=82=D1=80?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D0=B2=205=20=D1=83=D1=82=D1=80=D0=B0...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kashin_maxim_lab_3/faculty_service/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/kashin_maxim_lab_3/faculty_service/app.py b/kashin_maxim_lab_3/faculty_service/app.py index 4845397..97678eb 100644 --- a/kashin_maxim_lab_3/faculty_service/app.py +++ b/kashin_maxim_lab_3/faculty_service/app.py @@ -16,7 +16,6 @@ def handle_faculties(): dto = request.get_json()['dto'] faculty = faculty_service.create_faculty(dto['name'], dto['university_id']) - # Проверьте, является ли faculty словарем или объектом if isinstance(faculty, dict): return jsonify({"id": faculty['id'], "name": faculty['name'], "university_id": faculty['university_id']})