diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d52d2b9..a26ebfc 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.13.0" + ".": "0.14.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 408b580..d012bc8 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 19 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-bceac2d798eb515f8fd14406ac6f50de2aa983a3674cecb63167c0d0d52cfbc9.yml -openapi_spec_hash: b9963276e8c0178b0c45bf2ea07f63fb +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-85efd6925654a59860b926f34cbf05bacbf7de258c1da29a523ad3b3c04c52d8.yml +openapi_spec_hash: 6fe5c6605f24a2e7dc4306d3cdabdc90 config_hash: 3dbe79c14ecd9a153418249f9155d159 diff --git a/CHANGELOG.md b/CHANGELOG.md index eb62ba4..6460328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.14.0 (2026-08-26) + +Full Changelog: [v0.13.0...v0.14.0](https://github.com/prelude-so/python-sdk/compare/v0.13.0...v0.14.0) + +### Features + +* **api:** api update ([a26c822](https://github.com/prelude-so/python-sdk/commit/a26c8229337934a3d8aa9538c3f77aed50e27946)) +* **api:** api update ([0cb1485](https://github.com/prelude-so/python-sdk/commit/0cb148510657037c636847d21929c1c104a45a70)) + + +### Chores + +* **internal:** allow the mock server port to be set with STAINLESS_MOCK_PORT ([1e250e9](https://github.com/prelude-so/python-sdk/commit/1e250e9c868f9b2b2840153a2c66e9e4b4cc30ad)) + ## 0.13.0 (2026-08-07) Full Changelog: [v0.12.0...v0.13.0](https://github.com/prelude-so/python-sdk/compare/v0.12.0...v0.13.0) diff --git a/pyproject.toml b/pyproject.toml index 942e6f9..2bdc9df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "prelude-python-sdk" -version = "0.13.0" +version = "0.14.0" description = "The official Python library for the Prelude API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/scripts/mock b/scripts/mock index feebe5e..984e1c0 100755 --- a/scripts/mock +++ b/scripts/mock @@ -4,6 +4,11 @@ set -e cd "$(dirname "$0")/.." +if [ "$1" == "--install" ]; then + npm exec --package=@stdy/cli@0.22.1 -- steady --version + exit 0 +fi + if [[ -n "$1" && "$1" != '--'* ]]; then URL="$1" shift @@ -20,16 +25,18 @@ fi echo "==> Starting mock server with URL ${URL}" # Run steady mock on the given spec +MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}" + if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout npm exec --package=@stdy/cli@0.22.1 -- steady --version - npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" attempts=0 - while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do + while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do if ! kill -0 $! 2>/dev/null; then echo cat .stdy.log @@ -48,5 +55,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" + npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index 19acc91..9dbb5cd 100755 --- a/scripts/test +++ b/scripts/test @@ -9,8 +9,10 @@ GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color +MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}" + function steady_is_running() { - curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1 + curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1 } kill_server_on_port() { @@ -27,7 +29,7 @@ function is_overriding_api_base_url() { if ! is_overriding_api_base_url && ! steady_is_running ; then # When we exit this script, make sure to kill the background mock server process - trap 'kill_server_on_port 4010' EXIT + trap 'kill_server_on_port "$MOCK_PORT"' EXIT # Start the dev server ./scripts/mock --daemon @@ -43,7 +45,7 @@ elif ! steady_is_running ; then echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 @@ -52,6 +54,10 @@ else echo fi +if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then + export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT" +fi + export DEFER_PYDANTIC_BUILD=false echo "==> Running tests" diff --git a/src/prelude_python_sdk/_version.py b/src/prelude_python_sdk/_version.py index 65cf06b..2aab5a9 100644 --- a/src/prelude_python_sdk/_version.py +++ b/src/prelude_python_sdk/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "prelude_python_sdk" -__version__ = "0.13.0" # x-release-please-version +__version__ = "0.14.0" # x-release-please-version diff --git a/src/prelude_python_sdk/types/verification_create_params.py b/src/prelude_python_sdk/types/verification_create_params.py index 53058ca..73efc28 100644 --- a/src/prelude_python_sdk/types/verification_create_params.py +++ b/src/prelude_python_sdk/types/verification_create_params.py @@ -229,6 +229,15 @@ class Signals(TypedDict, total=False): device_platform: Literal["android", "ios", "ipados", "tvos", "web"] """The type of the user's device.""" + existing_user: bool + """ + Whether the end-user already exists in your system, for example an existing + account signing in again rather than a first-time signup. Unlike + `is_trusted_user`, this signal does not bypass fraud checks; it is taken into + account as one additional anti-fraud signal. For more details, refer to + [Signals](/verify/v2/documentation/prevent-fraud#signals). + """ + ip: str """The public IP v4 or v6 address of the end-user's device. diff --git a/src/prelude_python_sdk/types/watch_predict_params.py b/src/prelude_python_sdk/types/watch_predict_params.py index abc43a4..93a0496 100644 --- a/src/prelude_python_sdk/types/watch_predict_params.py +++ b/src/prelude_python_sdk/types/watch_predict_params.py @@ -69,6 +69,15 @@ class Signals(TypedDict, total=False): device_platform: Literal["android", "ios", "ipados", "tvos", "web"] """The type of the user's device.""" + existing_user: bool + """ + Whether the end-user already exists in your system, for example an existing + account signing in again rather than a first-time signup. Unlike + `is_trusted_user`, this signal does not bypass fraud checks; it is taken into + account as one additional anti-fraud signal. For more details, refer to + [Signals](/verify/v2/documentation/prevent-fraud#signals). + """ + ip: str """The public IP v4 or v6 address of the end-user's device. diff --git a/src/prelude_python_sdk/types/watch_predict_response.py b/src/prelude_python_sdk/types/watch_predict_response.py index 906108d..499d6ed 100644 --- a/src/prelude_python_sdk/types/watch_predict_response.py +++ b/src/prelude_python_sdk/types/watch_predict_response.py @@ -24,6 +24,7 @@ class WatchPredictResponse(BaseModel): risk_factors: Optional[ List[ Literal[ + "account_risk_profile", "behavioral_pattern", "device_attribute", "fraud_database", @@ -42,6 +43,9 @@ class WatchPredictResponse(BaseModel): Only present when prediction is "suspicious" and the anti-fraud system detected specific risk signals. + - `account_risk_profile` - The target matches a risk profile derived from the + outcomes reported on your own account, rather than from a signal shared across + accounts. - `behavioral_pattern` - The phone number past behavior during verification flows exhibits suspicious patterns. - `device_attribute` - The device exhibits characteristics associated with diff --git a/tests/api_resources/test_verification.py b/tests/api_resources/test_verification.py index 6279bae..b8aa3b3 100644 --- a/tests/api_resources/test_verification.py +++ b/tests/api_resources/test_verification.py @@ -62,6 +62,7 @@ def test_method_create_with_all_params(self, client: Prelude) -> None: "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2", "device_model": "iPhone17,2", "device_platform": "ios", + "existing_user": False, "ip": "203.0.113.123", "is_trusted_user": False, "ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1", @@ -208,6 +209,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncPrelude) - "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2", "device_model": "iPhone17,2", "device_platform": "ios", + "existing_user": False, "ip": "203.0.113.123", "is_trusted_user": False, "ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1", diff --git a/tests/api_resources/test_watch.py b/tests/api_resources/test_watch.py index b35509e..95343e7 100644 --- a/tests/api_resources/test_watch.py +++ b/tests/api_resources/test_watch.py @@ -45,6 +45,7 @@ def test_method_predict_with_all_params(self, client: Prelude) -> None: "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2", "device_model": "iPhone17,2", "device_platform": "ios", + "existing_user": False, "ip": "203.0.113.123", "is_trusted_user": False, "ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1", @@ -227,6 +228,7 @@ async def test_method_predict_with_all_params(self, async_client: AsyncPrelude) "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2", "device_model": "iPhone17,2", "device_platform": "ios", + "existing_user": False, "ip": "203.0.113.123", "is_trusted_user": False, "ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1",