Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

primeiro #17

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI
on:
push:
branches:
- "*"
pull_request:
branches:
- "*"
workflow_dispatch:

jobs:
test:
strategy:
fail-fast: true
matrix:
python-version: ['3.8', '3.10']
os: [ubuntu-latest]
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: ${{matrix.python-version}}
- name: Install Poetry
run: pip install --upgrade pip && pip install poetry

- name: Install Project
run: poetry install

- name: Look for style errors
run: poetry run flake8 beerlog

- name: Look for auto format errors
run: poetry run black -l 79 --check --diff beerlog tests

- name: Run tests
run: poetry run pytest -v --junitxml=test-result.xml

- name: publish junit results
uses: EnricoMi/publish-unit-test-result-action@v1
if: always()
with:
files: test-result.xml
check_name: Test Result (Python ${{matrix.python-version}})
Binary file added beerlog.db
Binary file not shown.
28 changes: 28 additions & 0 deletions beerlog/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from fastapi import FastAPI, Response, status
from typing import Optional, List
from beerlog.core import get_beers_from_database
from beerlog.serializers import BeerIn, BeerOut
from beerlog.models import Beer
from beerlog.database import get_session


api = FastAPI(title="beerlog")


@api.get("/beers", response_model=List[BeerOut])
async def list_beers(style: Optional[str] = None):
"""Lists beers from the database"""
beers = get_beers_from_database(style)
return beers


@api.post("/beers", response_model=BeerOut)
async def add_beer(beer_in: BeerIn, response: Response):
beer = Beer(**beer_in.dict())
with get_session() as session:
session.add(beer)
session.commit()
session.refresh(beer)

response.status_code = status.HTTP_201_CREATED
return beer
64 changes: 61 additions & 3 deletions beerlog/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,63 @@
from .config import settings
# import sys
# from .config import settings
#
#
# def main():
# for attr in sys.argv[1:]:
# print ("-> ", attr)
# # print(sys.argv)
#
# # print("Hello from", settings.NAME)

import typer
from typing import Optional
from rich.console import Console
from rich.table import Table
from rich import print

def main():
print("Hello from", settings.NAME)
from beerlog.core import add_beer_to_database, get_beers_from_database

main = typer.Typer(help="Beer Management Application")
console = Console()


@main.command("add")
def add(
name: str,
style: str,
flavor: int = typer.Option(...),
image: int = typer.Option(...),
cost: int = typer.Option(...),
):
"""Adds a new beer to database"""
# print(name, style, flavor, image, cost)
if add_beer_to_database(name, style, flavor, image, cost):
print(":beer_mug: Beer added to database")
else:
print(":no entry: - Cannot add beer")


@main.command("list")
def list_beers(style: Optional[str] = None):
"""List beers in database"""
print(style)
beers = get_beers_from_database(style)
# print(beers)
table = Table(title="beerlog" if not style else f"Beerlog {style}")
headers = [
"id",
"name",
"style",
"flavor",
"image",
"cost",
"rate",
"date",
]
for header in headers:
table.add_column(header, style="magenta")
for beer in beers:
beer.date = beer.date.strftime("%Y-%m-%d")
values = [str(getattr(beer, header)) for header in headers]
table.add_row(*values)
console.print(table)
29 changes: 29 additions & 0 deletions beerlog/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from typing import Optional, List
from sqlmodel import select
from beerlog.database import get_session
from beerlog.models import Beer


def add_beer_to_database(
name: str,
style: str,
flavor: int,
image: int,
cost: int,
) -> bool:
with get_session() as session:
beer = Beer(
name=name, style=style, flavor=flavor, image=image, cost=cost
)
session.add(beer)
session.commit()

return True


def get_beers_from_database(style: Optional[str] = None) -> List[Beer]:
with get_session() as session:
sql = select(Beer)
if style:
sql = sql.where(Beer.style == style)
return list(session.exec(sql))
19 changes: 19 additions & 0 deletions beerlog/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import warnings
from sqlalchemy.exc import SAWarning
from sqlmodel.sql.expression import Select, SelectOfScalar
from sqlmodel import create_engine, Session
from beerlog.config import settings
from beerlog import models

warnings.filterwarnings("ignore", category=SAWarning)
SelectOfScalar.inherit_cache = True
Select.inherit_cache = True


engine = create_engine(settings.database.url)

models.SQLModel.metadata.create_all(engine)


def get_session():
return Session(engine)
36 changes: 36 additions & 0 deletions beerlog/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# from dataclasses import dataclass
from typing import Optional
from sqlmodel import SQLModel, Field
from pydantic import validator

# from sqlmodel import select
from statistics import mean
from datetime import datetime


class Beer(SQLModel, table=True):
id: Optional[int] = Field(primary_key=True, default=None, index=True)
name: str
style: str
flavor: int
image: int
cost: int
rate: int = 0
date: datetime = Field(default_factory=datetime.now)

@validator("flavor", "image", "cost")
def validade_rating(cls, v, field):
if v < 1 or v > 10:
raise RuntimeError(f"{field.name} must be between 1 and 10")
return v

@validator("rate", always=True)
def calculate_rate(cls, v, values):
rate = mean([values["flavor"], values["image"], values["cost"]])
return int(rate)


# try:
brewdog = Beer(name="Brewdog", style="NEIPA", flavor=6, image=8, cost=10)
# except RuntimeError:
# print("deu zica demais")
12 changes: 12 additions & 0 deletions beerlog/rotas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from typing import Optional
from fastapi import FastAPI
from beerlog.core import get_beers_from_database

api = FastAPI(title="beerlog")


@api.get("/beers/")
def list_beers(style: Optional[str] = None):
"""Lists beers from the database"""
beers = get_beers_from_database(style)
return beers
31 changes: 31 additions & 0 deletions beerlog/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from datetime import datetime
from pydantic import BaseModel, validator
from fastapi import HTTPException, status


class BeerOut(BaseModel):
id: int
name: str
style: str
flavor: int
image: int
cost: int
rate: int
date: datetime


class BeerIn(BaseModel):
name: str
style: str
flavor: int
image: int
cost: int

@validator("image", "flavor", "cost")
def validate_ratings(cls, v, field):
if v < 1 or v > 10:
raise HTTPException(
detail=f"{field.name} must be between 1 and 10",
status_code=status.HTTP_400_BAD_REQUEST,
)
return v
5 changes: 4 additions & 1 deletion beerlog/settings.toml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
name = "beerlog"
name = "Beerlog"

[database]
url = "sqlite:///beerlog.db"
14 changes: 14 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest
from unittest.mock import patch
from sqlmodel import create_engine
from beerlog import models


@pytest.fixture(autouse=True, scope="function")
def each_test_uses_separate_database(request):
tmpdir = request.getfixturevalue("tmpdir")
test_db = tmpdir.join("beerlog.test.db")
engine = create_engine(f"sqlite:///{test_db}")
models.SQLModel.metadata.create_all(bind=engine)
with patch("beerlog.database.engine", engine):
yield # return do protocolo generator (mais poderoso que o o return)
Empty file added identifier.sqlite
Empty file.
Loading