Skip to content

Commit cd10410

Browse files
committed
feat: initial Python SDK implementation
- Add sync and async Forminit clients - Add comprehensive type definitions - Add 21 tests with 85% coverage - Add Flask, FastAPI, and Django examples - Add GitHub Actions for CI/CD - Add dual authentication support for PyPI publishing
1 parent e9ddba0 commit cd10410

34 files changed

+4029
-0
lines changed

.github/workflows/ci.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
name: Lint
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v5
18+
with:
19+
python-version: "3.12"
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v4
23+
with:
24+
enable-cache: true
25+
26+
- name: Install dependencies
27+
run: uv sync
28+
29+
- name: Run ruff check
30+
run: uv run ruff check .
31+
32+
- name: Run ruff format check
33+
run: uv run ruff format --check .
34+
35+
test:
36+
name: Test Python ${{ matrix.python-version }}
37+
runs-on: ubuntu-latest
38+
strategy:
39+
fail-fast: false
40+
matrix:
41+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
42+
43+
steps:
44+
- uses: actions/checkout@v4
45+
46+
- name: Set up Python ${{ matrix.python-version }}
47+
uses: actions/setup-python@v5
48+
with:
49+
python-version: ${{ matrix.python-version }}
50+
51+
- name: Install uv
52+
uses: astral-sh/setup-uv@v4
53+
with:
54+
enable-cache: true
55+
56+
- name: Install dependencies
57+
run: uv sync
58+
59+
- name: Run tests
60+
run: uv run pytest -v --tb=short
61+
62+
coverage:
63+
name: Coverage
64+
runs-on: ubuntu-latest
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Set up Python
69+
uses: actions/setup-python@v5
70+
with:
71+
python-version: "3.12"
72+
73+
- name: Install uv
74+
uses: astral-sh/setup-uv@v4
75+
with:
76+
enable-cache: true
77+
78+
- name: Install dependencies
79+
run: uv sync
80+
81+
- name: Run tests with coverage
82+
run: uv run pytest --cov=forminit --cov-report=xml --cov-report=term
83+
84+
- name: Upload coverage to Codecov
85+
uses: codecov/codecov-action@v4
86+
with:
87+
file: ./coverage.xml
88+
fail_ci_if_error: false

.github/workflows/publish.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Publish Package
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
build:
9+
name: Build distribution
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Set up Python
15+
uses: actions/setup-python@v5
16+
with:
17+
python-version: "3.12"
18+
19+
- name: Install uv
20+
uses: astral-sh/setup-uv@v4
21+
22+
- name: Build package
23+
run: uv build
24+
25+
- name: Store the distribution packages
26+
uses: actions/upload-artifact@v4
27+
with:
28+
name: python-package-distributions
29+
path: dist/
30+
31+
publish-to-pypi:
32+
name: Publish to PyPI
33+
needs:
34+
- build
35+
runs-on: ubuntu-latest
36+
environment:
37+
name: pypi
38+
url: https://pypi.org/p/forminit
39+
steps:
40+
- name: Download all the dists
41+
uses: actions/download-artifact@v4
42+
with:
43+
name: python-package-distributions
44+
path: dist/
45+
46+
- name: Publish to PyPI
47+
uses: pypa/gh-action-pypi-publish@release/v1
48+
with:
49+
password: ${{ secrets.PYPI_API_TOKEN }}
50+
skip-existing: true
51+
52+
publish-to-github:
53+
name: Publish to GitHub Packages
54+
needs:
55+
- build
56+
runs-on: ubuntu-latest
57+
permissions:
58+
contents: read
59+
packages: write
60+
steps:
61+
- name: Download all the dists
62+
uses: actions/download-artifact@v4
63+
with:
64+
name: python-package-distributions
65+
path: dist/
66+
67+
- name: Publish to GitHub Packages
68+
uses: pypa/gh-action-pypi-publish@release/v1
69+
with:
70+
repository-url: https://maven.pkg.github.com/${{ github.repository }}
71+
password: ${{ secrets.GITHUB_TOKEN }}
72+
skip-existing: true

.github/workflows/release.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
create-release:
13+
name: Create GitHub Release
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Extract version from tag
21+
id: version
22+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
23+
24+
- name: Generate changelog
25+
id: changelog
26+
run: |
27+
# Get the previous tag
28+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
29+
30+
if [ -z "$PREV_TAG" ]; then
31+
# First release, get all commits
32+
CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges)
33+
else
34+
# Get commits since previous tag
35+
CHANGELOG=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges)
36+
fi
37+
38+
# Save to file for multiline support
39+
echo "$CHANGELOG" > changelog.txt
40+
41+
- name: Create Release
42+
uses: softprops/action-gh-release@v2
43+
with:
44+
name: Release ${{ steps.version.outputs.VERSION }}
45+
body_path: changelog.txt
46+
draft: false
47+
prerelease: false
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*.pyd
5+
*.so
6+
7+
# Virtual environments
8+
.venv/
9+
venv/
10+
ENV/
11+
12+
# Packaging
13+
build/
14+
dist/
15+
*.egg-info/
16+
17+
# Test/coverage
18+
.pytest_cache/
19+
.coverage
20+
.coverage.*
21+
htmlcov/
22+
coverage.xml
23+
24+
# IDE/editor
25+
.vscode/
26+
.idea/
27+
28+
# OS
29+
.DS_Store

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.5.5
4+
hooks:
5+
- id: ruff
6+
args: ["--fix"]
7+
- id: ruff-format

0 commit comments

Comments
 (0)