Skip to content

Commit 8ebe37a

Browse files
authored
Merge pull request #10 from proafxin/refactor
Refactor
2 parents 9b4ac52 + 2e3480c commit 8ebe37a

File tree

14 files changed

+1067
-1169
lines changed

14 files changed

+1067
-1169
lines changed

.coveragerc

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/python-package.yml renamed to .github/workflows/ci.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ jobs:
2020
strategy:
2121
fail-fast: false
2222
matrix:
23-
python-version: ["3.10", "3.11"]
23+
python-version: ["3.11", "3.12"]
2424

2525
steps:
26-
- uses: actions/checkout@v3
26+
- uses: actions/checkout@master
2727
- name: Set up Python ${{ matrix.python-version }}
28-
uses: actions/setup-python@v3
28+
uses: actions/setup-python@master
2929
with:
3030
python-version: ${{ matrix.python-version }}
3131
- name: Tox
@@ -34,11 +34,11 @@ jobs:
3434
python -m pip install -U tox
3535
tox
3636
- name: Trunk Check
37-
uses: trunk-io/trunk-action@v1
38-
37+
uses: trunk-io/trunk-action@main
38+
3939
- name: Upload coverage reports to Codecov
40-
uses: codecov/codecov-action@v3
41-
40+
uses: codecov/codecov-action@main
41+
4242
with:
4343
token: ${{ secrets.CODECOV_TOKEN }}
4444
directory: ./

.trunk/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
plugins
77
user_trunk.yaml
88
user.yaml
9+
tmp

.trunk/trunk.yaml

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
version: 0.1
22
cli:
3-
version: 1.15.0
3+
version: 1.22.2
44
plugins:
55
sources:
66
- id: trunk
7-
ref: v1.2.3
7+
ref: v1.6.0
88
uri: https://github.com/trunk-io/plugins
99
runtimes:
1010
enabled:
1111
- node@18.12.1
1212
- python@3.10.8
1313
lint:
1414
enabled:
15-
- actionlint@1.6.25
16-
- checkov@2.4.9
17-
- isort@5.12.0
18-
- osv-scanner@1.3.6
19-
- yamllint@1.32.0
20-
- bandit@1.7.5
21-
- black@23.7.0
15+
- actionlint@1.7.1
16+
- checkov@3.2.136
17+
- isort@5.13.2
18+
- osv-scanner@1.7.4
19+
- yamllint@1.35.1
20+
- bandit@1.7.9
21+
- black@24.4.2
2222
- git-diff-check
23-
- markdownlint@0.36.0
24-
- prettier@3.0.3
25-
- ruff@0.0.287
23+
- markdownlint@0.41.0
24+
- prettier@3.3.2
25+
- ruff@0.4.8
2626
- taplo@0.8.1
27-
- trivy@0.45.0
28-
- trufflehog@3.54.3
27+
- trivy@0.52.1
28+
- trufflehog@3.78.1
2929

