Martín Miranda

Creación del proyecto Sage API con FastAPI and Starlatte

  1 +__pycache__/
  2 +.idea
  3 +
  4 +.env
  5 +
  1 +DEBUG=False
  2 +
  3 +DATABASE_URL=mssql+pymssql://user:password@database_host/db_name
  1 +from sqlalchemy import create_engine, MetaData, Table
  2 +from sqlalchemy.orm import mapper
  3 +from sqlalchemy.sql import select
  4 +
  5 +from config import settings
  6 +
  7 +
  8 +class Persona(object):
  9 + pass
  10 +
  11 +
  12 +engine = create_engine(settings.database_url)
  13 +metadata = MetaData(engine)
  14 +
  15 +tabla_persona = Table('tb_personas', metadata, autoload=True)
  16 +mapper(Persona, tabla_persona)
  17 +
  18 +print(tabla_persona.columns)
  19 +
  20 +# Ejecutar una query
  21 +conn = engine.connect()
  22 +s = select([Persona.Apellido]).where(Persona.id == 802)
  23 +res = conn.execute(s)
  24 +row = res.fetchone()
  25 +res = None if row is None else row['ColumnName']
  26 +print(res)
  1 +from sqlalchemy import Column, INTEGER, VARCHAR, ForeignKey, DATE
  2 +from sqlalchemy.orm import relationship
  3 +
  4 +from database import ModelBase
  5 +
  6 +
  7 +class Sexo(ModelBase):
  8 + __tablename__ = 'tb_sexo'
  9 +
  10 + id = Column('idSexo', INTEGER(), primary_key=True, nullable=False)
  11 + nombre = Column('Descripcion', VARCHAR(length=17), nullable=False)
  12 + abreviacion = Column('Mnemo', VARCHAR(length=1))
  13 +
  14 + def __str__(self):
  15 + return f"{self.nombre}"
  16 +
  17 + def __repr__(self):
  18 + return f"<Sexo: {self}>"
  19 +
  20 +
  21 +class Persona(ModelBase):
  22 + __tablename__ = 'tb_personas'
  23 +
  24 + id = Column('idPersona', INTEGER(), primary_key=True, nullable=False)
  25 + apellido = Column('Apellido', VARCHAR(length=100), nullable=False)
  26 + nombres = Column('Nombres', VARCHAR(length=100), nullable=False)
  27 + cuil = Column('CUIL', VARCHAR(length=20))
  28 + documento = Column('Documento', INTEGER(), nullable=False)
  29 + fecha_nacimiento = Column('FechaNacimiento', DATE(), nullable=False)
  30 + domicilio = Column('Domicilio', VARCHAR(length=100))
  31 + email = Column('Email', VARCHAR(length=50))
  32 + sexo_id = Column('Sexo', INTEGER(), ForeignKey('tb_sexo.idSexo'), nullable=False)
  33 + sexo = relationship('Sexo')
  34 + es_discapacitado = Column('EsDiscapacitado', VARCHAR(length=1), nullable=False)
  35 + codigo_postal = Column('CodPostal', VARCHAR(length=20))
  36 +
  37 + def __str__(self):
  38 + return f"{self.apellido}, {self.nombres}"
  39 +
  40 + def __repr__(self):
  41 + return f"<Persona {self}>"
  1 +from typing import List, Optional
  2 +
  3 +from fastapi import APIRouter, Depends, HTTPException
  4 +from sqlalchemy.orm import Session
  5 +
  6 +from database import get_db
  7 +from persona.models import Sexo, Persona
  8 +from persona.schemas import SexoSchema, PersonaSchema
  9 +
  10 +router = APIRouter()
  11 +
  12 +
  13 +@router.get("/sexos/", response_model=List[SexoSchema])
  14 +def obtener_sexos(db: Session = Depends(get_db)):
  15 + queryset = db.query(Sexo).all()
  16 + return queryset
  17 +
  18 +
  19 +@router.get('/personas/', response_model=List[PersonaSchema])
  20 +def obtener_personas(
  21 + skip: int = 0,
  22 + limit: int = 50,
  23 + search: Optional[str] = None,
  24 + db: Session = Depends(get_db)):
  25 +
  26 + if search:
  27 + return db.query(Persona).filter(Persona.documento == search).all()
  28 +
  29 + return db.query(Persona).offset(skip).limit(limit).all()
  30 +
  31 +
  32 +@router.get('/personas/{persona_id}/', response_model=PersonaSchema)
  33 +def obtener_persona_por_id(persona_id: int, db: Session = Depends(get_db)):
  34 + persona = db.query(Persona).filter(Persona.id == persona_id).first()
  35 +
  36 + if persona is None:
  37 + raise HTTPException(status_code=404, detail=f"No se encontró la persona con id {persona_id}")
  38 +
  39 + return persona
  1 +from datetime import date
  2 +from typing import Optional
  3 +
  4 +import pydantic
  5 +
  6 +
  7 +class SexoSchema(pydantic.BaseModel):
  8 + id: int
  9 + nombre: str
  10 + abreviacion: Optional[str] = None
  11 +
  12 + class Config:
  13 + orm_mode = True
  14 +
  15 +
  16 +class PersonaSchema(pydantic.BaseModel):
  17 + id: int
  18 + apellido: str
  19 + nombres: str
  20 + cuil: Optional[str] = None
  21 + documento: int
  22 + fecha_nacimiento: date
  23 + domicilio: Optional[str] = None
  24 + email: Optional[str] = None
  25 + sexo: SexoSchema
  26 + es_discapacitado: str
  27 + codigo_postal: Optional[str] = None
  28 +
  29 + class Config:
  30 + orm_mode = True
  1 +import sys
  2 +from pathlib import Path
  3 +
  4 +from pydantic import BaseSettings
  5 +
  6 +
  7 +ROOT_DIR = Path(__file__).resolve().parent.parent
  8 +PROJECT_DIR = ROOT_DIR / 'project'
  9 +APPS_DIR = PROJECT_DIR / 'apps'
  10 +
  11 +sys.path.append(str(APPS_DIR)) # Add imports for apps.
  12 +
  13 +
  14 +class Settings(BaseSettings):
  15 + database_url: str = 'example'
  16 + debug: bool = False
  17 +
  18 + class Config:
  19 + env_file = str(ROOT_DIR / '.env')
  20 +
  21 +
  22 +settings = Settings()
  1 +from sqlalchemy import create_engine, MetaData
  2 +from sqlalchemy.ext.declarative import declarative_base
  3 +from sqlalchemy.orm import sessionmaker
  4 +
  5 +from config import settings
  6 +
  7 +
  8 +engine = create_engine(settings.database_url)
  9 +metadata = MetaData(engine)
  10 +
  11 +ModelBase = declarative_base(metadata=metadata)
  12 +SessionLocal = sessionmaker(engine, autoflush=False, autocommit=False)
  13 +
  14 +
  15 +# Dependency
  16 +def get_db():
  17 + try:
  18 + db = SessionLocal()
  19 + yield db
  20 + finally:
  21 + db.close()
  1 +from fastapi import FastAPI
  2 +
  3 +from config import settings
  4 +from persona.routers import router as persona_router
  5 +
  6 +
  7 +app = FastAPI(debug=settings.debug)
  8 +
  9 +app.include_router(persona_router)
  1 +# Fastapi
  2 +fastapi==0.61.1
  3 +python-dotenv==0.14.0
  4 +
  5 +# Database
  6 +SQLAlchemy==1.3.20
  7 +pymssql==2.1.5
  1 +-r base.txt
  2 +
  3 +ipython==7.18.1
  4 +
  5 +# server development
  6 +uvicorn==0.12.2