seetapsych-attributes 0.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. seetapsych_attributes-0.0.2/.github/workflows/ci.yml +156 -0
  2. seetapsych_attributes-0.0.2/.github/workflows/publish.yml +188 -0
  3. seetapsych_attributes-0.0.2/.gitignore +33 -0
  4. seetapsych_attributes-0.0.2/.vscode/launch.json +14 -0
  5. seetapsych_attributes-0.0.2/.vscode/settings.json +11 -0
  6. seetapsych_attributes-0.0.2/DEVELOPMENT.md +96 -0
  7. seetapsych_attributes-0.0.2/LICENSE +15 -0
  8. seetapsych_attributes-0.0.2/PKG-INFO +742 -0
  9. seetapsych_attributes-0.0.2/README.md +707 -0
  10. seetapsych_attributes-0.0.2/pyproject.toml +104 -0
  11. seetapsych_attributes-0.0.2/seetapsych_attributes/__init__.py +13 -0
  12. seetapsych_attributes-0.0.2/seetapsych_attributes/_version.py +24 -0
  13. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/__init__.py +23 -0
  14. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/__init__.py +25 -0
  15. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/action_units.py +63 -0
  16. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/dense_landmarks.py +33 -0
  17. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/detection.py +26 -0
  18. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/dimensional_affect.py +41 -0
  19. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/expression.py +44 -0
  20. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/gaze_screen.py +54 -0
  21. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/heart_rate.py +45 -0
  22. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/landmarks.py +35 -0
  23. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/mesh.py +33 -0
  24. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/face/selection.py +34 -0
  25. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/head/__init__.py +21 -0
  26. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/head/detection.py +35 -0
  27. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/head/gaze_point.py +53 -0
  28. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/head/selection.py +40 -0
  29. seetapsych_attributes-0.0.2/seetapsych_attributes/schema/head/social_gaze.py +96 -0
  30. seetapsych_attributes-0.0.2/seetapsych_attributes/types/__init__.py +114 -0
  31. seetapsych_attributes-0.0.2/seetapsych_attributes/types/face.py +211 -0
  32. seetapsych_attributes-0.0.2/seetapsych_attributes/types/head.py +88 -0
  33. seetapsych_attributes-0.0.2/tests/__init__.py +0 -0
  34. seetapsych_attributes-0.0.2/tests/test_attributes.py +8 -0
  35. seetapsych_attributes-0.0.2/tools/generate_readme.py +141 -0
  36. seetapsych_attributes-0.0.2/tools/header.md +62 -0
  37. seetapsych_attributes-0.0.2/uv.lock +1405 -0
