@@ -904,94 +904,16 @@ from comdirect_client.exceptions import (
904904
905905```
906906ComdirectAPIError (base)
907- ├── AuthenticationError # 401 Unauthorized
908- ├── ValidationError # 422 Unprocessable Entity
909- ├── ServerError # 500 Internal Server Error
910- ├── AccountNotFoundError # 404 Not Found
907+ ├── AuthenticationError
908+ ├── ValidationError
909+ ├── ServerError
910+ ├── AccountNotFoundError
911911├── TANTimeoutError
912912├── SessionActivationError
913913├── TokenExpiredError
914914└── NetworkTimeoutError
915915```
916916
917- ### Error Handling Example
918-
919- ``` python
920- import asyncio
921- from comdirect_client.client import ComdirectClient
922- from comdirect_client.exceptions import (
923- AuthenticationError,
924- ValidationError,
925- ServerError,
926- TANTimeoutError,
927- TokenExpiredError,
928- AccountNotFoundError,
929- NetworkTimeoutError,
930- )
931-
932-
933- async def main ():
934- client = ComdirectClient(... )
935-
936- try :
937- # Authenticate
938- await client.authenticate()
939-
940- except AuthenticationError as e:
941- print (f " Invalid credentials: { e} " )
942- # Check username/password, client_id/client_secret
943-
944- except TANTimeoutError as e:
945- print (f " TAN approval timeout: { e} " )
946- # User didn't approve TAN within 60 seconds
947- # Retry authentication flow
948-
949- except NetworkTimeoutError as e:
950- print (f " Network timeout: { e} " )
951- # Check internet connection, retry later
952-
953- try :
954- # Fetch data
955- balances = await client.get_account_balances()
956-
957- except ValidationError as e:
958- print (f " Invalid request parameters: { e} " )
959- # Check query parameter values
960-
961- except ServerError as e:
962- print (f " Server error: { e} " )
963- # Retry later - server-side issue
964-
965- except TokenExpiredError as e:
966- print (f " Token expired: { e} " )
967- # Automatic refresh failed, reauthentication needed
968- await client.authenticate()
969-
970- except AccountNotFoundError as e:
971- print (f " Account not found: { e} " )
972- # Invalid account UUID provided
973-
974- except ServerError as e:
975- print (f " Server error: { e} " )
976- # API returned 500 error
977-
978-
979- if __name__ == " __main__" :
980- asyncio.run(main())
981- ```
982-
983- ### ServerError Details
984-
985- The ` ServerError ` exception is raised when the API returns a 500 Internal Server Error:
986-
987- ``` python
988- try :
989- balances = await client.get_account_balances()
990- except ServerError as e:
991- print (f " Server error: { e} " )
992- # Handle server error - consider retrying later
993- ```
994-
995917---
996918
997919## Logging
@@ -1023,130 +945,12 @@ logger.setLevel(logging.DEBUG) # Set DEBUG for detailed logs
1023945| ** WARNING** | Recoverable issues | ` Token refresh failed - token expired ` |
1024946| ** ERROR** | Critical failures | ` Authentication failed: Invalid credentials ` |
1025947
1026- ### Example Log Output
1027-
1028- ```
1029- INFO: Starting authentication flow
1030- DEBUG: Step 1: Obtaining OAuth2 password credentials token
1031- INFO: OAuth2 token obtained: 1a2b3c4d...
1032- DEBUG: Step 2: Retrieving session status
1033- INFO: Session UUID retrieved: abcd1234...
1034- DEBUG: Step 3: Creating TAN challenge
1035- INFO: TAN challenge created - Type: P_TAN_PUSH, ID: challenge123
1036- INFO: Step 4: Polling for TAN approval (P_TAN_PUSH)
1037- DEBUG: Polling TAN status
1038- DEBUG: TAN approval pending, continuing poll
1039- INFO: TAN approved via P_TAN_PUSH
1040- DEBUG: Step 4b: Activating session
1041- INFO: Session activated successfully
1042- DEBUG: Step 5: Exchanging for secondary token
1043- INFO: Secondary token obtained: xyz789..., expires in 599s
1044- INFO: Authentication successful
1045- INFO: Token refresh task started
1046- DEBUG: Next token refresh in 479s
1047- ```
1048-
1049- ### Sensitive Data Sanitization
1050-
1051- ** Automatic sanitization of:**
1052-
1053- - Access tokens (only first 8 characters shown)
1054- - Refresh tokens (sanitized)
1055- - Passwords (never logged)
1056- - Session IDs (sanitized)
1057-
1058- ``` python
1059- # Logged as:
1060- " OAuth2 token obtained: 1a2b3c4d..." # Only prefix shown
1061- " Session UUID retrieved: abcd1234..." # Sanitized
1062-
1063- # Never logged in full:
1064- - self ._password
1065- - Complete tokens
1066- ```
1067-
1068948---
1069949
1070- ## Security Notes
1071-
1072- ### Credential Management
1073-
1074- ** ❌ Never commit credentials to version control:**
1075-
1076- ``` bash
1077- # Add to .gitignore
1078- .env
1079- * .env
1080- credentials.json
1081- ```
1082-
1083- ** ✅ Use environment variables or secure vaults:**
1084-
1085- ``` python
1086- import os
1087-
1088- client = ComdirectClient(
1089- client_id = os.getenv(" COMDIRECT_CLIENT_ID" ),
1090- client_secret = os.getenv(" COMDIRECT_CLIENT_SECRET" ),
1091- username = os.getenv(" COMDIRECT_USERNAME" ),
1092- password = os.getenv(" COMDIRECT_PASSWORD" ),
1093- )
1094- ```
1095-
1096- ** ✅ Production considerations:**
1097-
1098- - Use AWS Secrets Manager, HashiCorp Vault, or similar
1099- - Encrypt credentials at rest
1100- - Rotate credentials regularly
1101- - Use least-privilege principle
1102-
1103- ### Token Security
1104-
1105- - Tokens are automatically sanitized in logs
1106- - Tokens stored only in memory (not persisted to disk)
1107- - Use HTTPS for all API calls (enforced by default)
1108- - Consider implementing token persistence with encryption
1109-
1110- ### API Security
1111-
1112- - TAN (Two-Factor Authentication) required for all sessions
1113- - Supports Push-TAN, Photo-TAN, SMS-TAN
1114- - Session timeout enforced by Comdirect API
1115- - Rate limiting protection built-in
1116-
1117- ---
1118-
1119- ## Additional Resources
1120-
1121- ### Official Documentation
1122-
1123- - [ Comdirect Developer Portal] ( https://entwickler.comdirect.de )
1124- - [ API Reference] ( https://entwickler.comdirect.de/content/howto/api-uebersicht )
1125- - [ OAuth2 Documentation] ( https://oauth.net/2/ )
1126-
1127- ### Project Documentation
1128-
1129- - ** ` comdirect_api.feature ` ** - Gherkin BDD specification (39 scenarios)
1130- - ** ` examples/basic_usage.py ` ** - Complete working example
1131-
1132- ### Requirements
1133-
1134- - Python 3.9+
1135- - httpx (async HTTP client)
1136- - pydantic (data validation)
1137-
1138- ### License
950+ ## License
1139951
1140952MIT License - see LICENSE file for details
1141953
1142- ### Support
1143-
1144- For issues, questions, or contributions:
1145-
1146- - Open an issue on GitHub
1147- - Refer to the Gherkin specification (` comdirect_api.feature ` ) for behavior details
1148- - Check the example scripts in ` examples/ `
1149-
1150- ### Disclaimer
954+ ## Disclaimer
1151955
1152956This is an unofficial client library. Use at your own risk. The authors are not affiliated with Comdirect Bank AG.
0 commit comments