FabioSantos commited on
Commit
e481f9d
·
verified ·
1 Parent(s): ae48807

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +25 -0
  2. app.db +0 -0
  3. database.py +23 -0
  4. main.py +131 -0
  5. models.py +28 -0
  6. requirements.txt +0 -0
  7. schemas.py +23 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
2
+ # you will also find guides on how best to write your Dockerfile
3
+
4
+ FROM python:3.9
5
+
6
+ # Cria o usuário e define o PATH
7
+ RUN useradd -m -u 1000 user
8
+ USER user
9
+ ENV PATH="/home/user/.local/bin:$PATH"
10
+
11
+ # Define o diretório de trabalho
12
+ WORKDIR /app
13
+
14
+ # Copia e instala as dependências
15
+ COPY --chown=user ./requirements.txt requirements.txt
16
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
17
+
18
+ # Cria o diretório 'uploads' dentro do contêiner com a propriedade correta
19
+ RUN mkdir -p /app/uploads && chown -R user:user /app/uploads
20
+
21
+ # Copia o restante da aplicação
22
+ COPY --chown=user . /app
23
+
24
+ # Define o comando de inicialização
25
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
app.db ADDED
Binary file (32.8 kB). View file
 
database.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy.ext.declarative import declarative_base
2
+ from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
3
+ from sqlalchemy.orm import sessionmaker
4
+
5
+ # Definindo a classe Base
6
+ Base = declarative_base()
7
+
8
+ # Configuração do motor (engine) assíncrono do SQLAlchemy
9
+ DATABASE_URL = "sqlite+aiosqlite:///./app.db"
10
+
11
+ engine = create_async_engine(
12
+ DATABASE_URL,
13
+ future=True,
14
+ echo=True
15
+ )
16
+
17
+ # Sessão assíncrona
18
+ async_session = sessionmaker(
19
+ engine,
20
+ class_=AsyncSession,
21
+ expire_on_commit=False
22
+ )
23
+
main.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, Depends, HTTPException, status, File, UploadFile, Form
2
+ from fastapi.responses import JSONResponse
3
+ from sqlalchemy.ext.asyncio import AsyncSession
4
+ from sqlalchemy import select
5
+ from database import async_session, engine
6
+ import models
7
+ import schemas
8
+ import os
9
+ from fastapi.middleware.cors import CORSMiddleware
10
+
11
+ app = FastAPI()
12
+
13
+ from fastapi.staticfiles import StaticFiles
14
+
15
+ # Monta o diretório "uploads" para servir arquivos estáticos
16
+ app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
17
+
18
+
19
+ UPLOAD_DIRECTORY = "uploads"
20
+ if not os.path.exists(UPLOAD_DIRECTORY):
21
+ os.makedirs(UPLOAD_DIRECTORY)
22
+
23
+ app.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"],
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
+
31
+ async def get_db():
32
+ async with async_session() as session:
33
+ yield session
34
+
35
+ @app.on_event("startup")
36
+ async def on_startup():
37
+ async with engine.begin() as conn:
38
+ await conn.run_sync(models.Base.metadata.create_all)
39
+
40
+ from sqlalchemy import or_
41
+
42
+ # Nova rota para buscar promoções por palavra-chave
43
+ @app.get("/promocoes/search/", response_model=list[schemas.Promocao])
44
+ async def buscar_promocoes(q: str, db: AsyncSession = Depends(get_db)):
45
+ # Realiza a busca no título ou descrição
46
+ result = await db.execute(
47
+ select(models.Promocao)
48
+ .where(or_(models.Promocao.titulo.contains(q), models.Promocao.descricao.contains(q)))
49
+ )
50
+ promocoes = result.scalars().all()
51
+ return promocoes
52
+
53
+
54
+ # 1. Criar Promoção
55
+ @app.post("/empresas/{empresa_id}/promocoes/", response_model=schemas.Promocao)
56
+ async def criar_promocao(
57
+ empresa_id: int,
58
+ titulo: str = Form(...),
59
+ descricao: str = Form(...),
60
+ imagem: UploadFile = File(...),
61
+ db: AsyncSession = Depends(get_db)
62
+ ):
63
+ # Validações de campos obrigatórios
64
+ if not titulo or not descricao:
65
+ raise HTTPException(status_code=400, detail="Campos de título e descrição são obrigatórios")
66
+
67
+ if not imagem:
68
+ raise HTTPException(status_code=400, detail="O arquivo de imagem é obrigatório")
69
+
70
+ # Salvar a imagem no diretório de uploads
71
+ image_location = os.path.join(UPLOAD_DIRECTORY, imagem.filename)
72
+ with open(image_location, "wb") as file:
73
+ content = await imagem.read()
74
+ file.write(content)
75
+
76
+ image_url = f"http://127.0.0.1:8000/uploads/{imagem.filename}"
77
+
78
+ # Criação da promoção
79
+ nova_promocao = models.Promocao(
80
+ titulo=titulo,
81
+ descricao=descricao,
82
+ imagem=image_url,
83
+ empresa_id=empresa_id
84
+ )
85
+
86
+ db.add(nova_promocao)
87
+ await db.commit()
88
+ await db.refresh(nova_promocao)
89
+ return nova_promocao
90
+
91
+ # 2. Listar Promoções de uma Empresa
92
+ @app.get("/empresas/{empresa_id}/promocoes/", response_model=list[schemas.Promocao])
93
+ async def listar_promocoes_empresa(empresa_id: int, db: AsyncSession = Depends(get_db)):
94
+ result = await db.execute(select(models.Promocao).where(models.Promocao.empresa_id == empresa_id))
95
+ promocoes = result.scalars().all()
96
+ return promocoes
97
+
98
+ # 3. Atualizar Promoção
99
+ @app.put("/empresas/{empresa_id}/promocoes/{promocao_id}", response_model=schemas.Promocao)
100
+ async def atualizar_promocao(
101
+ empresa_id: int,
102
+ promocao_id: int,
103
+ promocao: schemas.PromocaoCreate,
104
+ db: AsyncSession = Depends(get_db)
105
+ ):
106
+ result = await db.execute(select(models.Promocao).where(models.Promocao.id == promocao_id, models.Promocao.empresa_id == empresa_id))
107
+ promocao_db = result.scalars().first()
108
+
109
+ if not promocao_db:
110
+ raise HTTPException(status_code=404, detail="Promoção não encontrada.")
111
+
112
+ promocao_db.titulo = promocao.titulo
113
+ promocao_db.descricao = promocao.descricao
114
+
115
+ await db.commit()
116
+ await db.refresh(promocao_db)
117
+ return promocao_db
118
+
119
+ # 4. Deletar Promoção
120
+ @app.delete("/empresas/{empresa_id}/promocoes/{promocao_id}", status_code=status.HTTP_204_NO_CONTENT)
121
+ async def deletar_promocao(empresa_id: int, promocao_id: int, db: AsyncSession = Depends(get_db)):
122
+ result = await db.execute(select(models.Promocao).where(models.Promocao.id == promocao_id, models.Promocao.empresa_id == empresa_id))
123
+ promocao_db = result.scalars().first()
124
+
125
+ if not promocao_db:
126
+ raise HTTPException(status_code=404, detail="Promoção não encontrada.")
127
+
128
+ await db.delete(promocao_db)
129
+ await db.commit()
130
+ return JSONResponse(status_code=status.HTTP_204_NO_CONTENT, content={"message": "Promoção deletada com sucesso"})
131
+
models.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # models.py
2
+ from sqlalchemy import Column, Integer, String, ForeignKey
3
+ from sqlalchemy.orm import relationship
4
+ from database import Base
5
+
6
+ class Empresa(Base):
7
+ __tablename__ = "empresas"
8
+
9
+ id = Column(Integer, primary_key=True, index=True)
10
+ nome = Column(String, unique=True, index=True)
11
+ senha = Column(String)
12
+ promocoes = relationship("Promocao", back_populates="empresa")
13
+
14
+ class Promocao(Base):
15
+ __tablename__ = "promocoes"
16
+
17
+ id = Column(Integer, primary_key=True, index=True)
18
+ titulo = Column(String, index=True)
19
+ descricao = Column(String, index=True)
20
+ imagem = Column(String)
21
+ empresa_id = Column(Integer, ForeignKey("empresas.id")) # Relação com Empresa
22
+ empresa = relationship("Empresa", back_populates="promocoes")
23
+
24
+
25
+
26
+
27
+
28
+
requirements.txt ADDED
Binary file (1.55 kB). View file
 
schemas.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from typing import Optional
3
+
4
+ class EmpresaCreate(BaseModel):
5
+ nome: str
6
+ senha: str
7
+
8
+ class PromocaoBase(BaseModel):
9
+ titulo: str
10
+ descricao: str
11
+ imagem: Optional[str] = None
12
+
13
+ class PromocaoCreate(PromocaoBase):
14
+ pass
15
+
16
+ class Promocao(PromocaoBase):
17
+ id: int
18
+ empresa_id: int
19
+
20
+ class Config:
21
+ orm_mode = True
22
+
23
+