@@ -0,0 +1,156 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - workflows
8
+ - "workflows/**"
9
+ tags-ignore: ["r*"]
10
+ pull_request:
11
+
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ lint:
18
+ name: Lint & Type & Security
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+
25
+ - name: Derive package directory
26
+ id: pkg
27
+ run: |
28
+ REPO_NAME="${{ github.event.repository.name }}"
29
+ PACKAGE_DIR="${REPO_NAME//-/_}"
30
+ echo "PACKAGE_DIR=$PACKAGE_DIR" >> "$GITHUB_OUTPUT"
31
+ shell: bash
32
+
33
+ - name: Set up Python
34
+ uses: actions/setup-python@v5
35
+ with:
36
+ python-version: "3.12"
37
+
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v3
40
+ with:
41
+ enable-cache: true
42
+
43
+ - name: Install dependencies
44
+ run: uv sync --group dev
45
+
46
+ - name: Run all lint/type/security checks (collect all failures)
47
+ env:
48
+ PACKAGE_DIR: ${{ steps.pkg.outputs.PACKAGE_DIR }}
49
+ run: |
50
+ set +e
51
+ EXIT_CODE=0
52
+
53
+ echo "=== ruff check ==="
54
+ uv run ruff check .
55
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
56
+
57
+ echo ""
58
+ echo "=== ruff format --check ==="
59
+ uv run ruff format --check .
60
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
61
+
62
+ echo ""
63
+ echo "=== mypy ==="
64
+ uv run mypy "$PACKAGE_DIR"
65
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
66
+
67
+ echo ""
68
+ echo "=== bandit ==="
69
+ uv run bandit -r "$PACKAGE_DIR" -c pyproject.toml
70
+ EC=$?; [ $EC -ne 0 ] && EXIT_CODE=$EC
71
+
72
+ exit $EXIT_CODE
73
+ shell: bash
74
+
75
+ test:
76
+ name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
77
+ runs-on: ${{ matrix.os }}
78
+ needs: lint
79
+ strategy:
80
+ fail-fast: false
81
+ matrix:
82
+ include:
83
+ - python-version: "3.10"
84
+ os: ubuntu-latest
85
+ - python-version: "3.10"
86
+ os: windows-latest
87
+ - python-version: "3.11"
88
+ os: ubuntu-latest
89
+ - python-version: "3.11"
90
+ os: windows-latest
91
+ - python-version: "3.12"
92
+ os: ubuntu-latest
93
+ - python-version: "3.12"
94
+ os: windows-latest
95
+ - python-version: "3.12"
96
+ os: macos-latest
97
+ - python-version: "3.13"
98
+ os: ubuntu-latest
99
+ - python-version: "3.13"
100
+ os: windows-latest
101
+ - python-version: "3.14"
102
+ os: ubuntu-latest
103
+ - python-version: "3.14"
104
+ os: windows-latest
105
+
106
+ steps:
107
+ - uses: actions/checkout@v4
108
+ with:
109
+ fetch-depth: 0
110
+
111
+ - name: Set up Python ${{ matrix.python-version }}
112
+ uses: actions/setup-python@v5
113
+ with:
114
+ python-version: ${{ matrix.python-version }}
115
+
116
+ - name: Install uv
117
+ uses: astral-sh/setup-uv@v3
118
+ with:
119
+ enable-cache: true
120
+
121
+ - name: Install dependencies
122
+ run: uv sync --group dev
123
+
124
+ - name: Run pytest
125
+ run: uv run pytest
126
+
127
+ build:
128
+ name: Build package
129
+ runs-on: ubuntu-latest
130
+ needs: test
131
+
132
+ steps:
133
+ - uses: actions/checkout@v4
134
+ with:
135
+ fetch-depth: 0
136
+
137
+ - name: Set up Python
138
+ uses: actions/setup-python@v5
139
+ with:
140
+ python-version: "3.12"
141
+
142
+ - name: Install build tools
143
+ run: python -m pip install --upgrade build twine
144
+
145
+ - name: Build package
146
+ run: python -m build
147
+
148
+ - name: Verify built artifacts
149
+ run: twine check dist/*
150
+
151
+ - name: Upload dist artifacts
152
+ uses: actions/upload-artifact@v4
153
+ with:
154
+ name: dist-artifacts
155
+ path: dist/
156
+ if-no-files-found: error
@@ -0,0 +1,188 @@
1
+ name: Publish to PyPI & GitHub Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "r*"
7
+
8
+ jobs:
9
+ test:
10
+ name: Pytest smoke gate
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ fetch-depth: 0
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v3
24
+ with:
25
+ enable-cache: true
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --group dev
29
+
30
+ - name: Run pytest (release gate)
31
+ run: uv run pytest
32
+
33
+ github-release:
34
+ name: Build and create GitHub Release
35
+ runs-on: ubuntu-latest
36
+ needs: test
37
+ permissions:
38
+ contents: write
39
+
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ with:
43
+ fetch-depth: 0
44
+
45
+ - name: Set up Python
46
+ uses: actions/setup-python@v5
47
+ with:
48
+ python-version: "3.12"
49
+
50
+ - name: Install build tools
51
+ run: python -m pip install --upgrade build twine
52
+
53
+ - name: Build package
54
+ run: python -m build
55
+
56
+ - name: Verify built artifacts
57
+ run: twine check dist/*
58
+
59
+ - name: Extract tag name
60
+ id: get_tag
61
+ run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
62
+ shell: bash
63
+
64
+ - name: Determine release type
65
+ id: release_type
66
+ run: |
67
+ TAG="${{ steps.get_tag.outputs.TAG }}"
68
+ if [[ "$TAG" == *-* ]]; then
69
+ echo "PYPI_PUBLISH=false" >> "$GITHUB_OUTPUT"
70
+ echo "PRERELEASE=true" >> "$GITHUB_OUTPUT"
71
+ else
72
+ echo "PYPI_PUBLISH=true" >> "$GITHUB_OUTPUT"
73
+ echo "PRERELEASE=false" >> "$GITHUB_OUTPUT"
74
+ fi
75
+ shell: bash
76
+
77
+ - name: Discover dist assets
78
+ id: assets
79
+ run: |
80
+ SDIST=$(ls dist/*.tar.gz | head -n1)
81
+ WHEEL=$(ls dist/*.whl | head -n1)
82
+ echo "SDIST=$SDIST" >> "$GITHUB_OUTPUT"
83
+ echo "WHEEL=$WHEEL" >> "$GITHUB_OUTPUT"
84
+ echo "SDIST_NAME=$(basename $SDIST)" >> "$GITHUB_OUTPUT"
85
+ echo "WHEEL_NAME=$(basename $WHEEL)" >> "$GITHUB_OUTPUT"
86
+ shell: bash
87
+
88
+ - name: Compose release body
89
+ id: release_body
90
+ env:
91
+ PYPI_PUBLISH: ${{ steps.release_type.outputs.PYPI_PUBLISH }}
92
+ REPO: ${{ github.repository }}
93
+ GITHUB_REF_NAME: ${{ github.ref_name }}
94
+ run: |
95
+ PROJ_NAME="${REPO#*/}"
96
+ VERSION="${GITHUB_REF_NAME#r}"
97
+ BODY_FILE=$(mktemp)
98
+ if [ "$PYPI_PUBLISH" = "true" ]; then
99
+ {
100
+ echo "Install from PyPI:"
101
+ echo ""
102
+ echo '```bash'
103
+ echo "pip install ${PROJ_NAME}==${VERSION}"
104
+ echo '```'
105
+ echo ""
106
+ echo "PyPI page: https://pypi.org/project/${PROJ_NAME}/${VERSION}/"
107
+ } >"$BODY_FILE"
108
+ else
109
+ {
110
+ echo "**Preview build** \u2014 available only from GitHub Assets."
111
+ echo ""
112
+ echo "This build is not published to PyPI."
113
+ echo ""
114
+ echo "To try it, download the wheel from the Assets section below and install:"
115
+ echo ""
116
+ echo '```bash'
117
+ echo "pip install ./${PROJ_NAME}-*.whl"
118
+ echo '```'
119
+ } >"$BODY_FILE"
120
+ fi
121
+ {
122
+ echo "BODY<<GITHUB_EOF_MARKER"
123
+ cat "$BODY_FILE"
124
+ echo "GITHUB_EOF_MARKER"
125
+ } >> "$GITHUB_OUTPUT"
126
+ rm -f "$BODY_FILE"
127
+ shell: bash
128
+
129
+ - name: Upload dist artifacts
130
+ uses: actions/upload-artifact@v4
131
+ with:
132
+ name: dist-artifacts-${{ steps.get_tag.outputs.TAG }}
133
+ path: dist/
134
+ if-no-files-found: error
135
+
136
+ - name: Create GitHub Release
137
+ id: create_release
138
+ uses: actions/create-release@v1
139
+ env:
140
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
141
+ with:
142
+ tag_name: ${{ steps.get_tag.outputs.TAG }}
143
+ release_name: Release ${{ steps.get_tag.outputs.TAG }}
144
+ body: ${{ steps.release_body.outputs.BODY }}
145
+ draft: false
146
+ prerelease: ${{ steps.release_type.outputs.PRERELEASE }}
147
+
148
+ - name: Upload sdist to GitHub Release
149
+ uses: actions/upload-release-asset@v1
150
+ env:
151
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
152
+ with:
153
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
154
+ asset_path: ${{ steps.assets.outputs.SDIST }}
155
+ asset_name: ${{ steps.assets.outputs.SDIST_NAME }}
156
+ asset_content_type: application/gzip
157
+
158
+ - name: Upload wheel to GitHub Release
159
+ uses: actions/upload-release-asset@v1
160
+ env:
161
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
162
+ with:
163
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
164
+ asset_path: ${{ steps.assets.outputs.WHEEL }}
165
+ asset_name: ${{ steps.assets.outputs.WHEEL_NAME }}
166
+ asset_content_type: application/zip
167
+
168
+ pypi-publish:
169
+ name: Publish to PyPI
170
+ runs-on: ubuntu-latest
171
+ needs: github-release
172
+ if: startsWith(github.ref, 'refs/tags/r') && !contains(github.ref_name, '-')
173
+ environment:
174
+ name: pypi
175
+ url: https://pypi.org/p/${{ github.event.repository.name }}
176
+ permissions:
177
+ id-token: write
178
+ contents: read
179
+
180
+ steps:
181
+ - name: Download dist artifacts from github-release job
182
+ uses: actions/download-artifact@v4
183
+ with:
184
+ name: dist-artifacts-${{ github.ref_name }}
185
+ path: dist
186
+
187
+ - name: Publish package distributions to PyPI
188
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,33 @@
1
+ # project
2
+ /.idea/
3
+ /.venv/
4
+ /build/
5
+ /dist/
6
+ /*.egg-info/
7
+ /.eggs/
8
+ /.pytest_cache/
9
+ /.mypy_cache/
10
+ /.ruff_cache/
11
+ /.tox/
12
+ /.nox/
13
+ /htmlcov/
14
+ /.coverage
15
+ /coverage.xml
16
+ /.hypothesis/
17
+ /.cache/
18
+ /.upload/
19
+ /.streamlit/
20
+ /.ipynb_checkpoints/
21
+ *.log
22
+ .env
23
+
24
+ # generated files
25
+ seetapsych_attributes/_version.py
26
+
27
+ # compiled files
28
+ *.pyc
29
+ __pycache__/
30
+ *.pyo
31
+ *.pyd
32
+ *.so
33
+ *$py.class
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Build Doc Configs",
6
+ "type": "debugpy",
7
+ "request": "launch",
8
+ "program": "${workspaceFolder}/tools/generate_readme.py",
9
+ "cwd": "${workspaceFolder}",
10
+ "console": "integratedTerminal",
11
+ "justMyCode": true
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "terminal.integrated.env.windows": {
3
+ "PYTHONPATH": "${workspaceFolder}"
4
+ },
5
+ "terminal.integrated.env.linux": {
6
+ "PYTHONPATH": "${workspaceFolder}"
7
+ },
8
+ "terminal.integrated.env.osx": {
9
+ "PYTHONPATH": "${workspaceFolder}"
10
+ }
11
+ }
@@ -0,0 +1,96 @@
1
+ # Development Guide
2
+
3
+ ## Local Verification (Before Creating a Release Tag)
4
+
5
+ Run these commands from the repository root. Make sure you have [`uv`](https://github.com/astral-sh/uv) installed.
6
+
7
+ ```bash
8
+ # Per-project: set PACKAGE to the top-level importable package directory
9
+ PACKAGE=seetapsych_attributes
10
+ # For any seetapsych-* project, auto-detect instead:
11
+ # PACKAGE="$(ls -d seetapsych_* 2>/dev/null | head -n1)"
12
+
13
+ # 1. Sync dependencies (installs the package + dev tools)
14
+ uv sync --group dev
15
+
16
+ # 2. Lint (ruff) (use `ruff check . --fix` to fix)
17
+ uv run ruff check .
18
+
19
+ # 3. Format check (ruff format -- non-destructive; use `ruff format` to apply)
20
+ uv run ruff format --check .
21
+
22
+ # 4. Static type check (mypy, strict mode)
23
+ uv run mypy "$PACKAGE"
24
+
25
+ # 5. Security scan (bandit)
26
+ uv run bandit -r "$PACKAGE" -c pyproject.toml
27
+
28
+ # 6. Unit tests (pytest)
29
+ uv run pytest
30
+
31
+ # 7. Build the distribution packages + verify metadata
32
+ uv run python -m build
33
+ uv run twine check dist/*
34
+ ```
35
+
36
+ If all seven steps pass, the code is ready to be tagged for release.
37
+
38
+ ## Tag Naming and Release Pipeline
39
+
40
+ Tag format is managed by [`hatch-vcs`](https://github.com/ofek/hatch-vcs) with the following pattern in `pyproject.toml`:
41
+
42
+ ```
43
+ tag-pattern = "^r(?P<version>[^-]+)$"
44
+ ```
45
+
46
+ This separates tags into two classes that drive the GitHub Actions pipeline in `.github/workflows/publish.yml`:
47
+
48
+ ### Class A — Official Release: `r<version>` (no `-`)
49
+
50
+ **Format**: `r` + a version string that contains **no hyphen** `-`.
51
+
52
+ Examples:
53
+ - `r0.1.0`
54
+ - `r2026.08.30`
55
+ - `r1.0.0.post1`
56
+
57
+ Pipeline behavior:
58
+ 1. CI runs (lint + test + build).
59
+ 2. `github-release` job builds sdist + wheel, **creates a GitHub Release** (`prerelease: false`), attaches both assets, and links to the PyPI version page.
60
+ 3. `pypi-publish` job runs (`if: no '-' in tag`) and uploads the same sdist + wheel to PyPI via Trusted Publisher (OIDC, no API token required).
61
+
62
+ ### Class B — Temporary / Pre-release: `r<version>-<suffix>`
63
+
64
+ **Format**: `r` + anything + **at least one hyphen** `-` + anything.
65
+
66
+ Examples:
67
+ - `r0.2.0-alpha`
68
+ - `r0.2.0-rc1`
69
+ - `r2026.08.30-tmp-hotfix-42`
70
+ - `r1.0.0-just-testing-release-flow`
71
+
72
+ Pipeline behavior:
73
+ 1. CI still runs (same lint + test + build gates — everything must still pass).
74
+ 2. `github-release` job builds sdist + wheel, creates a GitHub Release **marked as `prerelease: true`**, attaches both assets, and the release body clearly states "not published to PyPI".
75
+ 3. `pypi-publish` job is **skipped** (`if:` condition fails because the tag contains `-`). Nothing is uploaded to PyPI.
76
+
77
+ ### Quick Tagging Recipe
78
+
79
+ ```bash
80
+ # --- official release (PyPI + GitHub Release) ---
81
+ git tag r0.1.0
82
+ git push origin r0.1.0
83
+
84
+ # --- temp / pre-release (GitHub Release only, PyPI skipped) ---
85
+ git tag r0.1.0-alpha
86
+ git push origin r0.1.0-alpha
87
+ ```
88
+
89
+ ### Why the two classes?
90
+
91
+ Use Class B tags whenever you want to:
92
+ - exercise the full build + release-creation pipeline end-to-end without polluting PyPI,
93
+ - ship a throwaway build for QA or a staging consumer that can pull GitHub Release assets directly,
94
+ - share candidate wheels for a hotfix before cutting the final tag.
95
+
96
+ When the candidate is validated, re-tag without the suffix (e.g., `r0.1.0`) and push — the same CI gates run again, followed by the official PyPI publish.
@@ -0,0 +1,15 @@
1
+ Copyright (c) 2026, Visual Information Processing and Learning (VIPL) group,
2
+ Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China;
3
+ Southeast University, China;
4
+ Beijing Seetatech Co., Ltd.
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12
+
13
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.