Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions pytr/accountdetails.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from typing import TypedDict, Optional, List
from typing import cast

class Name(TypedDict):
first: str
last: str

class Email(TypedDict):
address: str
verified: bool

class PostalAddress(TypedDict):
street: str
houseNo: str
zip: str
city: str
country: str

class Birthplace(TypedDict):
birthplace: str
birthcountry: str

class TaxResidency(TypedDict):
tin: str
countryCode: str

class TaxExemptionOrder(TypedDict):
minimum: int
maximum: int
current: int
applied: int
syncStatus: int
validFrom: int
validUntil: int

class CashAccount(TypedDict):
iban: str
bic: str
bankName: str
logoUrl: Optional[str]

class ReferenceAccount(TypedDict):
iban: str
bic: Optional[str]
bankName: Optional[str]
logoUrl: Optional[str]

class Experience(TypedDict):
tradeCount: int
level: str
showsRiskWarning: bool

class InvestmentExperience(TypedDict):
stock: Experience
fund: Experience
derivative: Experience
crypto: Experience
bond: Experience

class SupportDocuments(TypedDict):
accountClosing: str
imprint: str
addressConfirmation: str

class TinFormat(TypedDict):
placeholder: str
keyboardLayout: str

class AccountDetails(TypedDict):
phoneNumber: str
jurisdiction: str
name: Name
email: Email
duplicateTradingEmail: Optional[str]
postalAddress: PostalAddress
birthdate: str
birthplace: Birthplace
mainNationality: str
additionalNationalities: List[str]
mainTaxResidency: TaxResidency
usTaxResidency: bool
additionalTaxResidencies: List[TaxResidency]
taxInformationSyncTimestamp: int
taxExemptionOrder: TaxExemptionOrder
registrationAccount: bool
cashAccount: CashAccount
referenceAccount: ReferenceAccount
referenceAccountV2: Optional[str]
referenceAccountList: List[ReferenceAccount]
securitiesAccountNumber: str
experience: InvestmentExperience
referralDetails: Optional[str]
supportDocuments: SupportDocuments
tinFormat: TinFormat
personId: str

def from_dict(d):
account_details: AccountDetails = cast(AccountDetails, d)
return account_details
7 changes: 7 additions & 0 deletions pytr/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,13 @@ def resume_websession(self):
return True
return False

def get_account_details(self):
r = self._websession.get(
f"{self._host}/api/v2/auth/account",
)
j = r.json()
return j

def _web_request(self, url_path, payload=None, method="GET"):
if self._web_session_token_expires_at < time.time():
r = self._websession.get(f"{self._host}/api/v1/auth/web/session")
Expand Down
24 changes: 23 additions & 1 deletion pytr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse
import asyncio
import signal
import json
from datetime import datetime, timedelta
from importlib.metadata import version
from pathlib import Path
Expand Down Expand Up @@ -198,7 +199,24 @@ def formatter(prog):
help="Format the date column in ISO8601 including the time.",
action="store_true",
)

# accountdetails
info = "Show account details"
parser_accountdetails = parser_cmd.add_parser(
"accountdetails",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
parents=[parser_login_args],
help=info,
description=info,
)
parser_accountdetails.add_argument(
"-o",
"--outfile",
help='Output path of JSON file. [default: "-" (stdout)]',
metavar="PATH",
type=argparse.FileType("w"),
default="-",
)
# completion
info = "Print shell tab completion"
parser_completion = parser_cmd.add_parser(
"completion",
Expand Down Expand Up @@ -310,6 +328,10 @@ def main():
installed_version = version("pytr")
print(installed_version)
check_version(installed_version)
elif args.command == "accountdetails":
tr = login(phone_no=args.phone_no, pin=args.pin, web=not args.applogin)
account_details = tr.get_account_details()
args.jsonoutput.write(json.dumps(account_details))
else:
parser.print_help()

Expand Down
37 changes: 37 additions & 0 deletions tests/sample_account_details.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"phoneNumber":"+491xxxx",
"jurisdiction":"DE",
"name":{"first":"xxfirstnamexx", "last":"xxx"},
"email":{"address":"xxxx@xxxx.de", "verified":true},
"duplicateTradingEmail":null,
"postalAddress":{"street":"SomeStreet", "houseNo":"4", "zip":"123456", "city":"Somecity", "country":"DE"},
"birthdate":"1902-01-01",
"birthplace":{"birthplace":"Somecity", "birthcountry":"DE"},
"mainNationality":"DE",
"additionalNationalities":[],
"mainTaxResidency":{"tin":"12345987", "countryCode":"DE"},
"usTaxResidency":false,
"additionalTaxResidencies":[],
"taxInformationSyncTimestamp":172177300000,
"taxExemptionOrder":{"minimum":0, "maximum":9900, "current":111, "applied":2131, "syncStatus":12414, "validFrom":1242, "validUntil":2312},
"registrationAccount":false,
"cashAccount":{"iban":"DE00000000000000000000", "bic":"TRBKDEBBXXX", "bankName":"J.P. Morgan SE", "logoUrl":null},
"referenceAccount":{"iban":"-", "bic":null},
"referenceAccountV2":null,
"referenceAccountList":[{"iban":"DE00012134874564878747", "bic":null, "bankName":"Bank", "logoUrl":"logos/bank_bank/v2"}],
"securitiesAccountNumber":"321354657",
"experience":{"stock":{"tradeCount":0, "level":"LOSER", "showsRiskWarning":true},
"fund":{"tradeCount":0, "level":"LOSER", "showsRiskWarning":true},
"derivative":{"tradeCount":0, "level":"LOSER", "showsRiskWarning":true},
"crypto":{"tradeCount":100, "level":"GODMODE", "showsRiskWarning":true},
"bond":{"level":"xxxx", "showsRiskWarning":true}},
"referralDetails":null,
"supportDocuments":{
"accountClosing":"https://assets.traderepublic.com/assets/files/foilename.pdf",
"imprint":"https://traderepublic.com/de-de/imprint",
"addressConfirmation":"https://support.traderepublic.com/de-de/102"},
"tinFormat":{"placeholder":"99999999999",
"keyboardLayout":"numerical"
},
"personId":"babdbddb-5441-23-124-423423542532112"
}
17 changes: 17 additions & 0 deletions tests/test_account_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import json

from pytr.accountdetails import AccountDetails


def test_account_details_from_dict():
# Load the sample JSON file
with open("tests/sample_account_details.json", "r") as file:
sample_data = json.load(file)

# Parse the JSON data using the from_dict function
ad = AccountDetails.from_dict(sample_data)

# Assert the expected values
assert ad["phoneNumber"] == "+491xxxx"
assert ad["name"]["first"] == "xxfirstnamexx"
assert ad["taxExemptionOrder"]["current"] == 111
Loading