Initial commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python
|
||||
"""Log in to the West Wood Club (PerfectGym) API and print the bearer token.
|
||||
|
||||
The token is written to stdout (and nothing else), so it can be piped to a file:
|
||||
|
||||
python login.py > token.txt
|
||||
|
||||
Credentials are read from the WESTWOOD_EMAIL and WESTWOOD_PASSWORD environment
|
||||
variables; any that are missing are prompted for on the terminal. Prompts and
|
||||
errors go to stderr, keeping stdout clean for the token.
|
||||
"""
|
||||
|
||||
import getpass
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
BASE_URL = "https://goapi2.perfectgym.com"
|
||||
WHITE_LABEL_ID = "7d073db5-0ef8-4d78-89ec-4a8bebaf4cbc"
|
||||
USER_AGENT = (
|
||||
"West Wood Club/1.28.3.0 "
|
||||
"(com.perfectgym.perfectgymgo2.westwoodclub; build:1028003000; Android 16)"
|
||||
)
|
||||
|
||||
|
||||
def log_in(email: str, password: str) -> str:
|
||||
"""Return the bearer token (the value for the Authorization header)."""
|
||||
body = json.dumps(
|
||||
{
|
||||
"email": email,
|
||||
"password": password,
|
||||
"clientApplicationInfo": {
|
||||
"type": "whitelabel",
|
||||
"whiteLabelId": WHITE_LABEL_ID,
|
||||
},
|
||||
}
|
||||
).encode()
|
||||
|
||||
request = urllib.request.Request(
|
||||
f"{BASE_URL}/v1/Authorize/LogInWithEmail",
|
||||
data=body,
|
||||
method="POST",
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json; charset=UTF-8",
|
||||
"Accept-Language": "en",
|
||||
"X-Go-App-Platform": "Android",
|
||||
"X-Go-App-Version": "1.28.3",
|
||||
"X-Go-White-Label-ID": WHITE_LABEL_ID,
|
||||
"User-Agent": USER_AGENT,
|
||||
},
|
||||
)
|
||||
|
||||
with urllib.request.urlopen(request) as response:
|
||||
payload = json.load(response)
|
||||
|
||||
if payload.get("errors"):
|
||||
raise SystemExit(f"login failed: {payload['errors']}")
|
||||
|
||||
data = payload.get("data") or {}
|
||||
token = data.get("token")
|
||||
if not token:
|
||||
raise SystemExit(f"no token in response: {payload}")
|
||||
return token
|
||||
|
||||
|
||||
def main() -> None:
|
||||
email = os.environ.get("WESTWOOD_EMAIL") or input("Email: ")
|
||||
password = os.environ.get("WESTWOOD_PASSWORD") or getpass.getpass("Password: ")
|
||||
|
||||
try:
|
||||
token = log_in(email, password)
|
||||
except urllib.error.HTTPError as exc:
|
||||
raise SystemExit(f"HTTP {exc.code}: {exc.read().decode('utf-8', 'replace')}")
|
||||
except urllib.error.URLError as exc:
|
||||
raise SystemExit(f"request failed: {exc.reason}")
|
||||
|
||||
print(token)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user