Skip to content

Latest commit

 

History

History
156 lines (100 loc) · 6.21 KB

contributing.md

File metadata and controls

156 lines (100 loc) · 6.21 KB

Contributing to Fingerprint Server API SDK

Structure

Most files in the project are autogenerated by openapi-generator with urllib3 library for python.

Commit messages

This project follows the Conventional Commits standard. commitlint checks the messages of all commits in a pull request in the Analyze Commit Messages check, using the @fingerprintjs/commit-lint-dx-team config.

Git hooks

This repository has two optional hook setups. You can only use one of them at a time.

  • install_hooks.sh sets core.hooksPath to the .git_hooks folder and installs commitlint globally with npm, so you need Node.js. Its commit-msg hook checks the commit message with commitlint, and its pre-push hook tries to stop accidental pushes to main:

    pnpm install
    ./install_hooks.sh
  • pre-commit runs Ruff (formatting and linting) and MyPy on every commit. Install it after uv sync:

    uv run pre-commit install

pre-commit install refuses to run while core.hooksPath is set, so it doesn't work after ./install_hooks.sh. To switch to pre-commit, run git config --unset-all core.hooksPath first.

Commit messages are also checked in CI. If the check fails, reword the offending commits (for example, with git rebase -i) and force-push the branch.

Code generation

You need Docker to run code generation with openapi-generator.

You can just run ./generate.sh script and it will do all the work.

To download fresh OpenAPI schema run ./sync.sh

Linting and Formatting

This project uses Ruff for linting and formatting, and MyPy for type checking.

Running locally

# Format code
uv run ruff format .

# Run linter
uv run ruff check --fix .

# Run type checker
uv run mypy fingerprint_server_sdk

Updating templates

When modifying templates in the template/ directory, try to generate code that minimizes formatter changes. This includes:

  • Using single quotes instead of double quotes
  • Sorting imports (standard library -> third-party -> local)
  • Using modern type annotations (list, dict, tuple instead of List, Dict, Tuple)
  • Removing # coding: utf-8 headers (we are already aiming Python 3.9+)

However, some formatting issues are difficult or impossible to fix in Mustache templates due to:

  • Vendor extensions injecting imports that may duplicate template imports
  • Conditional blocks creating extra whitespaces
  • Mustache's limited control over output formatting

In these cases, it's acceptable to let the formatter handle the adjustments. The goal is to minimize unnecessary changes, not eliminate them entirely.

Configuration

Project configuration is described in config.json file. To read about available parameters run the command below:

docker run --rm openapitools/openapi-generator-cli:v7.19.0 config-help -g python

Testing the local source code of the SDK

To make requests using the local source code of the SDK:

  1. Define your Secret API key, Visitor ID, Request ID and Region by creating a .env file at the root of the repository. (See example))
  2. Run the following commands:
uv sync
uv run python run_checks.py

Test environment

You need to install uv. Then you can run:

uv sync

Running tests

uv run pytest

How to publish

We use changesets to version the SDK and to write release notes.

Adding a changeset

If your PR changes the SDK's public API or behavior, add a changeset to it:

pnpm install
pnpm exec changeset

Pick the bump type and write a short summary. The command creates a markdown file in the .changeset folder. Commit it together with the rest of your changes. The summary is copied as-is into CHANGELOG.md and the GitHub release notes, so write it for SDK users:

---
'@fingerprint/python-sdk': minor
---

Add `device_details` smart signal to the event model

Pick the bump type that matches the commit type:

Change Commit type Changeset bump Version change
Bug fix fix patch 9.8.0 -> 9.8.1
New backward-compatible feature feat minor 9.8.0 -> 9.9.0
Breaking change Any <type>! (for example, feat!) or a BREAKING CHANGE: footer major 9.8.0 -> 10.0.0
Docs, tests, CI, refactoring and other internal changes docs, test, ci, refactor, chore, ... No changeset No release

If a PR has several user-facing changes, add one changeset for each. When several changesets are released together, the highest bump wins.

Release flow

  1. On every PR, a bot comments with a preview of the release notes that the PR's changesets will produce. If the PR has no changesets, the comment reminds you to add one.
  2. After a PR with changesets is merged to main, the Release workflow opens a Release [changeset] PR, or updates it if it's already open. That PR consumes all pending changesets, bumps the version and updates CHANGELOG.md.
  3. Merging the Release [changeset] PR creates the Git tag and the GitHub release. The Publish workflow then uploads the package to PyPI.

Pre-release flow

Pre-release will be created after merging pr to the dev branch and running the release workflow.

Python uses PEP 440 for versions format, so we convert a pre-release version from semver to PEP 440 in the ./generate.sh.