def setup_context(self, reset_config_if_needed=True): if isfile(self.conf): self._BUNQ_CONF_CUSTOM = self.conf pass # Config is already present elif isfile(self.determine_bunq_conf_filename()): pass # Config is already present elif self.env == ApiEnvironmentType.SANDBOX: sandbox_user = self.generate_new_sandbox_user() ApiContext.create(ApiEnvironmentType.SANDBOX, sandbox_user.api_key, socket.gethostname()).save( self.determine_bunq_conf_filename()) else: raise BunqException(self._ERROR_COULD_NOT_DETIRMINE_CONF) try: api_context = ApiContext.restore( self.determine_bunq_conf_filename()) api_context.ensure_session_active() api_context.save(self.determine_bunq_conf_filename()) BunqContext.load_api_context(api_context) except ForbiddenException as forbidden_exception: if reset_config_if_needed: self.__handle_forbidden_exception(forbidden_exception) else: raise forbidden_exception
def _request(self, method: str, uri_relative: str, request_bytes: bytes, params: Dict[str, str], custom_headers: Dict[str, str]) -> BunqResponseRaw: from bunq.sdk.context.bunq_context import BunqContext uri_relative_with_params = self._append_params_to_uri( uri_relative, params) if uri_relative not in self._URIS_NOT_REQUIRING_ACTIVE_SESSION: if self._api_context.ensure_session_active(): BunqContext.update_api_context(self._api_context) all_headers = self._get_all_headers(request_bytes, custom_headers) response = requests.request( method, self._get_uri_full(uri_relative_with_params), data=request_bytes, headers=all_headers, proxies={self.FIELD_PROXY_HTTPS: self._api_context.proxy_url}, ) self._assert_response_success(response) if self._api_context.installation_context is not None: security.validate_response( self._api_context.installation_context.public_key_server, response.status_code, response.content, response.headers) return self._create_bunq_response_raw(response)
def test_bad_request_with_response_id(self): """ """ BunqContext.load_api_context(self._get_api_context()) with self.assertRaises(ApiException) as caught_exception: MonetaryAccountBank.get(self._INVALID_MONETARY_ACCOUNT_ID) self.assertIsNotNone(caught_exception.exception.response_id)
def setUpClass(cls): cls._PAYMENT_LISTING_PAGE_SIZE = 2 cls._PAYMENT_REQUIRED_COUNT_MINIMUM = cls._PAYMENT_LISTING_PAGE_SIZE * 2 cls._NUMBER_ZERO = 0 cls._PAYMENT_AMOUNT_EUR = '0.01' cls._PAYMENT_CURRENCY = 'EUR' cls._PAYMENT_DESCRIPTION = 'Python test Payment' BunqContext.load_api_context(cls._get_api_context())
def setup_test_data(cls) -> None: if not os.path.isfile(cls._FILE_TEST_CONFIGURATION_PATH_FULL): try: BunqContext.load_api_context(cls._create_api_context()) except FileNotFoundError: return api_context = ApiContext.restore( cls._FILE_TEST_CONFIGURATION_PATH_FULL) BunqContext.load_api_context(api_context)
def alias_first(self) -> Pointer: if BunqContext.user_context().is_only_user_company_set(): return BunqContext.user_context().user_company.alias[ self._FIRST_INDEX] if BunqContext.user_context().is_only_user_person_set(): return BunqContext.user_context().user_person.alias[ self._FIRST_INDEX] raise BunqException(self.__ERROR_COULD_NOT_DETERMINE_USER)
def test_create_psd2_context(self) -> None: if os.path.isfile(self._FILE_TEST_CONFIGURATION_PATH_FULL): return try: api_context = self._create_api_context() BunqContext.load_api_context(api_context) self.assertTrue( os.path.isfile(self._FILE_TEST_CONFIGURATION_PATH_FULL)) except AssertionError: raise AssertionError
def test_auto_bunq_context_update(self): """ Tests the auto update of BunqContext. """ api_context: ApiContext = BunqContext.api_context() api_context_json: object = json.loads(api_context.to_json()) api_context_json[self.__FIELD_SESSION_CONTEXT][ self.__FIELD_EXPIRE_TIME] = self.__TIME_STAMP_IN_PAST expired_api_context = ApiContext.from_json( json.dumps(api_context_json)) self.assertNotEqual(api_context.session_context.expiry_time, expired_api_context.session_context.expiry_time) self.assertEqual(BunqContext.api_context().session_context.expiry_time, api_context.session_context.expiry_time) BunqContext.update_api_context(expired_api_context) BunqContext.user_context().refresh_user_context() self.assertNotEqual( BunqContext.api_context().session_context.expiry_time, api_context.session_context.expiry_time) self.assertFalse(BunqContext.api_context().ensure_session_active())
def init(api_key_fn): AnchorObjectAdapter._override_field_map.update({ 'ScheduledPaymentBatch': 'SchedulePaymentBatch', 'TransferwisePayment': 'TransferwiseTransfer', }) if CONTEXTFILE.exists(): context = ApiContext.restore(str(CONTEXTFILE)) else: context = ApiContext.create(ApiEnvironmentType.PRODUCTION, api_key_fn(), DEVICE_DESCRIPTION) context.save(str(CONTEXTFILE)) BunqContext.load_api_context(context)
def setup_context(self): if isfile(self.determine_bunq_conf_filename()): pass # Config is already present elif self.env == ApiEnvironmentType.SANDBOX: sandbox_user = self.generate_new_sandbox_user() ApiContext.create(ApiEnvironmentType.SANDBOX, sandbox_user.api_key, socket.gethostname()).save( self.determine_bunq_conf_filename()) else: raise BunqException(self._ERROR_COULD_NOT_DETIRMINE_CONF) api_context = ApiContext.restore(self.determine_bunq_conf_filename()) api_context.ensure_session_active() api_context.save(self.determine_bunq_conf_filename()) BunqContext.load_api_context(api_context)
def main(ctx, iban: str, api_key: str, sandbox: bool, currency: str): """ \b ____ _ | __ ) _ _ __ _ _ _| |_ | _ \| | | |/ _` | | | | __| | |_) | |_| | (_| | |_| | |_ |____/ \__,_|\__,_|\__,_|\__| Buaut are several Bunq automations in a convenient CLI tool. Enable autocomplete for Bash (.bashrc): eval "$(_BUAUT_COMPLETE=source buaut)" Enable autocomplete for ZSH (.zshrc): eval "$(_BUAUT_COMPLETE=source_zsh buaut)" """ # Set Bunq context context = ApiEnvironmentType.SANDBOX if sandbox \ else ApiEnvironmentType.PRODUCTION # Setup Bunq authentication api_context = ApiContext.create(context, api_key, socket.gethostname()) api_context.ensure_session_active() # Load api context into BunqContext used for subsequent calls BunqContext.load_api_context(api_context) if validators.iban(iban): try: # Set monetary_account monetary_account: int = utils.get_monetary_account( value_type='IBAN', value=iban) except: # TODO: Exit nicely exit(1) else: # TODO: Exit nicely exit(1) # Append to ctx object to have available in commands ctx.obj = {} ctx.obj['args'] = {} ctx.obj['args']['iban'] = iban ctx.obj['args']['api_key'] = api_key ctx.obj['monetary_account'] = monetary_account ctx.obj['currency'] = currency
def setup_context(self): if 'bunq-conf' in self.config.value: LOGGER.debug('Found existing api context config. Restoring.') api_context = ApiContext.from_json(self.config.value['bunq-conf']) api_context.ensure_session_active() else: LOGGER.debug('Did not find existing api context config. creating.') api_context = ApiContext.create( ApiEnvironmentType.PRODUCTION, self.config.value['bunq']['api_token'], self.DEVICE_DESCRIPTION) self.config.value['bunq-conf'] = api_context.to_json() LOGGER.info('persisting new api context config') self.config.save(self.config.value) BunqContext.load_api_context(api_context)
def create(cls, grant_type: OauthGrantType, oauth_code: str, redirect_uri: str, client: OauthClient) -> OauthAccessToken: api_client = AnonymousApiClient(BunqContext.api_context()) response_raw = api_client.post( cls.create_token_uri(grant_type.value, oauth_code, redirect_uri, client), bytearray(), {}) return cls.from_json(OauthAccessToken, response_raw).value
def _determine_monetary_account_id(cls, monetary_account_id: int = None) -> int: from bunq.sdk.context.bunq_context import BunqContext if monetary_account_id is None: return BunqContext.user_context().primary_monetary_account.id_ return monetary_account_id
def test_session_delete(self): """ Tests the deletion and resetting of the current active session This test has no assertion as of its testing to see if the code runs without errors. Notes ----- time.sleep() is needed as of you can only make 1 POST call to Session endpoint per second. """ Session.delete(self._SESSION_ID) time.sleep(2) BunqContext.api_context().reset_session() BunqContext.api_context().save(self._BUNQ_CONFIG_FILE)
def determine_auth_uri_format(cls) -> str: environment_type = BunqContext.api_context().environment_type if ApiEnvironmentType.PRODUCTION == environment_type: return cls.TOKEN_URI_FORMAT_PRODUCTION if ApiEnvironmentType.SANDBOX == environment_type: return cls.TOKEN_URI_FORMAT_SANDBOX raise BunqException(cls.ERROR_ENVIRONMENT_TYPE_NOT_SUPPORTED)
def test_create_and_update_tab(self): """ Tests the creation of a Tab, adds a tab item to it and updates this tab This test has no assertion as of its testing to see if the code runs without errors """ if BunqContext.user_context().is_only_user_person_set(): return unittest.skip(self._ERROR_ONLY_USER_COMPANY_CAN_CREATE_TAB) tab_uuid = TabUsageSingle.create( self._get_cash_register_id(), self._TAB_DESCRIPTION, self._STATUS_OPEN, Amount(self._AMOUNT_EUR, self._CURRENCY)).value self._add_item_to_tab(tab_uuid) self._update_tab(tab_uuid)
def test_order_debit_card(self): """ Tests ordering a new card and checks if the fields we have entered are indeed correct by retrieving the card from the card endpoint and checks this date against the data we have submitted """ second_line = self.second_line_random pin_code_assignment = CardPinAssignment( self._PIN_CODE_ASSIGNMENT_TYPE_PRIMARY, self._CARD_PIN_CODE, BunqContext.user_context().primary_monetary_account.id_) card_debit = CardDebit.create(second_line, self.card_name_allowed, self._CARD_TYPE_MAESTRO, self.alias_first, self._PRODUCT_TYPE_MAESTRO_DEBIT, [pin_code_assignment]).value card = Card.get(card_debit.id_).value self.assertEqual(self.card_name_allowed, card.name_on_card) self.assertEqual(second_line, card.second_line) self.assertEqual(card_debit.created, card.created)
def __should_request_spending_money(self): return self.env == ApiEnvironmentType.SANDBOX \ and float(BunqContext.user_context().primary_monetary_account.balance.value) <= self._ZERO_BALANCE
def update_context(self): BunqContext.api_context().save(self.determine_bunq_conf_filename())
def _get_api_context(cls) -> ApiContext: from bunq.sdk.context.bunq_context import BunqContext return BunqContext.api_context()
def setUp(self): self.__set_second_monetary_account() self.__request_spending_money() time.sleep(self.__TIME_OUT_AUTO_ACCEPT_SPENDING_MONEY) BunqContext.user_context().refresh_user_context()
def _determine_user_id(cls) -> int: from bunq.sdk.context.bunq_context import BunqContext return BunqContext.user_context().user_id
def get_primary_monetary_account(): return BunqContext.user_context().primary_monetary_account
def setUpClass(cls) -> None: BunqContext.load_api_context(cls._get_api_context())