Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

## Checklist

- [ ] Ran `ruff check`, `ruff format` and `pytest`
- [ ] Ran `ruff check`, `ruff format`, `mypy src` and `pytest`
- [ ] Updated `README.md` and `examples/`, if usage changed
- [ ] Bumped `version` in `pyproject.toml` and ran `uv lock`, if this needs a release
48 changes: 44 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,63 @@ jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: astral-sh/[email protected]
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
python-version: "3.12"
- run: uv sync --locked --extra dev
- run: uv run ruff check
- run: uv run ruff format --check
- run: uv run mypy src

test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v7
- uses: astral-sh/[email protected]
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
python-version: ${{ matrix.python-version }}
- run: uv sync --locked --extra dev
- run: uv run pytest

# Test with the minimum versions allowed in pyproject.toml.
test-lowest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
python-version: "3.10"
- run: uv run --resolution lowest-direct --extra dev pytest

coverage:
runs-on: ubuntu-latest
permissions:
pull-requests: write # Post the coverage comment on pull requests
contents: write # Save the coverage badge to the python-coverage-comment-action-data branch
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
with:
python-version: "3.12"
- run: uv sync --locked --extra dev
# Check the 90% minimum after the comment, so the comment shows even when coverage drops.
- run: uv run pytest --cov --cov-fail-under=0
- uses: py-cov-action/python-coverage-comment-action@a05be3d2e8a6272d3ef5fb2840ab20368bb2eb71 # v4.3
with:
GITHUB_TOKEN: ${{ github.token }}
MINIMUM_GREEN: 90
- run: uv run coverage report

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
- run: uv build
- run: uvx twine check --strict dist/*
18 changes: 18 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Release

on:
release:
types: [published]

jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
permissions:
contents: read
id-token: write # Needed for PyPI trusted publishing
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
- run: uv build
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ venv/
*.json
__pycache__/

**/*egg-info*
**/*egg-info*
.coverage
dist/
16 changes: 13 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ them from the `BEHAVIORALSIGNALS_CID` and `BEHAVIORALSIGNALS_API_KEY` environmen

## Code style

We use [ruff](https://docs.astral.sh/ruff/) with the settings in `ruff.toml` (line length 100).
The dev install above includes the ruff version we use. Before you open a pull request, run:
We use [ruff](https://docs.astral.sh/ruff/) with the settings in `ruff.toml` (line length 100),
and [mypy](https://mypy.readthedocs.io/) to check types. The dev install above includes the
versions we use. Before you open a pull request, run:

```bash
ruff check
ruff format
mypy src
```

## Tests
Expand All @@ -60,7 +62,10 @@ The tests don't call the API, so they need no credentials. Run them with:
pytest
```

CI runs ruff and the tests on Python 3.10 to 3.13 for every pull request.
To see which lines the tests miss, run `pytest --cov`. It fails if coverage is below 90%.

CI runs ruff and mypy, and runs the tests on Python 3.10 to 3.13, for every pull request. It also
runs the tests with the lowest versions allowed in `pyproject.toml`, and checks coverage.

## Regenerate the gRPC code

Expand All @@ -87,3 +92,8 @@ Then, in `src/behavioralsignals/generated/api_pb2_grpc.py`, change `import api_p
3. If you change how the SDK is used, update `README.md` and `examples/`.
4. If the change needs a new release, bump `version` in `pyproject.toml` and run `uv lock`.
5. Open the pull request and fill in the template.

## Releases

Maintainers release from `main`. Publish a GitHub release with a tag like `v1.0.0` that matches
`version` in `pyproject.toml`. The Release workflow then builds the package and uploads it to PyPI.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
[![Twitter](https://badgen.net/badge/b/behavioralsignals/icon?icon=twitter&label&color=black)](https://x.com/behaviorsignals)
[![readme.io](https://badgen.net/badge/readme.io/Documentation/?color=black)](https://behavioralsignals.readme.io/)
[![CI](https://github.com/BehavioralSignalTechnologies/behavioralsignals-python/actions/workflows/ci.yml/badge.svg)](https://github.com/BehavioralSignalTechnologies/behavioralsignals-python/actions/workflows/ci.yml)
[![Coverage](https://raw.githubusercontent.com/BehavioralSignalTechnologies/behavioralsignals-python/python-coverage-comment-action-data/badge.svg)](https://github.com/BehavioralSignalTechnologies/behavioralsignals-python/tree/python-coverage-comment-action-data)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
[![PyPI](https://badgen.net/pypi/v/behavioralsignals)](https://pypi.org/project/behavioralsignals/)
[![Status](https://img.shields.io/pypi/status/behavioralsignals)](https://pypi.org/project/behavioralsignals/)
Expand Down
25 changes: 25 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ dependencies = [
[project.optional-dependencies]
dev = [
"grpcio-tools>=1.73.1",
"mypy==2.3.1",
"pytest>=8",
"pytest-cov>=7",
"ruff==0.16.8",
"types-grpcio>=1.83.0",
"types-protobuf>=7.35.1",
]

[project.urls]
Expand All @@ -57,3 +61,24 @@ where = ["src"]

[tool.setuptools.package-data]
behavioralsignals = ["py.typed"]

[tool.coverage.run]
source = ["behavioralsignals"]
omit = ["*/behavioralsignals/generated/*"]
relative_files = true
branch = true

[tool.coverage.report]
fail_under = 90
show_missing = true

[tool.mypy]
plugins = ["pydantic.mypy"]

[[tool.mypy.overrides]]
module = "behavioralsignals.generated.*"
ignore_errors = true

[[tool.mypy.overrides]]
module = "pydub.*"
ignore_missing_imports = true
3 changes: 1 addition & 2 deletions src/behavioralsignals/behavioral.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ def list_processes(

query_params = ProcessListParams(
page=page, page_size=page_size, sort=sort, start_date=start_date, end_date=end_date
)
query_params = query_params.model_dump(by_alias=True, exclude_none=True)
).model_dump(by_alias=True, exclude_none=True)

data = self._send_request(
path=f"clients/{self.config.cid}/processes",
Expand Down
6 changes: 2 additions & 4 deletions src/behavioralsignals/deepfakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ def list_processes(

query_params = ProcessListParams(
page=page, page_size=page_size, sort=sort, start_date=start_date, end_date=end_date
)
query_params = query_params.model_dump(by_alias=True, exclude_none=True)
).model_dump(by_alias=True, exclude_none=True)

data = self._send_request(
path=f"detection/clients/{self.config.cid}/processes",
Expand Down Expand Up @@ -331,8 +330,7 @@ def list_video_processes(

query_params = ProcessListParams(
page=page, page_size=page_size, sort=sort, start_date=start_date, end_date=end_date
)
query_params = query_params.model_dump(by_alias=True, exclude_none=True)
).model_dump(by_alias=True, exclude_none=True)

data = self._send_request(
path=f"detection/clients/{self.config.cid}/processes/video",
Expand Down
6 changes: 3 additions & 3 deletions src/behavioralsignals/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def __len__(self) -> int:
def __getitem__(self, index):
return self.processes[index]

@computed_field
@computed_field # type: ignore[prop-decorator]
@property
def total_count(self) -> int:
return len(self.processes)
Expand Down Expand Up @@ -256,12 +256,12 @@ class ResultItem(_SerializableModel):
examples=["[11.614513397216797, -15.228992462158203, -4.92175817489624, ...]"],
)

@computed_field
@computed_field # type: ignore[prop-decorator]
@property
def st(self) -> float | None:
return float(self.startTime) if self.startTime else None

@computed_field
@computed_field # type: ignore[prop-decorator]
@property
def et(self) -> float | None:
return float(self.endTime) if self.endTime else None
Expand Down
Loading
Loading