pyfordpass 0.0.1__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.
- pyfordpass-0.0.1/.gitignore +36 -0
- pyfordpass-0.0.1/LICENSE.txt +18 -0
- pyfordpass-0.0.1/PKG-INFO +164 -0
- pyfordpass-0.0.1/README.md +132 -0
- pyfordpass-0.0.1/fordpass/__init__.py +17 -0
- pyfordpass-0.0.1/fordpass/__main__.py +6 -0
- pyfordpass-0.0.1/fordpass/api_config.py +105 -0
- pyfordpass-0.0.1/fordpass/client.py +1341 -0
- pyfordpass-0.0.1/fordpass/commands/__init__.py +1 -0
- pyfordpass-0.0.1/fordpass/commands/alerts.py +103 -0
- pyfordpass-0.0.1/fordpass/commands/api_config.py +60 -0
- pyfordpass-0.0.1/fordpass/commands/auth.py +84 -0
- pyfordpass-0.0.1/fordpass/commands/config.py +60 -0
- pyfordpass-0.0.1/fordpass/commands/dealer.py +52 -0
- pyfordpass-0.0.1/fordpass/commands/departure.py +52 -0
- pyfordpass-0.0.1/fordpass/commands/drivers.py +97 -0
- pyfordpass-0.0.1/fordpass/commands/messages.py +146 -0
- pyfordpass-0.0.1/fordpass/commands/ota.py +146 -0
- pyfordpass-0.0.1/fordpass/commands/profile.py +104 -0
- pyfordpass-0.0.1/fordpass/commands/remote.py +108 -0
- pyfordpass-0.0.1/fordpass/commands/roadside.py +114 -0
- pyfordpass-0.0.1/fordpass/commands/schedule.py +282 -0
- pyfordpass-0.0.1/fordpass/commands/service.py +346 -0
- pyfordpass-0.0.1/fordpass/commands/telemetry.py +798 -0
- pyfordpass-0.0.1/fordpass/commands/utils.py +1224 -0
- pyfordpass-0.0.1/fordpass/commands/vehicle.py +338 -0
- pyfordpass-0.0.1/fordpass/config.py +306 -0
- pyfordpass-0.0.1/fordpass/main.py +61 -0
- pyfordpass-0.0.1/fordpass/py.typed +0 -0
- pyfordpass-0.0.1/fordpass/sansio.py +1611 -0
- pyfordpass-0.0.1/fordpass/timezone_map.py +438 -0
- pyfordpass-0.0.1/fordpass/typing/__init__.py +170 -0
- pyfordpass-0.0.1/fordpass/typing/alerts.py +125 -0
- pyfordpass-0.0.1/fordpass/typing/api_config.py +78 -0
- pyfordpass-0.0.1/fordpass/typing/auth.py +56 -0
- pyfordpass-0.0.1/fordpass/typing/commands.py +15 -0
- pyfordpass-0.0.1/fordpass/typing/common.py +87 -0
- pyfordpass-0.0.1/fordpass/typing/config.py +63 -0
- pyfordpass-0.0.1/fordpass/typing/dealer.py +20 -0
- pyfordpass-0.0.1/fordpass/typing/drivers.py +53 -0
- pyfordpass-0.0.1/fordpass/typing/messages.py +58 -0
- pyfordpass-0.0.1/fordpass/typing/profile.py +152 -0
- pyfordpass-0.0.1/fordpass/typing/release.py +13 -0
- pyfordpass-0.0.1/fordpass/typing/roadside.py +34 -0
- pyfordpass-0.0.1/fordpass/typing/schedule.py +60 -0
- pyfordpass-0.0.1/fordpass/typing/service.py +107 -0
- pyfordpass-0.0.1/fordpass/typing/telemetry.py +91 -0
- pyfordpass-0.0.1/fordpass/typing/vehicle.py +201 -0
- pyfordpass-0.0.1/fordpass/utils.py +272 -0
- pyfordpass-0.0.1/man/fordpass.1 +2416 -0
- pyfordpass-0.0.1/pyproject.toml +268 -0
- pyfordpass-0.0.1/tests/conftest.py +206 -0
- pyfordpass-0.0.1/tests/pyproject.toml +27 -0
- pyfordpass-0.0.1/tests/test_api_config.py +89 -0
- pyfordpass-0.0.1/tests/test_client.py +634 -0
- pyfordpass-0.0.1/tests/test_commands_api_config.py +93 -0
- pyfordpass-0.0.1/tests/test_commands_auth.py +80 -0
- pyfordpass-0.0.1/tests/test_commands_config.py +67 -0
- pyfordpass-0.0.1/tests/test_commands_data.py +395 -0
- pyfordpass-0.0.1/tests/test_commands_schedule.py +203 -0
- pyfordpass-0.0.1/tests/test_commands_service.py +300 -0
- pyfordpass-0.0.1/tests/test_commands_simple.py +328 -0
- pyfordpass-0.0.1/tests/test_commands_telemetry.py +512 -0
- pyfordpass-0.0.1/tests/test_commands_utils.py +598 -0
- pyfordpass-0.0.1/tests/test_commands_vehicle.py +229 -0
- pyfordpass-0.0.1/tests/test_config.py +223 -0
- pyfordpass-0.0.1/tests/test_main.py +22 -0
- pyfordpass-0.0.1/tests/test_sansio.py +505 -0
- pyfordpass-0.0.1/tests/test_utils.py +319 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
*.kate-swp
|
|
2
|
+
*.log
|
|
3
|
+
*~
|
|
4
|
+
.*.swp
|
|
5
|
+
.*_cache/
|
|
6
|
+
.DS_Store*
|
|
7
|
+
.coverage
|
|
8
|
+
.cspellcache
|
|
9
|
+
.directory
|
|
10
|
+
.pnp.*
|
|
11
|
+
.venv/
|
|
12
|
+
/.bash_profile
|
|
13
|
+
/.bashrc
|
|
14
|
+
/.claude/commands
|
|
15
|
+
/.claude/settings.local.json
|
|
16
|
+
/.gitconfig
|
|
17
|
+
/.gitmodules
|
|
18
|
+
/.idea
|
|
19
|
+
/.mcp.json
|
|
20
|
+
/.profile
|
|
21
|
+
/.ripgreprc
|
|
22
|
+
/.wiswa-ci/
|
|
23
|
+
/.yarn/install-state.gz
|
|
24
|
+
/.zprofile
|
|
25
|
+
/.zshrc
|
|
26
|
+
/build/
|
|
27
|
+
/dist/
|
|
28
|
+
/docs/_build/
|
|
29
|
+
/man/_static/
|
|
30
|
+
/mypy-report*/
|
|
31
|
+
__pycache__/
|
|
32
|
+
cobertura.xml
|
|
33
|
+
coverage.xml
|
|
34
|
+
htmlcov/
|
|
35
|
+
mypy-report.xml
|
|
36
|
+
node_modules/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pyfordpass authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
7
|
+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
8
|
+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
|
12
|
+
substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
15
|
+
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
|
18
|
+
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyfordpass
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: FordPass client and CLI.
|
|
5
|
+
Project-URL: Issues, https://github.com/Tatsh/pyfordpass/issues
|
|
6
|
+
Project-URL: documentation, https://pyfordpass.readthedocs.org
|
|
7
|
+
Project-URL: homepage, https://tatsh.github.io/pyfordpass/
|
|
8
|
+
Project-URL: repository, https://github.com/Tatsh/pyfordpass
|
|
9
|
+
Author-email: Andrew Udvare <audvare@gmail.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE.txt
|
|
12
|
+
Keywords: command line,ford,fordpass
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: <4.0,>=3.10
|
|
23
|
+
Requires-Dist: bascom>=0.1.3
|
|
24
|
+
Requires-Dist: click>=8.4.1
|
|
25
|
+
Requires-Dist: curl-cffi>=0.15.0
|
|
26
|
+
Requires-Dist: niquests>=3.18.8
|
|
27
|
+
Requires-Dist: platformdirs>=4.9.6
|
|
28
|
+
Requires-Dist: rich>=15.0.0
|
|
29
|
+
Requires-Dist: tomlkit>=0.15.0
|
|
30
|
+
Requires-Dist: typing-extensions>=4.15.0
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# pyfordpass
|
|
34
|
+
|
|
35
|
+
<!-- WISWA-GENERATED-README:START -->
|
|
36
|
+
|
|
37
|
+
[](https://www.python.org/)
|
|
38
|
+
[](https://pypi.org/project/pyfordpass/)
|
|
39
|
+
[](https://github.com/Tatsh/pyfordpass/tags)
|
|
40
|
+
[](https://github.com/Tatsh/pyfordpass/blob/master/LICENSE.txt)
|
|
41
|
+
[](https://github.com/Tatsh/pyfordpass/compare/v0.0.1...master)
|
|
42
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/codeql.yml)
|
|
43
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/qa.yml)
|
|
44
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/tests.yml)
|
|
45
|
+
[](https://coveralls.io/github/Tatsh/pyfordpass?branch=master)
|
|
46
|
+
[](https://github.com/dependabot)
|
|
47
|
+
[](https://pyfordpass.readthedocs.org/?badge=latest)
|
|
48
|
+
[](https://mypy-lang.org/)
|
|
49
|
+
[](https://docs.astral.sh/uv/)
|
|
50
|
+
[](https://docs.pytest.org/en/stable/)
|
|
51
|
+
[](https://github.com/astral-sh/ruff)
|
|
52
|
+
[](https://pepy.tech/project/pyfordpass)
|
|
53
|
+
[](https://github.com/Tatsh/pyfordpass/stargazers)
|
|
54
|
+
[](https://github.com/pre-commit/pre-commit)
|
|
55
|
+
[](https://prettier.io/)
|
|
56
|
+
|
|
57
|
+
[](https://bsky.app/profile/Tatsh.bsky.social)
|
|
58
|
+
[](https://buymeacoffee.com/Tatsh)
|
|
59
|
+
[](irc://irc.libera.chat/Tatsh)
|
|
60
|
+
[](https://hostux.social/@Tatsh)
|
|
61
|
+
[](https://www.patreon.com/Tatsh2)
|
|
62
|
+
|
|
63
|
+
<!-- WISWA-GENERATED-README:STOP -->
|
|
64
|
+
|
|
65
|
+
FordPass client and CLI. A third-party reverse-engineered client for the same private mobile-app
|
|
66
|
+
endpoints the FordPass™ app uses, packaged as a Python library plus a `fordpass` command-line
|
|
67
|
+
tool.
|
|
68
|
+
|
|
69
|
+
## Disclaimer
|
|
70
|
+
|
|
71
|
+
This project is **not** an official Ford product. It is **not** affiliated with, endorsed by,
|
|
72
|
+
sponsored by, or otherwise connected to Ford Motor Company or any of its subsidiaries.
|
|
73
|
+
"FordPass", "The Lincoln Way", "Ford", and "Lincoln" are trademarks of Ford Motor Company.
|
|
74
|
+
|
|
75
|
+
Because this client speaks to private endpoints rather than a documented public API, Ford may
|
|
76
|
+
change, throttle, or revoke access without notice - and the maintainer cannot guarantee that any
|
|
77
|
+
particular feature will keep working.
|
|
78
|
+
|
|
79
|
+
> **Use of this software may cause your FordPass™ / The Lincoln Way™ account to be (temporarily)
|
|
80
|
+
> locked or suspended.** Traffic from any unofficial client can look anomalous to Ford's fraud
|
|
81
|
+
> and abuse detection. **Use at your own risk.**
|
|
82
|
+
|
|
83
|
+
It is **strongly recommended** to use a **separate, secondary FordPass™ account** for this
|
|
84
|
+
software rather than your primary account:
|
|
85
|
+
|
|
86
|
+
1. In the FordPass app on a phone (signed in as the primary owner), invite a secondary email
|
|
87
|
+
address as an additional driver for the vehicle. The invited address must be reachable from
|
|
88
|
+
that phone for verification.
|
|
89
|
+
2. Sign up for a new FordPass account using that secondary email and accept the driver
|
|
90
|
+
invitation.
|
|
91
|
+
3. Configure `pyfordpass` (`fordpass auth login`) with the secondary account's credentials.
|
|
92
|
+
|
|
93
|
+
If the secondary account is later suspended, your primary account, warranty records, and
|
|
94
|
+
roadside-assistance enrolment remain unaffected.
|
|
95
|
+
|
|
96
|
+
See the [ha-fordpass project's general disclaimer and account-setup
|
|
97
|
+
guidance](https://github.com/marq24/ha-fordpass#general-disclaimer) for the same procedure
|
|
98
|
+
written up from the Home Assistant integration's perspective - the steps are identical
|
|
99
|
+
regardless of which third-party client consumes the credentials.
|
|
100
|
+
|
|
101
|
+
## Installation
|
|
102
|
+
|
|
103
|
+
```shell
|
|
104
|
+
pip install pyfordpass
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
Add `-d` to show debug logs. Run with no arguments to see the top-level command list:
|
|
110
|
+
|
|
111
|
+
```shell
|
|
112
|
+
fordpass
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
A typical first-time flow:
|
|
116
|
+
|
|
117
|
+
```shell
|
|
118
|
+
fordpass auth login # Interactive sign-in against the secondary account.
|
|
119
|
+
fordpass vehicle list # See what's in the garage.
|
|
120
|
+
fordpass vehicle show VIN # Detailed view for one vehicle.
|
|
121
|
+
fordpass remote start VIN # Remote-start command.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Every subcommand supports `--help` and most data-returning subcommands support `--json` for
|
|
125
|
+
machine-readable output.
|
|
126
|
+
|
|
127
|
+
## Configuration
|
|
128
|
+
|
|
129
|
+
`pyfordpass` has two sets of optional settings, each managed with its own subcommand rather than
|
|
130
|
+
by editing files by hand. Both live under `~/.config/pyfordpass` on Linux (the platform-specific
|
|
131
|
+
equivalent elsewhere).
|
|
132
|
+
|
|
133
|
+
**User preferences** are managed with `fordpass config`. The most useful is a default VIN, so you
|
|
134
|
+
need not pass it to every command:
|
|
135
|
+
|
|
136
|
+
```shell
|
|
137
|
+
# Set a default VIN, used whenever a command's VIN argument is omitted.
|
|
138
|
+
fordpass config set vehicle.default_vin VIN
|
|
139
|
+
# Distance ("mi"/"km") and temperature ("F"/"C"); both default from your locale.
|
|
140
|
+
fordpass config set units.distance mi
|
|
141
|
+
fordpass config set units.temperature C
|
|
142
|
+
# Default output format: "pretty" (Rich tables) or "json".
|
|
143
|
+
fordpass config set output.format json
|
|
144
|
+
# Show the effective configuration (defaults included), drop a key, or start over.
|
|
145
|
+
fordpass config dump
|
|
146
|
+
fordpass config delete units.distance
|
|
147
|
+
fordpass config reset
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**API constants** are managed with `fordpass api-config`. The built-in defaults target Ford in the
|
|
151
|
+
USA, so most users never need to touch them. When Ford rotates a host or client ID you can patch
|
|
152
|
+
individual values without waiting for a new release; anything you set is merged over the defaults,
|
|
153
|
+
so only the changed keys are required:
|
|
154
|
+
|
|
155
|
+
```shell
|
|
156
|
+
# Override a single value; everything else falls back to the built-in defaults.
|
|
157
|
+
fordpass api-config set hosts.login https://login.ford.com
|
|
158
|
+
# Show the effective constants (defaults merged with overrides), or discard all overrides.
|
|
159
|
+
fordpass api-config dump
|
|
160
|
+
fordpass api-config reset
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Values for other regions and for Lincoln can be copied from
|
|
164
|
+
[ha-fordpass `const.py`](https://github.com/marq24/ha-fordpass/blob/main/custom_components/fordpass/const.py).
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# pyfordpass
|
|
2
|
+
|
|
3
|
+
<!-- WISWA-GENERATED-README:START -->
|
|
4
|
+
|
|
5
|
+
[](https://www.python.org/)
|
|
6
|
+
[](https://pypi.org/project/pyfordpass/)
|
|
7
|
+
[](https://github.com/Tatsh/pyfordpass/tags)
|
|
8
|
+
[](https://github.com/Tatsh/pyfordpass/blob/master/LICENSE.txt)
|
|
9
|
+
[](https://github.com/Tatsh/pyfordpass/compare/v0.0.1...master)
|
|
10
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/codeql.yml)
|
|
11
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/qa.yml)
|
|
12
|
+
[](https://github.com/Tatsh/pyfordpass/actions/workflows/tests.yml)
|
|
13
|
+
[](https://coveralls.io/github/Tatsh/pyfordpass?branch=master)
|
|
14
|
+
[](https://github.com/dependabot)
|
|
15
|
+
[](https://pyfordpass.readthedocs.org/?badge=latest)
|
|
16
|
+
[](https://mypy-lang.org/)
|
|
17
|
+
[](https://docs.astral.sh/uv/)
|
|
18
|
+
[](https://docs.pytest.org/en/stable/)
|
|
19
|
+
[](https://github.com/astral-sh/ruff)
|
|
20
|
+
[](https://pepy.tech/project/pyfordpass)
|
|
21
|
+
[](https://github.com/Tatsh/pyfordpass/stargazers)
|
|
22
|
+
[](https://github.com/pre-commit/pre-commit)
|
|
23
|
+
[](https://prettier.io/)
|
|
24
|
+
|
|
25
|
+
[](https://bsky.app/profile/Tatsh.bsky.social)
|
|
26
|
+
[](https://buymeacoffee.com/Tatsh)
|
|
27
|
+
[](irc://irc.libera.chat/Tatsh)
|
|
28
|
+
[](https://hostux.social/@Tatsh)
|
|
29
|
+
[](https://www.patreon.com/Tatsh2)
|
|
30
|
+
|
|
31
|
+
<!-- WISWA-GENERATED-README:STOP -->
|
|
32
|
+
|
|
33
|
+
FordPass client and CLI. A third-party reverse-engineered client for the same private mobile-app
|
|
34
|
+
endpoints the FordPass™ app uses, packaged as a Python library plus a `fordpass` command-line
|
|
35
|
+
tool.
|
|
36
|
+
|
|
37
|
+
## Disclaimer
|
|
38
|
+
|
|
39
|
+
This project is **not** an official Ford product. It is **not** affiliated with, endorsed by,
|
|
40
|
+
sponsored by, or otherwise connected to Ford Motor Company or any of its subsidiaries.
|
|
41
|
+
"FordPass", "The Lincoln Way", "Ford", and "Lincoln" are trademarks of Ford Motor Company.
|
|
42
|
+
|
|
43
|
+
Because this client speaks to private endpoints rather than a documented public API, Ford may
|
|
44
|
+
change, throttle, or revoke access without notice - and the maintainer cannot guarantee that any
|
|
45
|
+
particular feature will keep working.
|
|
46
|
+
|
|
47
|
+
> **Use of this software may cause your FordPass™ / The Lincoln Way™ account to be (temporarily)
|
|
48
|
+
> locked or suspended.** Traffic from any unofficial client can look anomalous to Ford's fraud
|
|
49
|
+
> and abuse detection. **Use at your own risk.**
|
|
50
|
+
|
|
51
|
+
It is **strongly recommended** to use a **separate, secondary FordPass™ account** for this
|
|
52
|
+
software rather than your primary account:
|
|
53
|
+
|
|
54
|
+
1. In the FordPass app on a phone (signed in as the primary owner), invite a secondary email
|
|
55
|
+
address as an additional driver for the vehicle. The invited address must be reachable from
|
|
56
|
+
that phone for verification.
|
|
57
|
+
2. Sign up for a new FordPass account using that secondary email and accept the driver
|
|
58
|
+
invitation.
|
|
59
|
+
3. Configure `pyfordpass` (`fordpass auth login`) with the secondary account's credentials.
|
|
60
|
+
|
|
61
|
+
If the secondary account is later suspended, your primary account, warranty records, and
|
|
62
|
+
roadside-assistance enrolment remain unaffected.
|
|
63
|
+
|
|
64
|
+
See the [ha-fordpass project's general disclaimer and account-setup
|
|
65
|
+
guidance](https://github.com/marq24/ha-fordpass#general-disclaimer) for the same procedure
|
|
66
|
+
written up from the Home Assistant integration's perspective - the steps are identical
|
|
67
|
+
regardless of which third-party client consumes the credentials.
|
|
68
|
+
|
|
69
|
+
## Installation
|
|
70
|
+
|
|
71
|
+
```shell
|
|
72
|
+
pip install pyfordpass
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
Add `-d` to show debug logs. Run with no arguments to see the top-level command list:
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
fordpass
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
A typical first-time flow:
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
fordpass auth login # Interactive sign-in against the secondary account.
|
|
87
|
+
fordpass vehicle list # See what's in the garage.
|
|
88
|
+
fordpass vehicle show VIN # Detailed view for one vehicle.
|
|
89
|
+
fordpass remote start VIN # Remote-start command.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Every subcommand supports `--help` and most data-returning subcommands support `--json` for
|
|
93
|
+
machine-readable output.
|
|
94
|
+
|
|
95
|
+
## Configuration
|
|
96
|
+
|
|
97
|
+
`pyfordpass` has two sets of optional settings, each managed with its own subcommand rather than
|
|
98
|
+
by editing files by hand. Both live under `~/.config/pyfordpass` on Linux (the platform-specific
|
|
99
|
+
equivalent elsewhere).
|
|
100
|
+
|
|
101
|
+
**User preferences** are managed with `fordpass config`. The most useful is a default VIN, so you
|
|
102
|
+
need not pass it to every command:
|
|
103
|
+
|
|
104
|
+
```shell
|
|
105
|
+
# Set a default VIN, used whenever a command's VIN argument is omitted.
|
|
106
|
+
fordpass config set vehicle.default_vin VIN
|
|
107
|
+
# Distance ("mi"/"km") and temperature ("F"/"C"); both default from your locale.
|
|
108
|
+
fordpass config set units.distance mi
|
|
109
|
+
fordpass config set units.temperature C
|
|
110
|
+
# Default output format: "pretty" (Rich tables) or "json".
|
|
111
|
+
fordpass config set output.format json
|
|
112
|
+
# Show the effective configuration (defaults included), drop a key, or start over.
|
|
113
|
+
fordpass config dump
|
|
114
|
+
fordpass config delete units.distance
|
|
115
|
+
fordpass config reset
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**API constants** are managed with `fordpass api-config`. The built-in defaults target Ford in the
|
|
119
|
+
USA, so most users never need to touch them. When Ford rotates a host or client ID you can patch
|
|
120
|
+
individual values without waiting for a new release; anything you set is merged over the defaults,
|
|
121
|
+
so only the changed keys are required:
|
|
122
|
+
|
|
123
|
+
```shell
|
|
124
|
+
# Override a single value; everything else falls back to the built-in defaults.
|
|
125
|
+
fordpass api-config set hosts.login https://login.ford.com
|
|
126
|
+
# Show the effective constants (defaults merged with overrides), or discard all overrides.
|
|
127
|
+
fordpass api-config dump
|
|
128
|
+
fordpass api-config reset
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Values for other regions and for Lincoln can be copied from
|
|
132
|
+
[ha-fordpass `const.py`](https://github.com/marq24/ha-fordpass/blob/main/custom_components/fordpass/const.py).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
FordPass client.
|
|
3
|
+
|
|
4
|
+
Public surface:
|
|
5
|
+
|
|
6
|
+
- :class:`fordpass.sansio.FordPassClient` - sans-I/O protocol core that builds
|
|
7
|
+
:class:`fordpass.sansio.RequestDict` descriptors.
|
|
8
|
+
- :class:`fordpass.client.AsyncFordPassClient` - fully-async niquests wrapper.
|
|
9
|
+
- ``fordpass`` command-line tool exposed via :mod:`fordpass.commands`.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from .client import AsyncFordPassClient
|
|
14
|
+
from .sansio import FordPassClient, RequestDict
|
|
15
|
+
|
|
16
|
+
__all__ = ('AsyncFordPassClient', 'FordPassClient', 'RequestDict')
|
|
17
|
+
__version__ = '0.0.1'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Loader for FordPass API constants."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from collections.abc import Mapping
|
|
5
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
6
|
+
import copy
|
|
7
|
+
import functools
|
|
8
|
+
|
|
9
|
+
from fordpass.config import CONFIG_DIR
|
|
10
|
+
import tomlkit
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .typing.api_config import APIConfig
|
|
14
|
+
|
|
15
|
+
__all__ = ('API_CONFIG_FILE', 'DEFAULT_API_CONFIG', 'load_api_config')
|
|
16
|
+
|
|
17
|
+
API_CONFIG_FILE = CONFIG_DIR / 'api.toml'
|
|
18
|
+
"""
|
|
19
|
+
Path to the optional constants-override TOML file.
|
|
20
|
+
|
|
21
|
+
When present, its contents are merged over :data:`DEFAULT_API_CONFIG`, letting a user patch
|
|
22
|
+
individual values (for example a rotated host or client ID) without waiting for a new release.
|
|
23
|
+
|
|
24
|
+
:meta hide-value:
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
DEFAULT_API_CONFIG: APIConfig = {
|
|
28
|
+
'application_id': 'BFE8C5ED-D687-4C19-A5DD-F92CDFC4503A',
|
|
29
|
+
'user_agent': 'okhttp/4.12.0',
|
|
30
|
+
'profile_groups_default': ('names,address,phoneNumbers,emails,country,languages,'
|
|
31
|
+
'unitsOfMeasure,namesExtensions'),
|
|
32
|
+
'hosts': {
|
|
33
|
+
'foundational': 'https://api.foundational.ford.com',
|
|
34
|
+
'login': 'https://login.ford.com',
|
|
35
|
+
'tmc': 'https://api.autonomic.ai',
|
|
36
|
+
'tmc_accounts': 'https://accounts.autonomic.ai',
|
|
37
|
+
'vehicle': 'https://api.vehicle.ford.com'
|
|
38
|
+
},
|
|
39
|
+
'auth': {
|
|
40
|
+
'b2c': {
|
|
41
|
+
'client_id': '09852200-05fd-41f6-8c21-d36d3497dc64',
|
|
42
|
+
'policy_template': 'B2C_1A_SignInSignUp_{locale}',
|
|
43
|
+
'redirect_uri': 'fordapp://userauthorized',
|
|
44
|
+
'tenant_id': '4566605f-43a7-400a-946e-89cc9fdb0bd7'
|
|
45
|
+
},
|
|
46
|
+
'tmc': {
|
|
47
|
+
'client_id': 'fordpass-prod'
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
'roadside': {
|
|
51
|
+
'x_source': {
|
|
52
|
+
'ford': 'FORD',
|
|
53
|
+
'lincoln': 'LINCOLN'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
"""
|
|
58
|
+
Built-in FordPass API constants captured from the official mobile app.
|
|
59
|
+
|
|
60
|
+
These serve as the default bundle when :data:`API_CONFIG_FILE` is absent.
|
|
61
|
+
|
|
62
|
+
:meta hide-value:
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _merge_into(base: dict[str, Any], override: Mapping[str, Any]) -> None:
|
|
67
|
+
"""
|
|
68
|
+
Recursively overlay ``override`` onto ``base`` in place.
|
|
69
|
+
|
|
70
|
+
Nested mappings are merged key by key; any other value (scalar, list, ...) replaces the value in
|
|
71
|
+
``base`` wholesale.
|
|
72
|
+
|
|
73
|
+
Parameters
|
|
74
|
+
----------
|
|
75
|
+
base : dict[str, Any]
|
|
76
|
+
The mapping to mutate. Typically a deep copy of :data:`DEFAULT_API_CONFIG`.
|
|
77
|
+
override : Mapping[str, Any]
|
|
78
|
+
The values to layer on top, such as a parsed override file.
|
|
79
|
+
"""
|
|
80
|
+
for key, value in override.items():
|
|
81
|
+
existing = base.get(key)
|
|
82
|
+
if isinstance(existing, dict) and isinstance(value, Mapping):
|
|
83
|
+
_merge_into(existing, value)
|
|
84
|
+
else:
|
|
85
|
+
base[key] = value
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@functools.cache
|
|
89
|
+
def load_api_config() -> APIConfig:
|
|
90
|
+
"""
|
|
91
|
+
Return the FordPass API constants, merging any override file over the defaults.
|
|
92
|
+
|
|
93
|
+
The result starts from a copy of :data:`DEFAULT_API_CONFIG`. When :data:`API_CONFIG_FILE`
|
|
94
|
+
exists, its parsed contents are deep-merged on top, so an override may patch as few or as many
|
|
95
|
+
values as it likes.
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
APIConfig
|
|
100
|
+
The effective constants bundle.
|
|
101
|
+
"""
|
|
102
|
+
merged = cast('dict[str, Any]', copy.deepcopy(DEFAULT_API_CONFIG))
|
|
103
|
+
if API_CONFIG_FILE.exists():
|
|
104
|
+
_merge_into(merged, tomlkit.loads(API_CONFIG_FILE.read_text()).unwrap())
|
|
105
|
+
return cast('APIConfig', merged)
|