Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ef3a203
refactor: prepare for full rewrite
bsoyka Aug 8, 2025
26d3c22
feat(adapter): set up basic REST adapter
bsoyka Aug 8, 2025
644d489
chore: set up project area labels
bsoyka Aug 8, 2025
4d1e603
feat(models): start basic profile model
bsoyka Aug 8, 2025
71bdc7e
feat(utils): add hash_email function
bsoyka Aug 8, 2025
3c5676f
feat(api): add GravatarAPI client for profile fetching
bsoyka Aug 8, 2025
e1b8d86
fix(adapter): correct type hinting for parameters
bsoyka Aug 8, 2025
5ad4857
fix(utils): trim whitespace before hashing emails
bsoyka Aug 8, 2025
dd7d6ef
test(utils): cover hash_email function
bsoyka Aug 8, 2025
b48c702
fix(api): use correct response schema
bsoyka Aug 8, 2025
f2f21c5
fix(api): use correct response schema
bsoyka Aug 8, 2025
0455dee
test(api): add basic integration test
bsoyka Aug 8, 2025
dffeca5
feat(api,models): support remaining fields
bsoyka Aug 8, 2025
43430de
feat(models): fully type-hint profile model with Pydantic
bsoyka Aug 8, 2025
b594a18
refactor: make API adapter profile-specific
bsoyka Aug 8, 2025
a58837a
refactor: move profile functionality to submodule
bsoyka Aug 8, 2025
c0b4e17
feat: initialize avatar generator class
bsoyka Aug 8, 2025
6ae3e8f
chore: update GitHub labels
bsoyka Aug 8, 2025
a2c0fc3
feat(avatars): enforce requirements for "initials" and "name" parameters
bsoyka Aug 8, 2025
11ff6e5
feat(avatars): add parameter and URL generation
bsoyka Aug 8, 2025
710de84
feat(avatars): don't pass default argument values
bsoyka Aug 8, 2025
e332146
fix(avatars): remove trailing ? with no parameters
bsoyka Aug 8, 2025
4b688a2
docs: add avatar generation example
bsoyka Aug 8, 2025
068eb7d
chore: enable rST doctesting by default
bsoyka Aug 8, 2025
5bba558
fix(avatars): use standard Enum for 3.10 compatibility
bsoyka Aug 8, 2025
cfa947a
fix(avatars): add type hints to resolve mypy errors
bsoyka Aug 8, 2025
4fc8432
fix(avatars): handle custom default images
bsoyka Aug 8, 2025
6cbeb35
chore: better expose needed models
bsoyka Aug 8, 2025
ea522d1
docs: start with tutorial/reference sections
bsoyka Aug 8, 2025
be9bd9e
refactor(avatars): move option enums to separate module
bsoyka Aug 8, 2025
17bb9e2
docs(avatars): build out API reference
bsoyka Aug 8, 2025
edf06b8
docs(profiles): build out API reference
bsoyka Aug 8, 2025
adc3fdb
fix(api): make key optional for profiles
bsoyka Aug 8, 2025
6206023
docs(profiles): document ProfileAPI.__init__()
bsoyka Aug 8, 2025
e99c1dd
fix(avatars): correct use of rating enum
bsoyka Aug 8, 2025
dc7b11c
docs(avatars): add tutorial
bsoyka Aug 8, 2025
ad214ce
docs(avatars): fix parameter style
bsoyka Aug 8, 2025
9500de8
docs(profiles): add tutorial
bsoyka Aug 8, 2025
2d56e69
ci: disable 3.9 type checking
bsoyka Aug 8, 2025
8f646d6
refactor(avatars): move default size/rating to constants
bsoyka Aug 8, 2025
da9bb3d
fix(avatars): ignore redundant cast error
bsoyka Aug 8, 2025
447a599
ci: pass Gravatar API key to tests
bsoyka Aug 8, 2025
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
8 changes: 7 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
root = true

[*]
end_of_line = crlf
end_of_line = lf
insert_final_newline = true
charset = utf-8

indent_size = 4
indent_style = space

trim_trailing_whitespace = true

[{*.json,*.json5,*.yaml,*.yml}]
indent_size = 2

