commit 07a6d7069ff906ecf62b2634127300156e915711 Author: Juan M. Ley Date: Fri Feb 13 17:00:52 2026 -0600 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..adf9df2 --- /dev/null +++ b/run.sh @@ -0,0 +1,4 @@ +#!/bin/bash +source /home/rodo/Documents/examen-mss/netflix/bin/activate +cd /home/rodo/Documents/examen-mss/src/ +python3 main.py diff --git a/script.sh b/script.sh new file mode 100755 index 0000000..ba54fbe --- /dev/null +++ b/script.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +CURRENT_DIR=$(pwd) + +mkdir $CURRENT_DIR/src + +mkdir $CURRENT_DIR/src/{application,core,domain,infrastructure} + +mkdir $CURRENT_DIR/src/application/{ports,services} + +mkdir $CURRENT_DIR/src/infrastructure/{adapters,api} + +mkdir $CURRENT_DIR/src/infrastructure/adapters/persistence + +touch $CURRENT_DIR/src/main.py + +echo "Here goes all repositories, each repo will implement the object they need and defines all methods as abstracts" > $CURRENT_DIR/src/application/ports/here.txt +echo "Here we will use all repositores and will define as classes all functions we will implement as execute method" > $CURRENT_DIR/src/application/services/here.txt +echo "Here we will define all the configurations for the multiple api's we're going to use" > $CURRENT_DIR/src/core/here.txt +echo "Here we will define the entities that we will operate with, normally as dataclasses because we won't define methods here" > $CURRENT_DIR/src/domain/here.txt +echo "Here we will define all the database parts, db will define the connection and session, models will define what is going to be in the database and the sql repository will define all the methods that will be executed in the database, these are called by the api." > $CURRENT_DIR/src/infrastructure/adapters/persistence/here.txt +echo "Here we will define each api application in each directory, we can use router to make things easier and scallable" > $CURRENT_DIR/src/infrastructure/api/here.txt + +# == Architecture dependencies == # + +python3 -m venv $CURRENT_DIR/netflix + +source $CURRENT_DIR/netflix/bin/activate + +pip install uvicorn fastapi pydantic pydantic-settings sqlalchemy + +printf "#!/bin/bash \ncd $(pwd)/src/ \npython3 main.py\n" > $CURRENT_DIR/run.sh + +chmod +x $CURRENT_DIR/run.sh diff --git a/src/application/__pycache__/exceptions.cpython-314.pyc b/src/application/__pycache__/exceptions.cpython-314.pyc new file mode 100644 index 0000000..b818b44 Binary files /dev/null and b/src/application/__pycache__/exceptions.cpython-314.pyc differ diff --git a/src/application/exceptions.py b/src/application/exceptions.py new file mode 100644 index 0000000..215c767 --- /dev/null +++ b/src/application/exceptions.py @@ -0,0 +1,2 @@ +class MicroserviceAlreadyExists(Exception): + pass diff --git a/src/application/ports/__pycache__/microservicio_a_repository.cpython-314.pyc b/src/application/ports/__pycache__/microservicio_a_repository.cpython-314.pyc new file mode 100644 index 0000000..6d496cd Binary files /dev/null and b/src/application/ports/__pycache__/microservicio_a_repository.cpython-314.pyc differ diff --git a/src/application/ports/__pycache__/microservicio_b_repository.cpython-314.pyc b/src/application/ports/__pycache__/microservicio_b_repository.cpython-314.pyc new file mode 100644 index 0000000..ba01d54 Binary files /dev/null and b/src/application/ports/__pycache__/microservicio_b_repository.cpython-314.pyc differ diff --git a/src/application/ports/microservicio_a_repository.py b/src/application/ports/microservicio_a_repository.py new file mode 100644 index 0000000..358eaf7 --- /dev/null +++ b/src/application/ports/microservicio_a_repository.py @@ -0,0 +1,19 @@ +from abc import ABC, abstractmethod +from domain.MicroservicioA import MicroservicioA + +class MicroservicioARepository(ABC): + @abstractmethod + def save(self, msa: MicroservicioA): + ... + @abstractmethod + def viewAll(self) -> list[MicroservicioA]: + ... + @abstractmethod + def viewById(self, msa_id: int): + ... + @abstractmethod + def remove(self, msa_id: int): + ... + @abstractmethod + def editById(self, msa_id: int, msa: MicroservicioA): + ... \ No newline at end of file diff --git a/src/application/ports/microservicio_b_repository.py b/src/application/ports/microservicio_b_repository.py new file mode 100644 index 0000000..3bdf4fb --- /dev/null +++ b/src/application/ports/microservicio_b_repository.py @@ -0,0 +1,19 @@ +from abc import ABC, abstractmethod +from domain.MicroservicioB import MicroservicioB + +class MicroservicioBRepository(ABC): + @abstractmethod + def save(self, msb: MicroservicioB): + ... + @abstractmethod + def viewAll(self) -> list[MicroservicioB]: + ... + @abstractmethod + def viewById(self, msb_id: int): + ... + @abstractmethod + def remove(self, msb_id: int): + ... + @abstractmethod + def editById(self, msb_id:int, msb: MicroservicioB): + ... \ No newline at end of file diff --git a/src/application/services/__init__.py b/src/application/services/__init__.py new file mode 100644 index 0000000..a2a12e4 --- /dev/null +++ b/src/application/services/__init__.py @@ -0,0 +1,4 @@ +from infrastructure.adapters.persistence.db import engine +from infrastructure.adapters.persistence.models import Base + +Base.metadata.create_all(bind=engine) \ No newline at end of file diff --git a/src/application/services/__pycache__/__init__.cpython-314.pyc b/src/application/services/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..92616e1 Binary files /dev/null and b/src/application/services/__pycache__/__init__.cpython-314.pyc differ diff --git a/src/application/services/__pycache__/microservicio_a_service.cpython-314.pyc b/src/application/services/__pycache__/microservicio_a_service.cpython-314.pyc new file mode 100644 index 0000000..f4a90d3 Binary files /dev/null and b/src/application/services/__pycache__/microservicio_a_service.cpython-314.pyc differ diff --git a/src/application/services/__pycache__/microservicio_b_service.cpython-314.pyc b/src/application/services/__pycache__/microservicio_b_service.cpython-314.pyc new file mode 100644 index 0000000..7484d3f Binary files /dev/null and b/src/application/services/__pycache__/microservicio_b_service.cpython-314.pyc differ diff --git a/src/application/services/microservicio_a_service.py b/src/application/services/microservicio_a_service.py new file mode 100644 index 0000000..6c04189 --- /dev/null +++ b/src/application/services/microservicio_a_service.py @@ -0,0 +1,57 @@ +from application.ports.microservicio_a_repository import MicroservicioARepository +from domain.MicroservicioA import MicroservicioA + +class Save: + def __init__(self, repo: MicroservicioARepository): + if not isinstance(repo, MicroservicioARepository): + raise TypeError("MicroservicioARepository must be a class instance") + self.repo = repo + + def execute(self, perfiles: str, idioma: str, calidad: str): + msa = MicroservicioA(msa_id=0,perfiles=perfiles, idioma=idioma,calidad=calidad) + self.repo.save(msa) + return msa + + +class ViewAllMsa: + def __init__(self, repo: MicroservicioARepository): + if not isinstance(repo, MicroservicioARepository): + raise TypeError("MicroservicioARepository must be a class instance") + self.repo = repo + + def execute(self): + msa_s = self.repo.viewAll() + return msa_s + + +class ViewById: + def __init__(self, repo: MicroservicioARepository): + if not isinstance(repo, MicroservicioARepository): + raise TypeError("MicroservicioARepository must be a class instance") + self.repo = repo + + def execute(self, msa_id: int) -> MicroservicioA | None: + msa = self.repo.viewById(msa_id) + return msa + + +class Remove: + def __init__(self, repo: MicroservicioARepository): + if not isinstance(repo, MicroservicioARepository): + raise TypeError("MicroservicioARepository must be a class instance") + self.repo = repo + + def execute(self, msa_id:int): + msa = self.repo.remove(msa_id) + return msa + + +class EditById: + def __init__(self, repo: MicroservicioARepository): + if not isinstance(repo, MicroservicioARepository): + raise TypeError("MicroservicioARepository must be a class instance") + self.repo = repo + + def execute(self, msa_id: int, msa: MicroservicioA): + return self.repo.editById(msa_id=msa_id, msa=msa) + \ No newline at end of file diff --git a/src/application/services/microservicio_b_service.py b/src/application/services/microservicio_b_service.py new file mode 100644 index 0000000..8c3a089 --- /dev/null +++ b/src/application/services/microservicio_b_service.py @@ -0,0 +1,56 @@ +from application.ports.microservicio_b_repository import MicroservicioBRepository +from domain.MicroservicioB import MicroservicioB + +class Save: + def __init__(self, repo: MicroservicioBRepository): + if not isinstance(repo, MicroservicioBRepository): + raise TypeError("MicroservicioBRepository must be a class instance") + self.repo = repo + + def execute(self, metodoPagoPredeterminado: str, historialFacturas: str, fechaProximoPago: str): + msb = MicroservicioB(msb_id=0, metodoPagoPredeterminado=metodoPagoPredeterminado, historialFacturas=historialFacturas, fechaProximoPago=fechaProximoPago) + self.repo.save(msb) + return msb + + +class ViewAllMsb: + def __init__(self, repo: MicroservicioBRepository): + if not isinstance(repo, MicroservicioBRepository): + raise TypeError("MicroservicioBRepository must be a class instance") + self.repo = repo + + def execute(self): + msb_s = self.repo.viewAll() + return msb_s + + +class ViewById: + def __init__(self, repo: MicroservicioBRepository): + if not isinstance(repo, MicroservicioBRepository): + raise TypeError("MicroservicioBRepository must be a class instance") + self.repo = repo + + def execute(self, msb_id: int) -> MicroservicioB | None: + msb = self.repo.viewById(msb_id) + return msb + + +class Remove: + def __init__(self, repo: MicroservicioBRepository): + if not isinstance(repo, MicroservicioBRepository): + raise TypeError("MicroservicioBRepository must be a class instance") + self.repo = repo + + def execute(self, msb_id:int): + msb = self.repo.remove(msb_id) + return msb + + +class EditById: + def __init__(self, repo: MicroservicioBRepository): + if not isinstance(repo, MicroservicioBRepository): + raise TypeError("MicroservicioBRepository must be a class instance") + self.repo = repo + + def execute(self, msb_id: int, msb: MicroservicioB): + return self.repo.editById(msb_id=msb_id, msb=msb) diff --git a/src/core/__pycache__/config.cpython-314.pyc b/src/core/__pycache__/config.cpython-314.pyc new file mode 100644 index 0000000..bd32479 Binary files /dev/null and b/src/core/__pycache__/config.cpython-314.pyc differ diff --git a/src/core/config.py b/src/core/config.py new file mode 100644 index 0000000..f33c436 --- /dev/null +++ b/src/core/config.py @@ -0,0 +1,23 @@ +from pydantic_settings import BaseSettings +from pydantic import Field + +class Settings(BaseSettings): + reload: bool = True + host: str = "0.0.0.0" + log_level:str = "info" + + database_url: str = Field(default="sqlite:///./database.db", description="database") + + # API A + api_a_title: str = "Microservicio A API" + api_a_version:str= "1.0.0" + api_a_description:str = "Catálogo y reproducción de contenido" + api_a_port: int = 8001 + + # API B + api_b_title: str = "Microservicio B API" + api_b_version:str= "1.0.0" + api_b_description:str = "Encargado de recomendaciones y \"Mi Lista\"" + api_b_port: int = 8002 + +ConfSettings = Settings() \ No newline at end of file diff --git a/src/database.db b/src/database.db new file mode 100644 index 0000000..e01dd62 Binary files /dev/null and b/src/database.db differ diff --git a/src/domain/MicroservicioA.py b/src/domain/MicroservicioA.py new file mode 100644 index 0000000..dd5675f --- /dev/null +++ b/src/domain/MicroservicioA.py @@ -0,0 +1,8 @@ +from dataclasses import dataclass + +@dataclass +class MicroservicioA: + msa_id: int + perfiles: str + idioma: str + calidad: str \ No newline at end of file diff --git a/src/domain/MicroservicioB.py b/src/domain/MicroservicioB.py new file mode 100644 index 0000000..027ad7b --- /dev/null +++ b/src/domain/MicroservicioB.py @@ -0,0 +1,8 @@ +from dataclasses import dataclass + +@dataclass +class MicroservicioB: + msb_id: int + metodoPagoPredeterminado: str + historialFacturas: str + fechaProximoPago: str \ No newline at end of file diff --git a/src/domain/__pycache__/MicroservicioA.cpython-314.pyc b/src/domain/__pycache__/MicroservicioA.cpython-314.pyc new file mode 100644 index 0000000..e315b04 Binary files /dev/null and b/src/domain/__pycache__/MicroservicioA.cpython-314.pyc differ diff --git a/src/domain/__pycache__/MicroservicioB.cpython-314.pyc b/src/domain/__pycache__/MicroservicioB.cpython-314.pyc new file mode 100644 index 0000000..98645d7 Binary files /dev/null and b/src/domain/__pycache__/MicroservicioB.cpython-314.pyc differ diff --git a/src/infrastructure/adapters/persistence/__pycache__/db.cpython-314.pyc b/src/infrastructure/adapters/persistence/__pycache__/db.cpython-314.pyc new file mode 100644 index 0000000..f778085 Binary files /dev/null and b/src/infrastructure/adapters/persistence/__pycache__/db.cpython-314.pyc differ diff --git a/src/infrastructure/adapters/persistence/__pycache__/microservicio_a_repository_sql.cpython-314.pyc b/src/infrastructure/adapters/persistence/__pycache__/microservicio_a_repository_sql.cpython-314.pyc new file mode 100644 index 0000000..33060ee Binary files /dev/null and b/src/infrastructure/adapters/persistence/__pycache__/microservicio_a_repository_sql.cpython-314.pyc differ diff --git a/src/infrastructure/adapters/persistence/__pycache__/microservicio_b_repository_sql.cpython-314.pyc b/src/infrastructure/adapters/persistence/__pycache__/microservicio_b_repository_sql.cpython-314.pyc new file mode 100644 index 0000000..fb9da06 Binary files /dev/null and b/src/infrastructure/adapters/persistence/__pycache__/microservicio_b_repository_sql.cpython-314.pyc differ diff --git a/src/infrastructure/adapters/persistence/__pycache__/models.cpython-314.pyc b/src/infrastructure/adapters/persistence/__pycache__/models.cpython-314.pyc new file mode 100644 index 0000000..96a9e56 Binary files /dev/null and b/src/infrastructure/adapters/persistence/__pycache__/models.cpython-314.pyc differ diff --git a/src/infrastructure/adapters/persistence/db.py b/src/infrastructure/adapters/persistence/db.py new file mode 100644 index 0000000..1b85827 --- /dev/null +++ b/src/infrastructure/adapters/persistence/db.py @@ -0,0 +1,16 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, declarative_base +from core.config import ConfSettings + +engine = create_engine( + ConfSettings.database_url, + connect_args={"check_same_thread": False} if "sqlite" in ConfSettings.database_url else {} + ) + +SessionLocal = sessionmaker( + bind=engine, + autocommit=False, + autoflush=False + ) + +Base = declarative_base() \ No newline at end of file diff --git a/src/infrastructure/adapters/persistence/microservicio_a_repository_sql.py b/src/infrastructure/adapters/persistence/microservicio_a_repository_sql.py new file mode 100644 index 0000000..2c058e1 --- /dev/null +++ b/src/infrastructure/adapters/persistence/microservicio_a_repository_sql.py @@ -0,0 +1,99 @@ +from sqlalchemy.orm import Session +from sqlalchemy.exc import IntegrityError +from domain.MicroservicioA import MicroservicioA +from application.ports.microservicio_a_repository import MicroservicioARepository +from infrastructure.adapters.persistence.db import SessionLocal +from infrastructure.adapters.persistence.models import MsaModel +from application.exceptions import MicroserviceAlreadyExists + +class SqlMicroservicioARepository(MicroservicioARepository): + def __init__(self): + self.db: Session = SessionLocal() + + def save(self, msa: MicroservicioA): + model = MsaModel( + perfiles=msa.perfiles, + idioma=msa.idioma, + calidad=msa.calidad + ) + + self.db.add(model) + + try: + self.db.commit() + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") + + + self.db.refresh(model) + + return MicroservicioA( + msa_id = model.msa_id, + perfiles=model.perfiles, + idioma=model.idioma, + calidad=model.calidad + ) + + def viewAll(self) -> list[MicroservicioA]: + models = self.db.query(MsaModel).all() + + return [ + MicroservicioA( + msa_id=model.msa_id, + perfiles=model.perfiles, + idioma=model.idioma, + calidad=model.calidad + ) for model in models + ] + + def viewById(self, msa_id: int) -> MicroservicioA | None: + model = self.db.query(MsaModel).filter(MsaModel.msa_id == msa_id).first() + + if not model: + return None + + return MicroservicioA( + msa_id=model.msa_id, + perfiles=model.perfiles, + idioma=model.idioma, + calidad=model.calidad + ) + + def remove(self, msa_id: int): + model = self.db.query(MsaModel).filter(MsaModel.msa_id == msa_id).first() + + if not model: + return False + + try: + self.db.delete(model) + self.db.commit() + return True + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") + + def editById(self, msa_id: int, msa: MicroservicioA) -> MicroservicioA | None: + model = self.db.query(MsaModel).filter(MsaModel.msa_id == msa_id).first() + + if not model: + return None + + try: + model.perfiles = msa.perfiles + model.idioma = msa.idioma + model.calidad = msa.calidad + + self.db.commit() + self.db.refresh(model) + + return MicroservicioA( + msa_id=model.msa_id, + perfiles=model.perfiles, + idioma=model.idioma, + calidad=model.calidad + ) + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") \ No newline at end of file diff --git a/src/infrastructure/adapters/persistence/microservicio_b_repository_sql.py b/src/infrastructure/adapters/persistence/microservicio_b_repository_sql.py new file mode 100644 index 0000000..845f9e1 --- /dev/null +++ b/src/infrastructure/adapters/persistence/microservicio_b_repository_sql.py @@ -0,0 +1,99 @@ +from sqlalchemy.orm import Session +from sqlalchemy.exc import IntegrityError +from domain.MicroservicioB import MicroservicioB +from application.ports.microservicio_b_repository import MicroservicioBRepository +from infrastructure.adapters.persistence.db import SessionLocal +from infrastructure.adapters.persistence.models import MsbModel +from application.exceptions import MicroserviceAlreadyExists + +class SqlMicroservicioBRepository(MicroservicioBRepository): + def __init__(self): + self.db: Session = SessionLocal() + + def save(self, msb: MicroservicioB): + model = MsbModel( + metodoPagoPredeterminado=msb.metodoPagoPredeterminado, + historialFacturas=msb.historialFacturas, + fechaProximoPago=msb.fechaProximoPago + ) + + self.db.add(model) + + try: + self.db.commit() + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") + + + self.db.refresh(model) + + return MicroservicioB( + msb_id = model.msb_id, + metodoPagoPredeterminado=model.metodoPagoPredeterminado, + historialFacturas=model.historialFacturas, + fechaProximoPago=model.fechaProximoPago + ) + + def viewAll(self) -> list[MicroservicioB]: + models = self.db.query(MsbModel).all() + + return [ + MicroservicioB( + msb_id=model.msb_id, + metodoPagoPredeterminado=model.metodoPagoPredeterminado, + historialFacturas=model.historialFacturas, + fechaProximoPago=model.fechaProximoPago + ) for model in models + ] + + def viewById(self, msb_id: int) -> MicroservicioB | None: + model = self.db.query(MsbModel).filter(MsbModel.msb_id == msb_id).first() + + if not model: + return None + + return MicroservicioB( + msb_id=model.msb_id, + metodoPagoPredeterminado=model.metodoPagoPredeterminado, + historialFacturas=model.historialFacturas, + fechaProximoPago=model.fechaProximoPago + ) + + def remove(self, msb_id: int): + model = self.db.query(MsbModel).filter(MsbModel.msb_id == msb_id).first() + + if not model: + return False + + try: + self.db.delete(model) + self.db.commit() + return True + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") + + def editById(self, msb_id: int, msb: MicroservicioB) -> MicroservicioB | None: + model = self.db.query(MsbModel).filter(MsbModel.msb_id == msb_id).first() + + if not model: + return None + + try: + model.metodoPagoPredeterminado = msb.metodoPagoPredeterminado + model.historialFacturas = msb.historialFacturas + model.fechaProximoPago = msb.fechaProximoPago + + self.db.commit() + self.db.refresh(model) + + return MicroservicioB( + msb_id=model.msb_id, + metodoPagoPredeterminado=model.metodoPagoPredeterminado, + historialFacturas=model.historialFacturas, + fechaProximoPago=model.fechaProximoPago + ) + except IntegrityError: + self.db.rollback() + raise MicroserviceAlreadyExists("There's already one registry with that data.") diff --git a/src/infrastructure/adapters/persistence/models.py b/src/infrastructure/adapters/persistence/models.py new file mode 100644 index 0000000..117680d --- /dev/null +++ b/src/infrastructure/adapters/persistence/models.py @@ -0,0 +1,19 @@ +from sqlalchemy import Column, Integer, String, Float, DateTime +from infrastructure.adapters.persistence.db import Base + +class MsaModel(Base): + __tablename__ = "microservicioa" + + msa_id = Column(Integer, primary_key=True, index=True) + perfiles = Column(String, unique=False, index=True) + idioma = Column(String, unique=True, index=True) + calidad = Column(String, unique=True, index=True) + + +class MsbModel(Base): + __tablename__ = "microserviciob" + + msb_id = Column(Integer, primary_key=True, index=True) + metodoPagoPredeterminado = Column(String, unique=False, index=True) + historialFacturas = Column(String, unique=False, index=True) + fechaProximoPago = Column(String, unique=False, index=True) \ No newline at end of file diff --git a/src/infrastructure/api/microservicio_a/__pycache__/app.cpython-314.pyc b/src/infrastructure/api/microservicio_a/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000..ee8f31b Binary files /dev/null and b/src/infrastructure/api/microservicio_a/__pycache__/app.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_a/__pycache__/microservices.cpython-314.pyc b/src/infrastructure/api/microservicio_a/__pycache__/microservices.cpython-314.pyc new file mode 100644 index 0000000..1b4ae6b Binary files /dev/null and b/src/infrastructure/api/microservicio_a/__pycache__/microservices.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_a/__pycache__/root.cpython-314.pyc b/src/infrastructure/api/microservicio_a/__pycache__/root.cpython-314.pyc new file mode 100644 index 0000000..a19eadd Binary files /dev/null and b/src/infrastructure/api/microservicio_a/__pycache__/root.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_a/__pycache__/router.cpython-314.pyc b/src/infrastructure/api/microservicio_a/__pycache__/router.cpython-314.pyc new file mode 100644 index 0000000..aa3f284 Binary files /dev/null and b/src/infrastructure/api/microservicio_a/__pycache__/router.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_a/app.py b/src/infrastructure/api/microservicio_a/app.py new file mode 100644 index 0000000..2f50a00 --- /dev/null +++ b/src/infrastructure/api/microservicio_a/app.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from core.config import ConfSettings +from infrastructure.api.microservicio_a.router import router + +def create_app() -> FastAPI: + app = FastAPI(title=ConfSettings.api_a_title, + version=ConfSettings.api_a_version, + description=ConfSettings.api_a_description) + app.include_router(router) + return app diff --git a/src/infrastructure/api/microservicio_a/microservices.py b/src/infrastructure/api/microservicio_a/microservices.py new file mode 100644 index 0000000..af360e2 --- /dev/null +++ b/src/infrastructure/api/microservicio_a/microservices.py @@ -0,0 +1,79 @@ +from fastapi import APIRouter, HTTPException +from application.services.microservicio_a_service import Save, ViewAllMsa, ViewById, Remove, EditById +from infrastructure.adapters.persistence.microservicio_a_repository_sql import SqlMicroservicioARepository +from domain.MicroservicioA import MicroservicioA + +router = APIRouter() + +@router.post("/") +def create_msa(perfiles: str, idioma: str, calidad: str): + service = Save(SqlMicroservicioARepository()) + + try: + return service.execute(perfiles, idioma, calidad) + except Exception as e: + raise HTTPException( + status_code=400, + detail=str(e) + ) + +@router.get("/") +def view_all_msa(): + service = ViewAllMsa(SqlMicroservicioARepository()) + + try: + return service.execute() + except Exception as e: + raise HTTPException( + status_code=500, + detail=str(e) + ) + +@router.get("/{msa_id}") +def view_msa_by_id(msa_id: int): + service = ViewById(SqlMicroservicioARepository()) + + result = service.execute(msa_id) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result + +@router.delete("/{msa_id}") +def delete_msa_by_id(msa_id: int): + service = Remove(SqlMicroservicioARepository()) + + result = service.execute(msa_id) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result + +@router.put("/{msa_id}") +def edit_msa_by_id(msa_id: int, perfiles: str, idioma: str, calidad: str): + service = EditById(SqlMicroservicioARepository()) + + try: + msa = MicroservicioA(msa_id=msa_id, perfiles=perfiles, idioma=idioma, calidad=calidad) + result = service.execute(msa_id=msa_id, msa=msa) + except Exception as e: + raise HTTPException( + status_code=500, + detail=str(e) + ) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result diff --git a/src/infrastructure/api/microservicio_a/root.py b/src/infrastructure/api/microservicio_a/root.py new file mode 100644 index 0000000..a84bc57 --- /dev/null +++ b/src/infrastructure/api/microservicio_a/root.py @@ -0,0 +1,16 @@ +from fastapi import APIRouter +import platform + +router = APIRouter() + +@router.get("/") +def root(): + uname = platform.uname() + return { + "machine": { + "OS": f"{uname.system} {uname.release}", + "Arch": uname.machine + }, + "Status": "Running", + "Docs": "/docs" + } diff --git a/src/infrastructure/api/microservicio_a/router.py b/src/infrastructure/api/microservicio_a/router.py new file mode 100644 index 0000000..a87a049 --- /dev/null +++ b/src/infrastructure/api/microservicio_a/router.py @@ -0,0 +1,17 @@ +from fastapi import APIRouter +from infrastructure.api.microservicio_a.microservices import router as orders_router +from infrastructure.api.microservicio_a.root import router as root_router + +router = APIRouter() + +router.include_router( + orders_router, + prefix="/microservicio_a", + tags=["microservicio a"] +) + +router.include_router( + root_router, + prefix='', + tags=["root"] +) diff --git a/src/infrastructure/api/microservicio_b/__init__.py b/src/infrastructure/api/microservicio_b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/infrastructure/api/microservicio_b/__pycache__/__init__.cpython-314.pyc b/src/infrastructure/api/microservicio_b/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..7f0ffdf Binary files /dev/null and b/src/infrastructure/api/microservicio_b/__pycache__/__init__.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_b/__pycache__/app.cpython-314.pyc b/src/infrastructure/api/microservicio_b/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000..b54dd0e Binary files /dev/null and b/src/infrastructure/api/microservicio_b/__pycache__/app.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_b/__pycache__/microservices.cpython-314.pyc b/src/infrastructure/api/microservicio_b/__pycache__/microservices.cpython-314.pyc new file mode 100644 index 0000000..20d01d8 Binary files /dev/null and b/src/infrastructure/api/microservicio_b/__pycache__/microservices.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_b/__pycache__/root.cpython-314.pyc b/src/infrastructure/api/microservicio_b/__pycache__/root.cpython-314.pyc new file mode 100644 index 0000000..1fec5bd Binary files /dev/null and b/src/infrastructure/api/microservicio_b/__pycache__/root.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_b/__pycache__/router.cpython-314.pyc b/src/infrastructure/api/microservicio_b/__pycache__/router.cpython-314.pyc new file mode 100644 index 0000000..b3f3f2e Binary files /dev/null and b/src/infrastructure/api/microservicio_b/__pycache__/router.cpython-314.pyc differ diff --git a/src/infrastructure/api/microservicio_b/app.py b/src/infrastructure/api/microservicio_b/app.py new file mode 100644 index 0000000..7b5d302 --- /dev/null +++ b/src/infrastructure/api/microservicio_b/app.py @@ -0,0 +1,10 @@ +from fastapi import FastAPI +from core.config import ConfSettings +from infrastructure.api.microservicio_b.router import router + +def create_app() -> FastAPI: + app = FastAPI(title=ConfSettings.api_b_title, + version=ConfSettings.api_b_version, + description=ConfSettings.api_b_description) + app.include_router(router) + return app diff --git a/src/infrastructure/api/microservicio_b/microservices.py b/src/infrastructure/api/microservicio_b/microservices.py new file mode 100644 index 0000000..0a9fa85 --- /dev/null +++ b/src/infrastructure/api/microservicio_b/microservices.py @@ -0,0 +1,79 @@ +from fastapi import APIRouter, HTTPException +from application.services.microservicio_b_service import Save, ViewAllMsb, ViewById, Remove, EditById +from infrastructure.adapters.persistence.microservicio_b_repository_sql import SqlMicroservicioBRepository +from domain.MicroservicioB import MicroservicioB + +router = APIRouter() + +@router.post("/") +def create_msb(metodoPagoPredeterminado: str, historialFacturas: str, fechaProximoPago: str): + service = Save(SqlMicroservicioBRepository()) + + try: + return service.execute(metodoPagoPredeterminado, historialFacturas, fechaProximoPago) + except Exception as e: + raise HTTPException( + status_code=400, + detail=str(e) + ) + +@router.get("/") +def view_all_msb(): + service = ViewAllMsb(SqlMicroservicioBRepository()) + + try: + return service.execute() + except Exception as e: + raise HTTPException( + status_code=500, + detail=str(e) + ) + +@router.get("/{msb_id}") +def view_msb_by_id(msb_id: int): + service = ViewById(SqlMicroservicioBRepository()) + + result = service.execute(msb_id) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result + +@router.delete("/{msb_id}") +def delete_msb_by_id(msb_id: int): + service = Remove(SqlMicroservicioBRepository()) + + result = service.execute(msb_id) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result + +@router.put("/{msb_id}") +def edit_msb_by_id(msb_id: int, metodoPagoPredeterminado: str, historialFacturas: str, fechaProximoPago: str): + service = EditById(SqlMicroservicioBRepository()) + + try: + msb = MicroservicioB(msb_id=msb_id, metodoPagoPredeterminado=metodoPagoPredeterminado, historialFacturas=historialFacturas, fechaProximoPago=fechaProximoPago) + result = service.execute(msb_id=msb_id, msb=msb) + except Exception as e: + raise HTTPException( + status_code=500, + detail=str(e) + ) + + if result is None: + raise HTTPException( + status_code=404, + detail="Microservice not found" + ) + + return result diff --git a/src/infrastructure/api/microservicio_b/root.py b/src/infrastructure/api/microservicio_b/root.py new file mode 100644 index 0000000..a84bc57 --- /dev/null +++ b/src/infrastructure/api/microservicio_b/root.py @@ -0,0 +1,16 @@ +from fastapi import APIRouter +import platform + +router = APIRouter() + +@router.get("/") +def root(): + uname = platform.uname() + return { + "machine": { + "OS": f"{uname.system} {uname.release}", + "Arch": uname.machine + }, + "Status": "Running", + "Docs": "/docs" + } diff --git a/src/infrastructure/api/microservicio_b/router.py b/src/infrastructure/api/microservicio_b/router.py new file mode 100644 index 0000000..713cd44 --- /dev/null +++ b/src/infrastructure/api/microservicio_b/router.py @@ -0,0 +1,17 @@ +from fastapi import APIRouter +from infrastructure.api.microservicio_b.microservices import router as microservices_router +from infrastructure.api.microservicio_b.root import router as root_router + +router = APIRouter() + +router.include_router( + microservices_router, + prefix="/microservicio_b", + tags=["microservicio b"] +) + +router.include_router( + root_router, + prefix='', + tags=["root"] +) diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..de8502d --- /dev/null +++ b/src/main.py @@ -0,0 +1,52 @@ +from infrastructure.api.microservicio_a.app import create_app as create_msa_app +from infrastructure.api.microservicio_b.app import create_app as create_msb_app +from core.config import ConfSettings +import threading +import uvicorn + +def run_msa_api(): + """Ejecuta la API de usuarios en puerto 8000""" + app_msa_app = create_msa_app() + uvicorn.run( + app_msa_app, + host=ConfSettings.host, + port=ConfSettings.api_a_port, + reload=False, + log_level=ConfSettings.log_level, + ) + +def run_msb_api(): + """Ejecuta la API del microservicio B""" + app_msb_app = create_msb_app() + uvicorn.run( + app_msb_app, + host=ConfSettings.host, + port=ConfSettings.api_b_port, + reload=False, + log_level=ConfSettings.log_level, + ) + +def run(): + """Inicia ambas APIs en threads separados""" + print("Iniciando microservicios...") + + msa_thread = threading.Thread(target=run_msa_api, daemon=True, name="Microservice-A-API") + msb_thread = threading.Thread(target=run_msb_api, daemon=True, name="Microservice-B-API") + + msa_thread.start() + msb_thread.start() + + print("API del microservicio A ejecutándose en http://0.0.0.0:" + str(ConfSettings.api_a_port)) + print("API del microservicio B ejecutándose en http://0.0.0.0:" + str(ConfSettings.api_b_port)) + print("\nDocumentación disponible en:") + print(" - Microservicio A: http://localhost:" + str(ConfSettings.api_a_port) + "/docs") + print(" - Microservicio B: http://localhost:" + str(ConfSettings.api_b_port) + "/docs") + + try: + msa_thread.join() + msb_thread.join() + except KeyboardInterrupt: + print("\n\nAteniendo señal de salida...") + +if __name__ == "__main__": + run() \ No newline at end of file