Skip to content

Commit

Permalink
feat(code cleanup + deprecations):
Browse files Browse the repository at this point in the history
  • Loading branch information
stvnksslr committed Jul 2, 2024
1 parent 26d94d6 commit 5731fd8
Show file tree
Hide file tree
Showing 12 changed files with 966 additions and 705 deletions.
22 changes: 8 additions & 14 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:

env:
PYTHON_VERSION: "3.12"
POETRY_VERSION: "1.6.1"
POETRY_VERSION: "1.8.3"

jobs:
test:
Expand Down Expand Up @@ -53,23 +53,17 @@ jobs:
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install
#----------------------------------------------
# run linter suite
# run formatter
#----------------------------------------------
- name: Run formatter
run: poetry run ruff format . --check
#----------------------------------------------
# run linter
#----------------------------------------------
- name: Run linters
run: poetry run ruff check .
#----------------------------------------------
# run test suite
#----------------------------------------------
- name: Run tests
run: poetry run pytest
#----------------------------------------------
# Send code coverage to code climate
#----------------------------------------------
- name: Submit coverage to code climate
uses: paambaati/codeclimate-action@v5.0.0
continue-on-error: true
env:
CI: "true"
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: poetry run pytest --cov-branch --cov-report xml --cov=src src
run: poetry run pytest --cov
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python 3.12.0
python 3.12.4
4 changes: 2 additions & 2 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ FROM python:3.12-slim
ENV PIP_DISABLE_PIP_VERSION_CHECK=on \
POETRY_VIRTUALENVS_CREATE=false \
PIP_NO_CACHE_DIR=off \
POETRY_VERSION=1.6.1
POETRY_VERSION=1.8.3

WORKDIR /src

COPY ./src /src/src
COPY pyproject.toml poetry.lock /src/

RUN pip install "poetry==$POETRY_VERSION"
RUN poetry install --no-dev
RUN poetry install --only main

EXPOSE 8080

Expand Down
1,353 changes: 836 additions & 517 deletions poetry.lock

Large diffs are not rendered by default.

169 changes: 82 additions & 87 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,33 @@ version = "1.3.0"
description = "a module for parsing battlescribe rosters and allowing them to be printed or displayed cleanly"
authors = ["Steven Kessler <stvnksslr@gmail.com>"]
license = "MIT"

package-mode = false

[tool.poetry.dependencies]
python = "^3.11"
beautifulsoup4 = "^4.12.2"
lxml = "^4.9.3"
fastapi = "^0.104.0"
aiofiles = "^23.2.1"
jinja2 = "^3.1.2"
jinja2-fragments = "^1.2.1"
python-multipart = "^0.0.6"
beautifulsoup4 = "^4.12.3"
lxml = "^5.2.2"
fastapi = "^0.111.0"
aiofiles = "^24.1.0"
jinja2 = "^3.1.4"
jinja2-fragments = "^1.4.0"
python-multipart = "^0.0.9"
loguru = "^0.7.2"
uvicorn = { extras = ["standard"], version = "^0.23.2" }
httpx = "^0.25.0"
pydantic = "^2.4.2"
uvicorn = { extras = ["standard"], version = "^0.30.1" }
httpx = "^0.27.0"
pydantic = "^2.8.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.3"
pytest-cov = "^4.1.0"
pytest-sugar = "^0.9.7"
pytest-asyncio = "^0.21.1"
pytest = "^8.2.2"
pytest-cov = "^5.0.0"
pytest-sugar = "^1.0.0"
pytest-asyncio = "^0.23.7"
pytest-clarity = "^1.0.1"
pytest-random-order = "^1.1.0"
pytest-random-order = "^1.1.1"

[tool.poetry.group.code-quality.dependencies]
ruff = "^0.1.3"
ruff = "^0.5.0"
pyright = "^1.1.369"

[build-system]
requires = ["poetry>=0.12"]
Expand All @@ -39,77 +40,71 @@ build-backend = "poetry.masonry.api"
asyncio_mode = "auto"
addopts = "-vv --random-order"

[tool.pyright]
ignore = ["src/tests"]

[tool.coverage.run]
omit = [
'*/.local/*',
'__init__.py',
'tests/*',
'*/tests/*',
'.venv/*',
'*/migrations/*',
'*_test.py',
"src/utils/logger_manager.py"
]

[tool.ruff]
line-length = 120
ignore = [
"B008", # function-call-in-default-argument (B008)
"S101", # Use of `assert` detected
"RET504", # Unnecessary variable assignment before `return` statement
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
"ARG001", # Unused function argument: `{name}`
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
]
select = [
"A", # flake8-builtins
"B", # flake8-bugbear
"E", # pycodestyle
"F", # Pyflakes
"N", # pep8-naming
"RET", # flake8-return
"S", # flake8-bandit
"W", # pycodestyle
"Q", # flake8-quotes
"C90", # mccabe
"I", # isort
"UP", # pyupgrade
"BLE", # flake8-blind-except
"C4", # flake8-comprehensions
"ISC", # flake8-implicit-str-concat
"ICN", # flake8-import-conventions
"PT", # flake8-pytest-style
"PIE", # flake8-pie
"T20", # flake8-print
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib
"ERA", # eradicate
"PL", # Pylint
"NPY", # NumPy-specific rules
"PLE", # Pylint
"PLR", # Pylint
"PLW", # Pylint
"RUF", # Ruff-specific rules
"PD", # pandas-vet
]
exclude = [
".eggs",
".git",
".pytype",
".ruff_cache",
".venv",
"__pypackages__",
".venv",
".eggs",
".git",
".pytype",
".ruff_cache",
".venv",
"__pypackages__",
".venv",
]