[{*.md,*.markdown}]
trim_trailing_whitespace = false
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Report a bug
description: Share when something isn't working as expected
labels: ["type:bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to share a bug report!
- type: textarea
attributes:
label: Bug description
description: Share a clear and concise description of the bug.
validations:
required: true
- type: textarea
attributes:
label: Reproducing the issue
description: Provide a minimal, reproducible example.
validations:
required: true
- type: textarea
attributes:
label: Expectations vs. reality
description: Give a clear description of what you expected to happen.
- type: input
attributes:
label: Affected version(s)
description: Share the version(s) where you observed this bug.
validations:
required: true
- type: textarea
attributes:
label: Additional context
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Request a feature
description: Suggest an improvement or addition to the project
labels: ['type:feature']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to request a feature!
- type: textarea
attributes:
label: Related to a problem?
description: Is your feature request related to a problem? If so, please describe.
- type: textarea
attributes:
label: Preferred solution
description: Give a clear and concise description of what you'd like to see.
validations:
required: true
- type: textarea
attributes:
label: Alternatives
description: Describe any alternatives you've considered.
- type: textarea
attributes:
label: Additional context
17 changes: 17 additions & 0 deletions .github/labels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Extends configuration at: https://raw.githubusercontent.com/bsoyka/cookiecutters/main/python-library/default-labels.yaml

- name: 'area:adapter'
color: 80cbc4
description: 'Related to the REST API adapter layer'

- name: 'area:avatars'
color: 80cbc4
description: 'Related to avatar URL generation and retrieval'

- name: 'area:models'
color: 80cbc4
description: 'Related to data models and schemas'

- name: 'area:profiles'
color: 80cbc4
description: 'Related to profile retrieval'
56 changes: 34 additions & 22 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
name: Upload to PyPI
name: Publishing

on:
release:
types: [created]
release:
types: [ published ]

permissions: {}

jobs:
publish:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flit
- name: Build and publish
env:
FLIT_USERNAME: __token__
FLIT_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
flit publish --setup-py
publish:
name: Upload to PyPI

runs-on: ubuntu-latest

environment:
name: pypi
url: https://pypi.org/project/gravify/

permissions:
contents: read
id-token: write

steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
with:
enable-cache: true

- name: Build package
run: uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
28 changes: 28 additions & 0 deletions .github/workflows/repo-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Repo configuration

on:
workflow_dispatch:

permissions: {}

jobs:
labels:
name: Sync labels

runs-on: ubuntu-latest

permissions:
issues: write

steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
sparse-checkout: .github/labels.yml

- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
with:
config-file: |
https://raw.githubusercontent.com/bsoyka/cookiecutters/main/python-library/default-labels.yaml
.github/labels.yaml
177 changes: 125 additions & 52 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,55 +1,128 @@
name: Test with pytest
name: Tests

on: [push, pull_request]
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions: {}

jobs:
test:
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
os: [ubuntu-latest, macOS-latest, windows-latest]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flit pytest
- name: Install module
run: |
flit install
- name: Run tests
run: |
pytest

coverage:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flit pytest coverage
- name: Install module
run: |
flit install
- name: Run tests
run: |
coverage run -m pytest
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
verbose: true
test:
name: Run pytest

runs-on: ubuntu-latest

permissions:
contents: read

strategy:
fail-fast: false
matrix:
python-version: [ "3.10", "3.11", "3.12", "3.13" ]

steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
with:
python-version: "${{ matrix.python-version }}"
enable-cache: true

- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3.0.0

- name: Run tests
run: just test ${TEST_ENV}
env:
TEST_ENV: "${{ matrix.python-version }}"

coverage:
name: Generate coverage report

runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
with:
enable-cache: true

- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3.0.0

- name: Run tests and generate coverage report
run: |
just coverage
env:
GRAVATAR_KEY: "${{ secrets.GRAVATAR_KEY }}"

- name: Upload results to Codecov
uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with:
token: "${{ secrets.CODECOV_TOKEN }}"

type:
name: Run type checks

runs-on: ubuntu-latest

permissions:
contents: read

strategy:
fail-fast: false
matrix:
python-version: [ "3.10", "3.11", "3.12", "3.13" ]

steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
with:
python-version: "${{ matrix.python-version }}"
enable-cache: true

- name: Install just
uses: extractions/setup-just@e33e0265a09d6d736e2ee1e0eb685ef1de4669ff # v3.0.0

- name: Run mypy
run: just typing

zizmor:
name: Analyze GitHub Actions

runs-on: ubuntu-latest

permissions:
actions: read
contents: read
security-events: write

steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false

- name: Run zizmor
uses: zizmorcore/zizmor-action@f52a838cfabf134edcbaa7c8b3677dde20045018 # v0.1.1
with:
persona: 'auditor'
Loading