Skip to content

Commit 304ad1f

Browse files
feat(ci): add lint, test and deploy (#10)
1 parent 6385ec7 commit 304ad1f

File tree

7 files changed

+150
-17
lines changed

7 files changed

+150
-17
lines changed

.github/workflows/ci.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
ci:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-python@v5
17+
id: setup-python
18+
with:
19+
python-version: '3.12'
20+
21+
- name: Install Poetry
22+
uses: snok/install-poetry@v1
23+
with:
24+
virtualenvs-create: true
25+
virtualenvs-in-project: true
26+
27+
- name: Load cached venv
28+
id: cached-poetry-dependencies
29+
uses: actions/cache@v4
30+
with:
31+
path: .venv
32+
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
33+
34+
- name: Install dependencies
35+
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
36+
run: poetry install --no-interaction --no-root
37+
38+
- name: Install library
39+
run: poetry install --no-interaction
40+
41+
- name: Lint
42+
run: |
43+
source .venv/bin/activate
44+
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
45+
poetry run flake8 . --count --exit-zero --max-complexity=10 --statistics
46+
poetry run black . --check
47+
poetry run isort .
48+
49+
- name: Create .env file
50+
run: |
51+
echo "TOKEN=${{ secrets.BLAGUES_API_TOKEN }}" > .env
52+
53+
- name: Run tests
54+
run: poetry run pytest --cov --cov-report=xml
55+
56+
- name: Upload coverage
57+
uses: codecov/[email protected]
58+
with:
59+
token: ${{ secrets.CODECOV_TOKEN }}
60+
file: ./coverage.xml
61+
fail_ci_if_error: true

.github/workflows/publish.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
12+
if: github.repository_owner == 'Blagues-API'
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 2
17+
18+
- name: Check if version changed
19+
id: check_version
20+
run: |
21+
git diff HEAD^ HEAD -- pyproject.toml | grep '+version' && echo "version_changed=true" >> $GITHUB_OUTPUT || echo "version_changed=false" >> $GITHUB_OUTPUT
22+
23+
- uses: actions/setup-python@v5
24+
if: steps.check_version.outputs.version_changed == 'true'
25+
id: setup-python
26+
with:
27+
python-version: '3.12'
28+
29+
- name: Install Poetry
30+
if: steps.check_version.outputs.version_changed == 'true'
31+
uses: snok/install-poetry@v1
32+
with:
33+
virtualenvs-create: true
34+
virtualenvs-in-project: true
35+
36+
- name: Load cached venv
37+
if: steps.check_version.outputs.version_changed == 'true'
38+
id: cached-poetry-dependencies
39+
uses: actions/cache@v4
40+
with:
41+
path: .venv
42+
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
43+
44+
- name: Build
45+
if: steps.check_version.outputs.version_changed == 'true'
46+
run: poetry build
47+
48+
- name: Publish package distributions to PyPI
49+
if: steps.check_version.outputs.version_changed == 'true'
50+
uses: pypa/gh-action-pypi-publish@release/v1
51+
with:
52+
packages-dir: dist/

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ __pycache__/
22
dist/
33
poetry.lock
44
.env
5-
.pytest_cache/
5+
.pytest_cache/
6+
.venv/
7+
coverage.xml

blagues_api/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
from .main import BlaguesAPI, BlagueType, CountJoke, Blague
1+
from .main import Blague, BlaguesAPI, BlagueType, CountJoke
2+
3+
__all__ = ["BlaguesAPI", "BlagueType", "CountJoke", "Blague"]

blagues_api/main.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
from enum import Enum
2+
from typing import List
3+
14
import aiohttp
25
import pydantic
3-
from typing import List
4-
from enum import Enum
6+
57

68
class BlagueType(str, Enum):
79
GLOBAL = "global"
@@ -14,51 +16,52 @@ class BlagueType(str, Enum):
1416
def __str__(self):
1517
return str(self.value)
1618

19+
1720
class Blague(pydantic.BaseModel):
1821
id: int
1922
type: BlagueType
2023
joke: str
2124
answer: str
2225

26+
2327
class CountJoke(pydantic.BaseModel):
2428
count: int
2529

30+
2631
class BlaguesAPI:
2732
def __init__(self, token: str):
2833
self.token = token
2934
self.base_url = "https://www.blagues-api.fr/api"
30-
self.headers = {'Authorization': 'Bearer ' + self.token}
31-
35+
self.headers = {"Authorization": f"Bearer {self.token}"}
3236

3337
async def _get(self, url: str, params: dict = None) -> dict:
3438
async with aiohttp.ClientSession(raise_for_status=True) as session:
35-
async with session.get(self.base_url+url, headers=self.headers, params=params) as resp:
39+
async with session.get(
40+
self.base_url + url, headers=self.headers, params=params
41+
) as resp:
3642
return await resp.json()
3743

3844
async def random(self, *, disallow: List[str] = None) -> Blague:
3945
endpoint = "/random"
4046
params = {"disallow": disallow} if disallow else {}
4147
data = await self._get(endpoint, params)
42-
43-
return Blague.model_validate(data)
4448

49+
return Blague.model_validate(data)
4550

4651
async def random_categorized(self, category: str) -> Blague:
4752
endpoint = f"/type/{category}/random"
4853
data = await self._get(endpoint)
49-
50-
return Blague.model_validate(data)
5154

55+
return Blague.model_validate(data)
5256

5357
async def from_id(self, id: int) -> Blague:
5458
endpoint = f"/id/{id}"
5559
data = await self._get(endpoint)
56-
60+
5761
return Blague.model_validate(data)
5862

5963
async def count(self) -> CountJoke:
6064
endpoint = "/count"
6165
data = await self._get(endpoint)
62-
63-
return CountJoke.model_validate(data)
6466

67+
return CountJoke.model_validate(data)

pyproject.toml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ readme = "README.md"
1313
repository = "https://github.com/Blagues-API/package-py"
1414

1515
[tool.poetry.dependencies]
16-
python = "^3.8"
16+
python = "^3.8.1"
1717
aiohttp = "^3.9.5"
1818
pydantic = "^2.8.2"
1919

2020
[tool.poetry.dev-dependencies]
2121
pytest = "^7.1.2"
2222
pytest-asyncio = "^0.18.3"
2323
python-dotenv = "^0.20.0"
24+
flake8 = "^7.1.0"
25+
flake8-pyproject = "^1.2.3"
26+
black = "^24.4.2"
27+
isort = "^5.13.2"
28+
pytest-cov = "^5.0.0"
2429

2530
[build-system]
2631
requires = ["poetry-core>=1.0.0"]
@@ -29,3 +34,9 @@ build-backend = "poetry.core.masonry.api"
2934
[tool.pytest.ini_options]
3035
asyncio_mode="auto"
3136

37+
[tool.flake8]
38+
max-line-length = 120
39+
exclude = [".venv"]
40+
41+
[tool.isort]
42+
profile = "black"

tests/test_blagues_api.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
2-
32
from dotenv import dotenv_values
4-
from blagues_api import BlaguesAPI, BlagueType, CountJoke, Blague
3+
4+
from blagues_api import Blague, BlaguesAPI, BlagueType, CountJoke
55

66
pytestmark = pytest.mark.asyncio
77

@@ -11,10 +11,12 @@ def token():
1111
env = dotenv_values(".env")
1212
return env["TOKEN"]
1313

14+
1415
@pytest.fixture
1516
def client(token):
1617
return BlaguesAPI(token)
1718

19+
1820
async def test_random_joke(client):
1921
response = await client.random()
2022
assert isinstance(response, Blague)

0 commit comments

Comments
 (0)