[tool.black]
line-length = 120
target-version = ['py38']
include = '\.pyi?$'
exclude = '''
(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)
)
'''
lint.ignore = [
"B008", # function-call-in-default-argument (B008)
"S101", # Use of `assert` detected
"RET504", # Unnecessary variable assignment before `return` statement
"PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
"ARG001", # Unused function argument: `{name}`
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
"ISC001" # Checks for implicitly concatenated strings on a single line
]
lint.select = [
"A", # flake8-builtins
"B", # flake8-bugbear
"E", # pycodestyle
"F", # Pyflakes
"N", # pep8-naming
"RET", # flake8-return
"S", # flake8-bandit
"W", # pycodestyle
"Q", # flake8-quotes
"C90", # mccabe
"I", # isort
"UP", # pyupgrade
"BLE", # flake8-blind-except
"C4", # flake8-comprehensions
"ISC", # flake8-implicit-str-concat
"ICN", # flake8-import-conventions
"PT", # flake8-pytest-style
"PIE", # flake8-pie
"T20", # flake8-print
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib
"ERA", # eradicate
"PL", # Pylint
"NPY", # NumPy-specific rules
"PLE", # Pylint
"PLR", # Pylint
"PLW", # Pylint
"RUF", # Ruff-specific rules
"PD", # pandas-vet
]
29 changes: 13 additions & 16 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from fastapi import FastAPI, File, Form, UploadFile
from starlette.requests import Request
from starlette.staticfiles import StaticFiles
from starlette.templating import Jinja2Templates
from fastapi.requests import Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from uvicorn import run

from src.utils.battlescribe_meta import check_battlescribe_version
Expand All @@ -25,7 +25,7 @@

@app.get("/")
async def root(request: Request):
return templates.TemplateResponse("home.html", {"request": request})
return templates.TemplateResponse(request, "home.html")


@app.post("/files/")
Expand All @@ -37,23 +37,20 @@ async def upload_roster(
file: UploadFile = File(...),
):
upload_contents = await check_if_zipped(file)
supported_battlescribe_version = check_battlescribe_version(roster=upload_contents)

if not supported_battlescribe_version:
if not check_battlescribe_version(roster=upload_contents):
return BATTLESCRIBE_VERSION_ERROR

data = get_parser_type_and_parse(roster=upload_contents, summary_page=summary_page)

parsed_roster = data.get("roster")
template = data.get("template")
rules_summary = data.get("rules_summary")

if use_icons:
template = "icons_" + template
template = "icons_" + data.get("template") if use_icons else data.get("template")

return templates.TemplateResponse(
template,
{"request": request, "multiple_pages": multiple_pages, "rules_summary": rules_summary, "roster": parsed_roster},
request=request,
name=template,
context={
"multiple_pages": multiple_pages,
"rules_summary": data.get("rules_summary"),
"roster": data.get("roster"),
},
)


Expand Down
60 changes: 13 additions & 47 deletions src/main_test.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,38 @@
from pathlib import Path

from starlette.testclient import TestClient
from fastapi.testclient import TestClient

from src.main import app

client = TestClient(app)

base_path = Path.cwd() / "test_rosters"
zipped_roster = str(base_path / "zipped_rosters" / "elite_roster.rosz")
test_roster = str(base_path / "horus_heresy" / "hhv2.nightlords_zm.ros")

SUCCESS: int = 200


def test__read_main():
response = client.get("/")
assert response.status_code == SUCCESS


def test__upload_roster():
multiple_pages = False
summary_page = False
use_icons = False
def post_files(multiple_pages, summary_page, use_icons):
with Path.open(test_roster) as roster_file:
roster_file_text = roster_file.read()

response = client.post(
return client.post(
"/files/",
files={"file": roster_file_text},
data={"multiple_pages": multiple_pages, "summary_page": summary_page, "use_icons": use_icons},
)

assert response.status_code == SUCCESS


def test__upload_roster_multipart_false():
multiple_pages = False
summary_page = False
use_icons = False
with Path.open(test_roster) as roster_file:
roster_file_text = roster_file.read()

response = client.post(
"/files/",
files={"file": roster_file_text},
data={"multiple_pages": multiple_pages, "summary_page": summary_page, "use_icons": use_icons},
)
multiple_pages_response = "single_page.css" in response.text

assert response.status_code == SUCCESS
assert multiple_pages_response
def test__read_main():
assert client.get("/").status_code == 200


def test__upload_roster_multipart_true():
multiple_pages = True
summary_page = False
use_icons = False
def test__upload_roster():
assert post_files(False, False, False).status_code == 200

with Path.open(test_roster) as roster_file:
roster_file_text = roster_file.read()

response = client.post(
"/files/",
files={"file": roster_file_text},
data={"multiple_pages": multiple_pages, "summary_page": summary_page, "use_icons": use_icons},
)
def test__upload_roster_multipart_false():
response = post_files(False, False, False)
assert response.status_code == 200
assert "single_page.css" in response.text

multiple_pages_response = "multiple_pages.css" in response.text

assert response.status_code == SUCCESS
assert multiple_pages_response
def test__upload_roster_multipart_true():
assert post_files(True, False, False).status_code == 200
Loading

0 comments on commit 5731fd8

Please sign in to comment.