pynissan is an async Python client for MyNISSAN connected vehicles. It provides a typed
API for vehicle telemetry, charging, climate, remote commands, account data, and
connected-service features.
The client supports MyNISSAN accounts in the United States and Canada, plus MiNissan accounts in Mexico. Vehicle and subscription capabilities determine which telemetry and remote controls are available.
- Fully async I/O built on
aiohttp. - Typed, immutable response models and a
py.typedmarker. - Cached vehicle, battery, charging, climate, door, location, tire, and mileage data.
- Charging, climate, lock, light, horn, engine, location, and status-refresh commands.
- Climate and charge schedules, vehicle capabilities, alerts, maintenance, and history.
- Automatic access-token refresh with a callback for persisting replacement tokens.
- Typed command requests with status polling and terminal results.
- Read-only mode enabled by default for safe discovery and monitoring.
python -m pip install pynissanPython 3.12 or newer is required.
Supported account markets are Country.US, Country.CA, and Country.MX.
The caller owns the aiohttp.ClientSession and decides how credentials and reusable tokens
are stored.
from aiohttp import ClientSession
from pynissan import Country, NissanClient, Tokens
async def save_tokens(tokens: Tokens) -> None:
"""Persist replacement tokens in the application's secure storage."""
async def read_vehicle(email: str, password: str) -> None:
async with ClientSession() as session:
client = NissanClient(
session,
country=Country.US,
token_listener=save_tokens,
)
await client.async_authenticate(email, password)
vehicles = await client.async_get_vehicles()
if not vehicles:
return
status = await client.async_get_vehicle_status(vehicles[0].vin)
if status.battery is not None:
print(status.battery.level)
print(status.battery.is_charging)Supply previously saved tokens to avoid signing in again:
client = NissanClient(
session,
country=Country.US,
tokens=saved_tokens,
token_listener=save_tokens,
)The client refreshes expired tokens before a request and publishes the replacement token set
through token_listener.
The authentication guide covers token reuse and request verification for applications that need those flows.
NissanClient starts in read-only mode. Queries work normally, while methods that change
vehicle or account state raise ReadOnlyError before any network request is sent.
from pynissan import Country, NissanClient
client = NissanClient(
session,
country=Country.US,
tokens=saved_tokens,
read_only=False,
)Enable write access only for an explicit user action. Remote commands return a typed request that can be polled until Nissan reports a terminal status.
from pynissan import ClimateSettings, TemperatureUnit
request = await client.async_start_climate(
vin,
ClimateSettings(72, TemperatureUnit.FAHRENHEIT),
)
result = await client.async_wait_for_service_request(vin, request)Battery status distinguishes the cable and charging states and includes the server-provided remaining charge time.
battery = await client.async_get_vehicle_battery_status(vin)
if battery is not None:
print(battery.level)
print(battery.is_plugged_in)
print(battery.is_charging)
print(battery.remaining_charge_time)All package exceptions inherit from NissanError:
AuthenticationErrorfor sign-in and token-refresh failures;NetworkErrorfor connection and timeout failures;ApiErrorfor rejected HTTP requests;GraphQLErrorfor rejected GraphQL operations;ResponseErrorfor malformed responses;ReadOnlyErrorfor blocked state-changing operations.
python -m pip install -e ".[test]"
python -m ruff check .
python -m ruff format --check .
python -m mypy
python -m pytest
python -m buildSee the API guide and authentication guide for usage details. Development and release procedures are documented in CONTRIBUTING.md and docs/releasing.md. Security issues should follow SECURITY.md.
pynissan is maintained by the community and is not affiliated with, endorsed by, or
supported by Nissan Motor Co., Ltd.