From ed0f15d81745198f261ea09786392f8e186c07a6 Mon Sep 17 00:00:00 2001 From: jcqueiroz Date: Mon, 25 Apr 2022 16:24:01 -0300 Subject: [PATCH 01/11] day1-completed --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bf978ef..c336274 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "extensions.showBuiltin": true, "redhat.telemetry.enabled": false, - "workbench.colorTheme": "Gruvbox Dark Hard", + "workbench.colorTheme": "★★★★★ NORD DARK ★★★★★", "editor.fontSize": 18, "git.autofetch": true, "python.insidersChannel": "off", From b7c1e1e118346c6811cca2d53bc284eb5080f874 Mon Sep 17 00:00:00 2001 From: jcqueiroz Date: Mon, 25 Apr 2022 16:27:48 -0300 Subject: [PATCH 02/11] Day1-Live-Completed --- beerlog.db | Bin 0 -> 12288 bytes beerlog/beerlog.db | Bin 0 -> 12288 bytes beerlog/database.py | 20 ++++++++++++++++++++ beerlog/models.py | 30 ++++++++++++++++++++++++++++++ beerlog/script-test.py | 25 +++++++++++++++++++++++++ beerlog/settings.toml | 3 +++ poetry.lock | 26 ++++++++++++++++++++++---- 7 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 beerlog.db create mode 100644 beerlog/beerlog.db create mode 100644 beerlog/script-test.py diff --git a/beerlog.db b/beerlog.db new file mode 100644 index 0000000000000000000000000000000000000000..3f3b4009f56e7c5c8920209c74363759d9bfd91e GIT binary patch literal 12288 zcmeI%O-sWt7zgmQ6J-V84rSNJn*;IUQ4s4EwAi&;J8`Fx*-QfM3SAlV;6eO^ej^iE zaYDU$8vj6=q)!u)Ur!HtxDQk%XM2s;<*Osnzv2|yw9_ZFu>;Kht z*lF~(tE2YbC)+>N4-^PM00Izz00bZa0SG_<0uX?}e+XRI+npoV8md_;mufklNLh|m zYMNFr=3c_d5BvOyeqt1bWa4zJ((Zd^?Q~q%`Z%w|B$MX7srG7a;#~!N^|jMhsa`DM z*E~KUr#%z7q(?9A-FPvDQ9|J`2uxsJy=KjkX(kp$SugTylFG%4Y>Ye?^QtjW3Z2TY zZ74P4zCLo|54hRLUF;9Mctp2+^nF;TYjSg)^rJuk0uX=z1Rwwb2tWV=5P$##Ah5v# i=8_-z{|5hH91Q{xfB*y_009U<00Izz00bbQ1-=0F$z19H literal 0 HcmV?d00001 diff --git a/beerlog/beerlog.db b/beerlog/beerlog.db new file mode 100644 index 0000000000000000000000000000000000000000..77db0195d87d400ed6adf82878abaf02eb8439e6 GIT binary patch literal 12288 zcmeI#&r8EF6bJCM6J-T|9m=lHn*;IUQ4s4EwAi&;J8`Fx*-QfM3SAlV;6eNg{f|s! z#R>K1X?z1|lD;P7eR_Hi_kpS;O^Y%Y6`ipIW?Af#h%sjC-qO8pX1!G}^k}Wk|C-wD zGk)hv}uwH!~REXOJ} zL#r2aFX7~eef~s0F^WPmaXMCM_dTP-kCNQsFv*yS&6N{p(5Bar8<>Ey)MxKj#)fgy+F6GxQ zl$v#4r=0i$ZZ2{c`vWf?(Jdc+C+l=gZLW)cGzdTd0uX=z1Rwwb2tWV=5P$##Hdw$h gxuO2w;6IGiAOHafKmY;|fB*y_009U<00NAC0r_lP+5i9m literal 0 HcmV?d00001 diff --git a/beerlog/database.py b/beerlog/database.py index e69de29..ecccac9 100644 --- a/beerlog/database.py +++ b/beerlog/database.py @@ -0,0 +1,20 @@ +from sqlmodel import create_engine, Session # NEW + +import warnings +from sqlalchemy.exc import SAWarning +from sqlmodel.sql.expression import Select, SelectOfScalar +warnings.filterwarnings("ignore", category=SAWarning) +SelectOfScalar.inherit_cache = True +Select.inherit_cache = True + + +from beerlog import models +from beerlog.config import settings + +engine = create_engine(settings.database.url, echo=False) +models.SQLModel.metadata.create_all(engine) + + +# NEW +def get_session(): + return Session(engine) \ No newline at end of file diff --git a/beerlog/models.py b/beerlog/models.py index e69de29..47c80f8 100644 --- a/beerlog/models.py +++ b/beerlog/models.py @@ -0,0 +1,30 @@ +from sqlmodel import SQLModel, Field +from sqlalchemy import select +from datetime import datetime +from typing import Optional +from pydantic import validator # NEW +from statistics import mean # NEW + + +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) + + # NEW + @validator("image", "flavor", "cost") + def validate_ratings(cls, v, field): + if v < 1 or v > 10: + raise RuntimeError(f"{field.name} must be between 1 and 10") + return v + + # NEW + @validator("rate", always=True) + def calculate_rate(cls, v, values): + rate = mean([values["flavor"], values["image"], values["cost"]]) + return int(rate) \ No newline at end of file diff --git a/beerlog/script-test.py b/beerlog/script-test.py new file mode 100644 index 0000000..304cc73 --- /dev/null +++ b/beerlog/script-test.py @@ -0,0 +1,25 @@ +#print(1 + 1) +#print("python".upper()) +#print(sum([1,2,3,4])) +################################################################################################################################################################ + + +event = "Python Week" +topics = ["\N{snake} Python", "\N{whale} Containers", "\N{penguin} Linux"] + +days = { + 1: "Introdução a Python", + 2: "Python para web", + 3: "Qualidade de código, testes e CI", + 4: "Análise de dados", + 5: "Perguntas" +} + +print(f"Boas vindas a {event} - um evento de {len(days)} dias") +for topic in topics: + print(f"{topic.upper()}") + +for day, title in days.items(): + print(f"{day} -> {title}") + if day == 1: + print("\t é Hoje!!!") \ No newline at end of file diff --git a/beerlog/settings.toml b/beerlog/settings.toml index 34d5fcb..d95698c 100644 --- a/beerlog/settings.toml +++ b/beerlog/settings.toml @@ -1 +1,4 @@ name = "beerlog" + +[database] +url = "sqlite:///beerlog.db" \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 185de7b..ec57120 100644 --- a/poetry.lock +++ b/poetry.lock @@ -200,6 +200,7 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = ">=2.4.0" +setuptools = ">=18.5" stack-data = "*" traitlets = ">=5" @@ -372,11 +373,11 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.11.2" +version = "2.12.0" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "rich" @@ -394,6 +395,19 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] +[[package]] +name = "setuptools" +version = "62.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] +testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] + [[package]] name = "six" version = "1.16.0" @@ -786,13 +800,17 @@ pyflakes = [ {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] pygments = [ - {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, - {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, + {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, + {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, ] rich = [ {file = "rich-12.2.0-py3-none-any.whl", hash = "sha256:c50f3d253bc6a9bb9c79d61a26d510d74abdf1b16881260fab5edfc3edfb082f"}, {file = "rich-12.2.0.tar.gz", hash = "sha256:ea74bc9dad9589d8eea3e3fd0b136d8bf6e428888955f215824c2894f0da8b47"}, ] +setuptools = [ + {file = "setuptools-62.1.0-py3-none-any.whl", hash = "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8"}, + {file = "setuptools-62.1.0.tar.gz", hash = "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, From fd8f896e92c86dbdf308b389e28ef6346447b88e Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Tue, 26 Apr 2022 15:30:07 -0300 Subject: [PATCH 03/11] Day2part2-Live-Completed --- beerlog/__main__.py | 1 + beerlog/cli.py | 40 +++++++++++++++++++++++++++++++++++++--- beerlog/core.py | 31 +++++++++++++++++++++++++++++++ beerlog/database.py | 7 ++----- beerlog/models.py | 8 ++++---- 5 files changed, 75 insertions(+), 12 deletions(-) diff --git a/beerlog/__main__.py b/beerlog/__main__.py index 9ae637f..4a548a0 100644 --- a/beerlog/__main__.py +++ b/beerlog/__main__.py @@ -2,3 +2,4 @@ if __name__ == "__main__": main() + \ No newline at end of file diff --git a/beerlog/cli.py b/beerlog/cli.py index 03c2367..a8d00bf 100644 --- a/beerlog/cli.py +++ b/beerlog/cli.py @@ -1,5 +1,39 @@ -from .config import settings +import typer +from typing import Optional +from beerlog.core import add_beer_to_database, get_beers_from_database +from rich.console import Console +from rich.table import Table +from rich import print -def main(): - print("Hello from", settings.NAME) +main = typer.Typer(help="Beer Management Application") +console = Console() + +@main.command() +def add( + name: str, + style: str, + flavor: int = typer.Option(...), + image: int = typer.Option(...), + cost: int = typer.Option(...), +): + """Adds a new beer to the database""" + if add_beer_to_database(name, style, flavor, image, cost): + print("\N{beer mug} Beer added to database!!!") + else: + print("\N{no entry} - Cannot add beer to database.") + + +@main.command("list") +def list_beers(style: Optional[str] = None): + """Lists beers from the database""" + beers = get_beers_from_database(style) + table = Table(title="Beerlog Database" 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) \ No newline at end of file diff --git a/beerlog/core.py b/beerlog/core.py index e69de29..b271398 100644 --- a/beerlog/core.py +++ b/beerlog/core.py @@ -0,0 +1,31 @@ +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)) \ No newline at end of file diff --git a/beerlog/database.py b/beerlog/database.py index ecccac9..594c775 100644 --- a/beerlog/database.py +++ b/beerlog/database.py @@ -1,5 +1,3 @@ -from sqlmodel import create_engine, Session # NEW - import warnings from sqlalchemy.exc import SAWarning from sqlmodel.sql.expression import Select, SelectOfScalar @@ -7,14 +5,13 @@ SelectOfScalar.inherit_cache = True Select.inherit_cache = True - -from beerlog import models +from sqlmodel import create_engine, Session from beerlog.config import settings +from beerlog import models engine = create_engine(settings.database.url, echo=False) models.SQLModel.metadata.create_all(engine) -# NEW def get_session(): return Session(engine) \ No newline at end of file diff --git a/beerlog/models.py b/beerlog/models.py index 47c80f8..b1e0dae 100644 --- a/beerlog/models.py +++ b/beerlog/models.py @@ -2,8 +2,8 @@ from sqlalchemy import select from datetime import datetime from typing import Optional -from pydantic import validator # NEW -from statistics import mean # NEW +from pydantic import validator +from statistics import mean class Beer(SQLModel, table=True): @@ -16,14 +16,14 @@ class Beer(SQLModel, table=True): rate: int = 0 date: datetime = Field(default_factory=datetime.now) - # NEW + @validator("image", "flavor", "cost") def validate_ratings(cls, v, field): if v < 1 or v > 10: raise RuntimeError(f"{field.name} must be between 1 and 10") return v - # NEW + @validator("rate", always=True) def calculate_rate(cls, v, values): rate = mean([values["flavor"], values["image"], values["cost"]]) From 7492dfd1067bca50c1b884d4ba8b3280bbec3961 Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Tue, 26 Apr 2022 19:28:38 -0300 Subject: [PATCH 04/11] Day2part2.1-Live-Completed --- beerlog.db | Bin 12288 -> 12288 bytes beerlog/api.py | 25 +++++++++++++++++++++ beerlog/cli.py | 1 - beerlog/core.py | 6 +++-- beerlog/database.py | 1 - beerlog/serializers.py | 29 ++++++++++++++++++++++++ poetry.lock | 49 ++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 8 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 beerlog/api.py create mode 100644 beerlog/serializers.py diff --git a/beerlog.db b/beerlog.db index 3f3b4009f56e7c5c8920209c74363759d9bfd91e..feee2b7d682d2674d7c8172927fd6219d55ea087 100644 GIT binary patch delta 289 zcmZojXh@hK&B!-V#+i|CW5N=C9u|HB2L99hGx(GF4K@o3DDc-CvT!m;3o`nS!C26%d)2>KU3DnHZZGGjlS?L$vrLrkCbrmLwKq z*JNsCYNTgmY;0*_VaSBlo List[Beer]: diff --git a/beerlog/database.py b/beerlog/database.py index 594c775..96ef7a9 100644 --- a/beerlog/database.py +++ b/beerlog/database.py @@ -12,6 +12,5 @@ engine = create_engine(settings.database.url, echo=False) models.SQLModel.metadata.create_all(engine) - def get_session(): return Session(engine) \ No newline at end of file diff --git a/beerlog/serializers.py b/beerlog/serializers.py new file mode 100644 index 0000000..a1a10a9 --- /dev/null +++ b/beerlog/serializers.py @@ -0,0 +1,29 @@ +from pydantic import BaseModel +from datetime import datetime +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 \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index ec57120..87b4688 100644 --- a/poetry.lock +++ b/poetry.lock @@ -23,6 +23,17 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "asgiref" +version = "3.5.0" +description = "ASGI specs, helper code, and adapters" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] + [[package]] name = "asttokens" version = "2.0.5" @@ -173,6 +184,14 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] docs = ["sphinx"] +[[package]] +name = "h11" +version = "0.13.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "idna" version = "3.3" @@ -554,6 +573,22 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "uvicorn" +version = "0.17.6" +description = "The lightning-fast ASGI server." +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +asgiref = ">=3.4.0" +click = ">=7.0" +h11 = ">=0.8" + +[package.extras] +standard = ["websockets (>=10.0)", "httptools (>=0.4.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"] + [[package]] name = "wcwidth" version = "0.2.5" @@ -565,7 +600,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "1e063e12af3889e809b53f9a6c5d6a76b6f76639335e397e000877ad7931ebc1" +content-hash = "f5938c803eac46f6a8cc263cd50efdaafe7b0f0a2a70ce0da6a02a660638ce7c" [metadata.files] anyio = [ @@ -576,6 +611,10 @@ appnope = [ {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, ] +asgiref = [ + {file = "asgiref-3.5.0-py3-none-any.whl", hash = "sha256:88d59c13d634dcffe0510be048210188edd79aeccb6a6c9028cdad6f31d730a9"}, + {file = "asgiref-3.5.0.tar.gz", hash = "sha256:2f8abc20f7248433085eda803936d98992f1343ddb022065779f37c5da0181d0"}, +] asttokens = [ {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, @@ -698,6 +737,10 @@ greenlet = [ {file = "greenlet-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd"}, {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, ] +h11 = [ + {file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"}, + {file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"}, +] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, @@ -889,6 +932,10 @@ typing-extensions = [ {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, ] +uvicorn = [ + {file = "uvicorn-0.17.6-py3-none-any.whl", hash = "sha256:19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6"}, + {file = "uvicorn-0.17.6.tar.gz", hash = "sha256:5180f9d059611747d841a4a4c4ab675edf54c8489e97f96d0583ee90ac3bfc23"}, +] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, diff --git a/pyproject.toml b/pyproject.toml index ad3f120..0cf0dd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ rich = "^12.2.0" dynaconf = "^3.1.8" black = "^22.3.0" flake8 = "^4.0.1" +uvicorn = "^0.17.6" [tool.poetry.dev-dependencies] ipython = "^8.2.0" From 57d9f08e2b8cc7fc499284a89e7831759bad8e2a Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Tue, 26 Apr 2022 20:04:00 -0300 Subject: [PATCH 05/11] Day2-part2.3-livecompleted --- beerlog/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beerlog/serializers.py b/beerlog/serializers.py index a1a10a9..c449f0b 100644 --- a/beerlog/serializers.py +++ b/beerlog/serializers.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel +from pydantic import BaseModel, validator from datetime import datetime from fastapi import HTTPException, status From db766c74e68030ce4de58b373f163d61ab2ec429 Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Tue, 26 Apr 2022 20:54:07 -0300 Subject: [PATCH 06/11] Day2-part2.4-livecompleted --- beerlog.db | Bin 12288 -> 0 bytes beerlog/beerlog.db | Bin 12288 -> 12288 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 beerlog.db diff --git a/beerlog.db b/beerlog.db deleted file mode 100644 index feee2b7d682d2674d7c8172927fd6219d55ea087..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#O>5LZ7zgl~B)%lzjzyLpJUHGg*pN(Sm$-s7Z3kUUcWau8J(aXcOJHAMH%fc( zAbyE{Cr^G2Po6w^a7MdWVTB&N2>*x7}LI)Bs<_Q)xpoj zdTVBH?y!KcPwavn>jVJ-2tWV=5P$##AOHafKmY;|fB*>{m)yTcb?9yNUao?$zngg8 zZC3uq$LFBikhpeoaY>)3=klDdx*3b$T7)izs>`laU__83)qS|I}e$2>Z^yv9CHoKmY;|fB*y_009U<00Izz00bcL U9}C>DDRmsv+qUT~%eGzj2l+yZ-T(jq diff --git a/beerlog/beerlog.db b/beerlog/beerlog.db index 77db0195d87d400ed6adf82878abaf02eb8439e6..268549e8d0d3a1f5b7dbf3b7b61b6d12486167bf 100644 GIT binary patch delta 106 zcmZojXh@hK&B#1a#+i|MW5N=CHb(x_4E(1z3kn?Mw>M_wWRMqT1Oi8&#Prg<%#y@n z&j3d*E>;dB10y3{0~1{%GX*09D^nvYQ)4}IO9Mkg11<&z21for4E%q9hP>xz2XdL2 GIXMAY)E7Vi delta 43 qcmZojXh@hK&B!!S#+i|6W5N=CCI*4cf(ozsCkF7daWMb^oC^Q|ObYY> From f024d67ce2c8310cefc2df0cbaa8e6e0a7ae6270 Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Wed, 27 Apr 2022 16:05:52 -0300 Subject: [PATCH 07/11] CI day3-01 --- .github/workflows.main.yaml | 44 +++++++ beerlog/beerlog.db => beerlog.db | Bin 12288 -> 12288 bytes beerlog/__main__.py | 1 - beerlog/api.py | 4 +- beerlog/cli.py | 30 +++-- beerlog/core.py | 8 +- beerlog/database.py | 12 +- beerlog/models.py | 6 +- beerlog/script-test.py | 25 ---- beerlog/serializers.py | 8 +- conftest.py | 14 ++ poetry.lock | 211 ++++++++++++++++++++++++++++--- pyproject.toml | 2 + testing.db | Bin 0 -> 12288 bytes tests/test_core.py | 11 ++ tests/test_functional_api.py | 30 +++++ tests/test_functional_cli.py | 12 ++ 17 files changed, 349 insertions(+), 69 deletions(-) create mode 100644 .github/workflows.main.yaml rename beerlog/beerlog.db => beerlog.db (96%) delete mode 100644 beerlog/script-test.py create mode 100644 testing.db create mode 100644 tests/test_core.py create mode 100644 tests/test_functional_api.py create mode 100644 tests/test_functional_cli.py diff --git a/.github/workflows.main.yaml b/.github/workflows.main.yaml new file mode 100644 index 0000000..cf1780d --- /dev/null +++ b/.github/workflows.main.yaml @@ -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}}) \ No newline at end of file diff --git a/beerlog/beerlog.db b/beerlog.db similarity index 96% rename from beerlog/beerlog.db rename to beerlog.db index 268549e8d0d3a1f5b7dbf3b7b61b6d12486167bf..f507a9184ca9ab0ac3584ee7a72b48b4d529ae94 100644 GIT binary patch delta 106 zcmZojXh@hK&B!uQ#+i|2W5N=C4krF-4E(40r)?G#=;CKGW}19fUP;hg!O+yoz{JYf zRL{uL(%8&!@@aV$S(vDSfu5O#k-3=(7Xt$W6aO~`{y+TRHVZ1e;^$&zW@KbyVrJ&# F1OT4S7-s+g delta 74 zcmZojXh@hK&B#1a#+i|MW5N=CHb(x_4E(1z3o0DspL|+gMcPck$iT|f$ja1M&)m|$ d(9nR3fq{XM{|^KIAE2VA{1XFsS(uqQIRW`;60raP diff --git a/beerlog/__main__.py b/beerlog/__main__.py index 4a548a0..9ae637f 100644 --- a/beerlog/__main__.py +++ b/beerlog/__main__.py @@ -2,4 +2,3 @@ if __name__ == "__main__": main() - \ No newline at end of file diff --git a/beerlog/api.py b/beerlog/api.py index 976d403..33b9a87 100644 --- a/beerlog/api.py +++ b/beerlog/api.py @@ -7,12 +7,14 @@ 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()) @@ -22,4 +24,4 @@ async def add_beer(beer_in: BeerIn, response: Response): session.refresh(beer) response.status_code = status.HTTP_201_CREATED - return beer \ No newline at end of file + return beer diff --git a/beerlog/cli.py b/beerlog/cli.py index 5f366c6..7cdde99 100644 --- a/beerlog/cli.py +++ b/beerlog/cli.py @@ -1,14 +1,16 @@ import typer from typing import Optional +from rich.console import Console # NEW +from rich.table import Table # NEW +from rich import print # NEW + from beerlog.core import add_beer_to_database, get_beers_from_database -from rich.console import Console -from rich.table import Table -from rich import print main = typer.Typer(help="Beer Management Application") console = Console() + @main.command() def add( name: str, @@ -19,20 +21,32 @@ def add( ): """Adds a new beer to the database""" if add_beer_to_database(name, style, flavor, image, cost): - print("\N{beer mug} Beer added to database!!!") + print(":beer_mug: Beer added!!!") # NEW else: - print("\N{no entry} - Cannot add beer to database.") + print(":no_entry: - Cannot add beer.") # NEW + @main.command("list") def list_beers(style: Optional[str] = None): """Lists beers from the database""" beers = get_beers_from_database(style) - table = Table(title="Beerlog Database" if not style else f"Beerlog {style}") - headers = ["id", "name", "style", "flavor", "image", "cost", "rate", "date"] + table = Table( + title="Beerlog Database" 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) \ No newline at end of file + console.print(table) diff --git a/beerlog/core.py b/beerlog/core.py index 5c2d5eb..39969f9 100644 --- a/beerlog/core.py +++ b/beerlog/core.py @@ -3,6 +3,7 @@ from beerlog.database import get_session from beerlog.models import Beer + def add_beer_to_database( name: str, style: str, @@ -20,14 +21,15 @@ def add_beer_to_database( ) beer = Beer(name="Lagunitas", style="IPA", flavor=10, image=10, cost=5) session.add(beer) - session.commit() + session.commit() for beer in session.exec(select(Beer).where(Beer.style == "IPA")): - print(beer.name, beer.style, beer.rate) + print(beer.name, beer.style, beer.rate) 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)) \ No newline at end of file + return list(session.exec(sql)) diff --git a/beerlog/database.py b/beerlog/database.py index 96ef7a9..2273797 100644 --- a/beerlog/database.py +++ b/beerlog/database.py @@ -1,16 +1,18 @@ import warnings from sqlalchemy.exc import SAWarning from sqlmodel.sql.expression import Select, SelectOfScalar +from sqlmodel import create_engine, Session + +from beerlog import models +from beerlog.config import settings + warnings.filterwarnings("ignore", category=SAWarning) SelectOfScalar.inherit_cache = True Select.inherit_cache = True -from sqlmodel import create_engine, Session -from beerlog.config import settings -from beerlog import models - engine = create_engine(settings.database.url, echo=False) models.SQLModel.metadata.create_all(engine) + def get_session(): - return Session(engine) \ No newline at end of file + return Session(engine) diff --git a/beerlog/models.py b/beerlog/models.py index b1e0dae..b9dab1b 100644 --- a/beerlog/models.py +++ b/beerlog/models.py @@ -3,7 +3,7 @@ from datetime import datetime from typing import Optional from pydantic import validator -from statistics import mean +from statistics import mean class Beer(SQLModel, table=True): @@ -16,15 +16,13 @@ class Beer(SQLModel, table=True): rate: int = 0 date: datetime = Field(default_factory=datetime.now) - @validator("image", "flavor", "cost") def validate_ratings(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) \ No newline at end of file + return int(rate) diff --git a/beerlog/script-test.py b/beerlog/script-test.py deleted file mode 100644 index 304cc73..0000000 --- a/beerlog/script-test.py +++ /dev/null @@ -1,25 +0,0 @@ -#print(1 + 1) -#print("python".upper()) -#print(sum([1,2,3,4])) -################################################################################################################################################################ - - -event = "Python Week" -topics = ["\N{snake} Python", "\N{whale} Containers", "\N{penguin} Linux"] - -days = { - 1: "Introdução a Python", - 2: "Python para web", - 3: "Qualidade de código, testes e CI", - 4: "Análise de dados", - 5: "Perguntas" -} - -print(f"Boas vindas a {event} - um evento de {len(days)} dias") -for topic in topics: - print(f"{topic.upper()}") - -for day, title in days.items(): - print(f"{day} -> {title}") - if day == 1: - print("\t é Hoje!!!") \ No newline at end of file diff --git a/beerlog/serializers.py b/beerlog/serializers.py index c449f0b..3a56628 100644 --- a/beerlog/serializers.py +++ b/beerlog/serializers.py @@ -2,6 +2,7 @@ from datetime import datetime from fastapi import HTTPException, status + class BeerOut(BaseModel): id: int name: str @@ -12,6 +13,7 @@ class BeerOut(BaseModel): rate: int date: datetime + class BeerIn(BaseModel): name: str style: str @@ -23,7 +25,7 @@ class BeerIn(BaseModel): 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 + detail=f"{field.name} must be between 1 and 10", + status_code=status.HTTP_400_BAD_REQUEST, ) - return v \ No newline at end of file + return v diff --git a/conftest.py b/conftest.py index e69de29..745474e 100644 --- a/conftest.py +++ b/conftest.py @@ -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 \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 87b4688..c15bcf6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -48,6 +48,28 @@ six = "*" [package.extras] test = ["astroid", "pytest"] +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "21.4.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] + [[package]] name = "backcall" version = "0.2.0" @@ -78,6 +100,25 @@ d = ["aiohttp (>=3.7.4)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] +[[package]] +name = "certifi" +version = "2021.10.8" +description = "Python package for providing Mozilla's CA Bundle." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "charset-normalizer" +version = "2.0.12" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" +optional = false +python-versions = ">=3.5.0" + +[package.extras] +unicode_backport = ["unicodedata2"] + [[package]] name = "click" version = "8.1.2" @@ -200,6 +241,14 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "ipython" version = "8.2.0" @@ -219,7 +268,6 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = ">=2.4.0" -setuptools = ">=18.5" stack-data = "*" traitlets = ">=5" @@ -278,6 +326,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + [[package]] name = "parso" version = "0.8.3" @@ -329,6 +388,18 @@ python-versions = ">=3.7" docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + [[package]] name = "prompt-toolkit" version = "3.0.29" @@ -359,6 +430,14 @@ python-versions = "*" [package.extras] tests = ["pytest"] +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "pycodestyle" version = "2.8.0" @@ -398,6 +477,56 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "pyparsing" +version = "3.0.8" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "dev" +optional = false +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["railroad-diagrams", "jinja2"] + +[[package]] +name = "pytest" +version = "7.1.2" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +tomli = ">=1.0.0" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "requests" +version = "2.27.1" +description = "Python HTTP for Humans." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} +idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +urllib3 = ">=1.21.1,<1.27" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] + [[package]] name = "rich" version = "12.2.0" @@ -414,19 +543,6 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] -[[package]] -name = "setuptools" -version = "62.1.0" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] -testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] - [[package]] name = "six" version = "1.16.0" @@ -573,6 +689,19 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "urllib3" +version = "1.26.9" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[package.extras] +brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] +secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + [[package]] name = "uvicorn" version = "0.17.6" @@ -600,7 +729,7 @@ python-versions = "*" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "f5938c803eac46f6a8cc263cd50efdaafe7b0f0a2a70ce0da6a02a660638ce7c" +content-hash = "2a4e0a23a207eca63dab3626d724d027ff67e5d16ae03edb87cffa33219d95f6" [metadata.files] anyio = [ @@ -619,6 +748,14 @@ asttokens = [ {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"}, {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"}, ] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, @@ -648,6 +785,14 @@ black = [ {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, ] +certifi = [ + {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, + {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, +] +charset-normalizer = [ + {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, + {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, +] click = [ {file = "click-8.1.2-py3-none-any.whl", hash = "sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e"}, {file = "click-8.1.2.tar.gz", hash = "sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72"}, @@ -745,6 +890,10 @@ idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] ipython = [ {file = "ipython-8.2.0-py3-none-any.whl", hash = "sha256:1b672bfd7a48d87ab203d9af8727a3b0174a4566b4091e9447c22fb63ea32857"}, {file = "ipython-8.2.0.tar.gz", hash = "sha256:70e5eb132cac594a34b5f799bd252589009905f05104728aea6a403ec2519dc1"}, @@ -765,6 +914,10 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] parso = [ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, @@ -785,6 +938,10 @@ platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, ] +pluggy = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] prompt-toolkit = [ {file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"}, {file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"}, @@ -797,6 +954,10 @@ pure-eval = [ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] +py = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] pycodestyle = [ {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, @@ -846,14 +1007,22 @@ pygments = [ {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"}, {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, ] +pyparsing = [ + {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, + {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, +] +pytest = [ + {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, + {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"}, +] +requests = [ + {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, + {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, +] rich = [ {file = "rich-12.2.0-py3-none-any.whl", hash = "sha256:c50f3d253bc6a9bb9c79d61a26d510d74abdf1b16881260fab5edfc3edfb082f"}, {file = "rich-12.2.0.tar.gz", hash = "sha256:ea74bc9dad9589d8eea3e3fd0b136d8bf6e428888955f215824c2894f0da8b47"}, ] -setuptools = [ - {file = "setuptools-62.1.0-py3-none-any.whl", hash = "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8"}, - {file = "setuptools-62.1.0.tar.gz", hash = "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -932,6 +1101,10 @@ typing-extensions = [ {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, ] +urllib3 = [ + {file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, + {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, +] uvicorn = [ {file = "uvicorn-0.17.6-py3-none-any.whl", hash = "sha256:19e2a0e96c9ac5581c01eb1a79a7d2f72bb479691acd2b8921fce48ed5b961a6"}, {file = "uvicorn-0.17.6.tar.gz", hash = "sha256:5180f9d059611747d841a4a4c4ab675edf54c8489e97f96d0583ee90ac3bfc23"}, diff --git a/pyproject.toml b/pyproject.toml index 0cf0dd3..a5f61d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,8 @@ uvicorn = "^0.17.6" [tool.poetry.dev-dependencies] ipython = "^8.2.0" +pytest = "^7.1.2" +requests = "^2.27.1" [tool.poetry.scripts] beerlog = "beerlog.__main__:main" diff --git a/testing.db b/testing.db new file mode 100644 index 0000000000000000000000000000000000000000..be2d477013a87b3c63654ee85d038efc4e082eab GIT binary patch literal 12288 zcmeI#O-sWt7zgmAoi8nD6&W6lHwQXuXLX$*)~)EUc3P|GX>_(qVK2~C(Srx^JNTtM z`DHwLFdZu@4Dlcy5R&6Xf`eu^&;reBCM%PRx~AOHafKmY;|fB*y_009U<;5P)egz@>sJUxlJL3kV8 zHd|pBH=`hJ#HwqVp2g};%{pTrIo5DknrBNM3ix53wQIS{OqRNSCuFClTir8V<}^I!oY;1n=qGpW(V5G(f76SzL%wW^I{sBS zGIP=ECnFQF&%g4YE)=BW8h^4^Kd{n^9J=)b(>-VV*7@MEa$)c{SDuLS%qs*0AOHaf zKmY;|fB*y_009U<00Ms~P!c4vFh_ZqwtscqjS|0KKQv`|Y*JG-ZAD#M(KgtsUeVSo zs!`l93{BTd^oN_&^@?6D8f8N-ugd&Yg7Qj~H(nti009U<00Izz00bZa0SG_<0ucB| N0%Ibjf*^{L^bW%$cPjt@ literal 0 HcmV?d00001 diff --git a/tests/test_core.py b/tests/test_core.py new file mode 100644 index 0000000..101b6b8 --- /dev/null +++ b/tests/test_core.py @@ -0,0 +1,11 @@ +from beerlog.core import get_beers_from_database, add_beer_to_database + + +def test_add_beer_to_database(): + # ARRANGE + assert add_beer_to_database("Blue Moon", "Witbier", 10, 3, 6) + # ACT + results = get_beers_from_database() + # ASSERT + assert len(results) > 0 + diff --git a/tests/test_functional_api.py b/tests/test_functional_api.py new file mode 100644 index 0000000..7603a67 --- /dev/null +++ b/tests/test_functional_api.py @@ -0,0 +1,30 @@ +from fastapi.testclient import TestClient + +from beerlog.api import api + + +client = TestClient(api) + + +def test_create_beer_via_api(): + response = client.post( + "/beers", + json={ + "name": "Skol", + "style": "KornPA", + "flavor": 1, + "image": 1, + "cost": 2 + }, + ) + assert response.status_code == 201 + result = response.json() + assert result["name"] == "Skol" + assert result["id"] == 1 + + +def test_list_beers(): + response = client.get("/beers") + assert response.status_code == 200 + result = response.json() + assert len(result) == 0 \ No newline at end of file diff --git a/tests/test_functional_cli.py b/tests/test_functional_cli.py new file mode 100644 index 0000000..d836cce --- /dev/null +++ b/tests/test_functional_cli.py @@ -0,0 +1,12 @@ +from typer.testing import CliRunner + +from beerlog.cli import main + +runner = CliRunner() + + +def test_add_beer(): + result = runner.invoke( + main, ["add", "Skol", "KornPA", "--flavor=1", "--image=2", "--cost=3"]) + assert result.exit_code == 0 + assert "Beer added" in result.stdout \ No newline at end of file From 8e4504ce3dc88cfa8d5a73f2fecae1129587d3d5 Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Wed, 27 Apr 2022 16:19:37 -0300 Subject: [PATCH 08/11] CI day3-03 --- .github/workflows.main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows.main.yaml b/.github/workflows.main.yaml index cf1780d..b75c334 100644 --- a/.github/workflows.main.yaml +++ b/.github/workflows.main.yaml @@ -14,7 +14,7 @@ jobs: fail-fast: true matrix: python-version: ['3.8', '3.10'] - os: [ubuntu-latest] + os: ['20.04'] runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v2 From 0b0f5a89ae0f9697344fb7d87a0ef52415e2b956 Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Sat, 30 Apr 2022 03:19:29 -0300 Subject: [PATCH 09/11] CI-day3-03 --- .github/{workflows.main.yaml => main.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{workflows.main.yaml => main.yaml} (100%) diff --git a/.github/workflows.main.yaml b/.github/main.yaml similarity index 100% rename from .github/workflows.main.yaml rename to .github/main.yaml From 782b9e0981d5d656f1e8088c0db87d9824af90ac Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Sat, 30 Apr 2022 03:49:19 -0300 Subject: [PATCH 10/11] CI day3-04 --- beerlog/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/beerlog/models.py b/beerlog/models.py index b9dab1b..154563b 100644 --- a/beerlog/models.py +++ b/beerlog/models.py @@ -1,5 +1,4 @@ from sqlmodel import SQLModel, Field -from sqlalchemy import select from datetime import datetime from typing import Optional from pydantic import validator From 3fdfbb475f2f6b97c3274ab59860bc8edfdd4bea Mon Sep 17 00:00:00 2001 From: Jean Queiroz Date: Sat, 30 Apr 2022 04:04:02 -0300 Subject: [PATCH 11/11] CI day3-05 --- .github/{ => workflows}/main.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/main.yaml (100%) diff --git a/.github/main.yaml b/.github/workflows/main.yaml similarity index 100% rename from .github/main.yaml rename to .github/workflows/main.yaml