3030
ignore:
3131
- linters: [ALL]
@@ -35,9 +35,8 @@ lint:
3535
- Dockerfile
3636
- .github/workflows/*.yml
3737
actions:
38-
disabled:
38+
enabled:
39+
- trunk-upgrade-available
3940
- trunk-announce
4041
- trunk-check-pre-push
4142
- trunk-fmt-pre-commit
42-
enabled:
43-
- trunk-upgrade-available

codecov.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ coverage:
22
precision: 2
33
round: up
44
# trunk-ignore(yamllint/quoted-strings)
5-
range: "95...100"
5+
range: "85...100"
66
status:
77
patch:
88
default:
9-
target: 95%
9+
target: 85%
1010
project:
1111
default:
12-
target: 95%
12+
target: 85%

poetry.lock

Lines changed: 984 additions & 1086 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
[tool.poetry]
22
name = "tracker"
33
version = "2.1.15"
4-
description = ""
5-
authors = ["Masum Billal <proafxin@users.noreply.github.com>"]
4+
description = "A simple bug tracking API"
5+
authors = ["Masum Billal <billalmasum93@gmail.com>"]
66
license = "LICENSE"
77
readme = "README.md"
88

99
[tool.poetry.dependencies]
10-
python = "^3.10"
11-
fastapi-myhelper = "^0.1.7"
12-
fastapi = { extras = ["all"], version = "^0.103.0" }
13-
uvicorn = { extras = ["standard"], version = "^0.23.2" }
10+
python = "^3.11"
1411
sqlalchemy = "^2.0.20"
1512
mysqlclient = "^2.2.0"
1613
pymysql = "^1.1.0"
1714
alembic = "^1.11.3"
1815
aiomysql = "^0.2.0"
1916
aiosqlite = "^0.19.0"
17+
fastapi-cli = "^0.0.4"
18+
fastapi = "^0.111.0"
19+
cryptography = "^42.0.8"
2020

2121
[tool.poetry.group.dev.dependencies]
2222
pytest = "^7.4.0"
2323
coverage = "^7.3.0"
2424
pytest-asyncio = "^0.21.1"
25-
gevent = "^23.9.0.post1"
25+
26+
[tool.pytest]
27+
asyncio_mode = "auto"
28+
29+
[tool.ruff]
30+
line-length = 100
2631

2732
[build-system]
2833
requires = ["poetry-core"]

tests/conftest.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
from typing import AsyncGenerator
23

34
import pytest
45
import pytest_asyncio
@@ -18,12 +19,10 @@
1819
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
1920
)
2021

21-
SessionTesting = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
22-
2322

2423
@pytest_asyncio.fixture(scope="class")
2524
async def app():
26-
session = SessionTesting()
25+
session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)()
2726
app_test = FastAPI()
2827
app_test.dependency_overrides[get_db] = lambda: session
2928
app_test.include_router(bug_router)
@@ -35,7 +34,7 @@ async def app():
3534

3635

3736
@pytest_asyncio.fixture(scope="class")
38-
async def client(app: FastAPI) -> AsyncClient:
37+
async def client(app: FastAPI) -> AsyncGenerator[AsyncClient, None]:
3938
async with engine.begin() as conn:
4039
await conn.run_sync(Base.metadata.create_all)
4140

tests/views/test_bug.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ async def __test_bug(self, bug: dict):
1414

1515
@pytest.mark.asyncio
1616
async def test_create(self, client: AsyncClient) -> None:
17-
json = {"name": "Test Story"}
17+
json: dict[str, str | int] = {"name": "Test Story"}
1818
await client.post("/stories/", json=json)
1919
json = {
2020
"title": "Test Bug",

tox.ini

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22

3-
envlist =
3+
envlist =
44
py3, tests
55
; docs-{linux, win32}
66
skipsdist = true
@@ -16,20 +16,18 @@ platform =
1616
passenv = *
1717
basepython = python3
1818
recreate = false
19-
20-
deps =
21-
poetry >= 1.3.2
19+
deps = poetry
2220

2321
commands =
2422
poetry install
2523

2624

2725
[testenv:tests]
2826

29-
commands =
27+
commands =
3028
poetry install --with dev
31-
poetry run coverage run -m pytest -v
32-
poetry run coverage report -m
29+
poetry run coverage run --source=. -m pytest
30+
poetry run coverage report -m --fail-under=85
3331
poetry run coverage xml -o coverage.xml
3432

3533
; [testenv:docs-win32]
@@ -49,8 +47,8 @@ commands =
4947
; allowlist_externals = *
5048

5149
; changedir = docs
52-
; commands =
50+
; commands =
5351
; poetry install --with docs
5452
; poetry run sphinx-apidoc -f -o source/ ../ ../tests/
5553
; make clean
56-
; make html
54+
; make html

tracker/config/settings.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
DBUSER = environ["MYSQL_USER"]
55
DBPASSWORD = environ["MYSQL_PASSWORD"]
66
DBHOST = environ["MYSQL_HOST"]
7-
DBPORT = environ["MYSQL_PORT"]
8-
DBPORT = int(DBPORT)
7+
DBPORT = int(environ["MYSQL_PORT"])

tracker/main.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
1+
from contextlib import asynccontextmanager
2+
from typing import AsyncGenerator
3+
14
from fastapi import FastAPI
25

36
from tracker.db.session import engine
47
from tracker.views.bug import router as bug_router
58
from tracker.views.story import router as story_router
69

7-
app = FastAPI(title="Bug Tracker", description="Simple bug tracking API.")
8-
910

10-
@app.on_event(event_type="startup")
11-
async def start():
12-
await configure()
11+
async def configure_router():
12+
app.include_router(story_router)
13+
app.include_router(bug_router)
1314

1415

15-
@app.on_event(event_type="shutdown")
16-
async def shutdown():
17-
await engine.dispose()
16+
async def configure():
17+
await configure_router()
1818

1919

20-
def configure_router():
21-
app.include_router(story_router)
22-
app.include_router(bug_router)
20+
@asynccontextmanager
21+
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
22+
await configure()
23+
yield
24+
await engine.dispose()
2325

2426

25-
async def configure():
26-
configure_router()
27+
app = FastAPI(
28+
title="Bug Tracker", description="Simple bug tracking API.", lifespan=lifespan
29+
)

tracker/views/bug.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from typing import Annotated
2+
13
from fastapi import APIRouter, Depends
2-
from sqlalchemy.orm import Session
4+
from sqlalchemy.ext.asyncio import AsyncSession
35

46
from tracker.db.session import get_db
57
from tracker.serializers.bug import BugInput, BugOutput
@@ -10,23 +12,21 @@
1012

1113

1214
@router.post("/bugs/", response_model=BugOutput)
13-
# trunk-ignore(ruff/B008)
14-
async def create(bug: BugInput, db: Session = Depends(get_db)):
15+
async def create(bug: BugInput, db: Annotated[AsyncSession, Depends(get_db)]):
1516
obj = await create_bug(db=db, bug=bug)
1617

1718
return obj
1819

1920

2021
@router.get("/bugs/", response_model=list[BugOutput])
21-
# trunk-ignore(ruff/B008)
22-
async def get(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
22+
async def get(
23+
db: Annotated[AsyncSession, Depends(get_db)], skip: int = 0, limit: int = 10
24+
):
2325
return await bugs(db=db, skip=skip, limit=limit)
2426

2527

2628
@router.get("/bugs/{id}", response_model=BugOutput)
27-
# trunk-ignore(ruff/B008)
28-
async def get_bug(id: int, db: Session = Depends(get_db)):
29+
async def get_bug(id: int, db: Annotated[AsyncSession, Depends(get_db)]):
2930
obj = await bug_by_id(db=db, id=id)
30-
print(obj)
3131

3232
return obj

tracker/views/story.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from typing import Annotated
2+
13
from fastapi import APIRouter, Depends
2-
from sqlalchemy.orm import Session
4+
from sqlalchemy.ext.asyncio import AsyncSession
35

46
from tracker.db.session import get_db
57
from tracker.serializers.story import StoryInput, StoryOutput
@@ -10,22 +12,21 @@
1012

1113

1214
@router.post("/stories/", response_model=StoryOutput)
13-
# trunk-ignore(ruff/B008)
14-
async def create(story: StoryInput, db: Session = Depends(get_db)):
15+
async def create(story: StoryInput, db: Annotated[AsyncSession, Depends(get_db)]):
1516
obj = await create_story(db=db, story=story)
1617

1718
return obj
1819

1920

2021
@router.get("/stories/", response_model=list[StoryOutput])
21-
# trunk-ignore(ruff/B008)
22-
async def get_stories(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
22+
async def get_stories(
23+
db: Annotated[AsyncSession, Depends(get_db)], skip: int = 0, limit: int = 10
24+
):
2325
return await stories(db=db, skip=skip, limit=limit)
2426

2527

2628
@router.get("/stories/{id}", response_model=StoryOutput)
27-
# trunk-ignore(ruff/B008)
28-
async def get_story(id: int, db: Session = Depends(get_db)):
29+
async def get_story(id: int, db: Annotated[AsyncSession, Depends(get_db)]):
2930
obj = await story_by_id(db=db, id=id)
3031

3132
return obj

0 commit comments

Comments
 (0)