class TokenAuthenticationTest(TestCase): """ Tests the behaviour of the TokenAuthentication implementation. """ def setUp(self): self.auth = TokenAuthentication() def test_initial_state(self): self.assertFalse( self.auth.is_ready(), "Initially the authentication backend should not be ready.") def test_set_token(self): self.auth.set_token('test_token') self.assertEqual(self.auth.auth_token, 'test_token', "The token was changed by the implementation.") self.assertTrue( self.auth.is_ready(), "The authentication backend should be ready when a token is set.") def test_session(self): self.auth.set_token('test_token') session = self.auth.get_session().headers self.assertEqual( session['Authorization'], 'Bearer test_token', "The implementation did not generate a proper HTTP Authorization header from the token.", )
class TokenAuthenticationTest(TestCase): """ Tests the behaviour of the TokenAuthentication implementation. """ def setUp(self): self.auth = TokenAuthentication() def test_initial_state(self): self.assertFalse(self.auth.is_ready(), "Initially the authentication backend should not be ready.") def test_set_token(self): self.auth.set_token('test_token') self.assertEqual(self.auth.auth_token, 'test_token', "The token was changed by the implementation.") self.assertTrue(self.auth.is_ready(), "The authentication backend should be ready when a token is set.") def test_session(self): self.auth.set_token('test_token') session = self.auth.get_session().headers self.assertEqual( session['Authorization'], 'Bearer test_token', "The implementation did not generate a proper HTTP Authorization header from the token.", )
from moneybird import MoneyBird, TokenAuthentication import logging logger = logging.getLogger('moneybird') moneybird = MoneyBird( TokenAuthentication( 'fc249145ec8fd04e167e3e2c80ad04123e883267219925ac5847abb6a027d03d')) moneybird.get('administrations') administrations = moneybird.get('administrations') for administration in administrations: id = administration['id'] contacts = moneybird.get('contacts', administration_id=id) # Print invoices per contact for contact in contacts: print(contact['company_name']) for invoice in moneybird.get('sales_invoices?filter=contact_id:%s' % contact['id'], administration_id=id): print(' ', invoice['invoice_id']) contacts = moneybird.get('contacts', administration_id=id) print(contacts)
def setUp(self): self.auth = TokenAuthentication()
def setUp(self): self.auth = TokenAuthentication(TEST_TOKEN) self.api = MoneyBird(self.auth)
class MoneyBirdAPITalker: _logger = logging.getLogger("django.moneybird") _token = settings.MONEYBIRD_API_TOKEN _administration_id = settings.MONEYBIRD_ADMINISTRATION_ID _moneybird = MoneyBird(TokenAuthentication(_token)) @property def moneybird(self): """An Moneybird API instance (can be adapted to support API sessions).""" return self._moneybird @property def administration_id(self): """The administration_id to work with.""" return self._administration_id def sync_objects(self, cls: Type[MoneybirdSynchronizableResourceModel]): """Synchronize all objects of a MoneybirdSynchronizableResourceModel.""" self._logger.info( f"Getting Moneybird {cls.get_moneybird_resource_path_name()} for synchronization" ) data = self.moneybird.get( f"{cls.get_moneybird_resource_path_name()}/synchronization", self.administration_id, ) self._logger.info( f"Moneybird returned {len(data)} {cls.get_moneybird_resource_path_name()}" ) mapped_objects = cls.objects.filter(id__in=[x["id"] for x in data]) if len(mapped_objects) > 0: self._logger.info( f"Mapped {len(mapped_objects)} {cls.get_moneybird_resource_path_name()}: {mapped_objects}" ) to_delete = cls.objects.exclude(id__in=[x["id"] for x in data]) if len(to_delete) > 0: self._logger.info( f"Found {len(to_delete)} {cls.get_moneybird_resource_path_name()} to delete: {to_delete}" ) to_delete.delete() update_or_create = [] for obj_data in data: try: obj = mapped_objects.get(id=obj_data["id"]) except cls.DoesNotExist: self._logger.info( f"Found new {cls.get_moneybird_resource_name()} to create with id {obj_data['id']}" ) update_or_create.append(obj_data["id"]) else: if obj.version != obj_data["version"]: self._logger.info(f"Found {obj} to be updated") update_or_create.append(obj_data["id"]) return self.update_or_create_objects(cls, update_or_create) def update_or_create_objects( self, cls: Type[MoneybirdSynchronizableResourceModel], ids: List[str]): """Update or create Moneybird objects with certain ids.""" chunks = [ids[i:i + 100] for i in range(0, len(ids), 100)] for chunk in chunks: self._logger.info( f"Getting {len(chunk)} Moneybird {cls.get_moneybird_resource_path_name()} by id to sync: {chunk}" ) data = self.moneybird.post( f"{cls.get_moneybird_resource_path_name()}/synchronization", {"ids": chunk}, self.administration_id, ) self._logger.info( f"Moneybird returned {len(data)} {cls.get_moneybird_resource_path_name()} to create or update: {data}" ) for object_data in data: self.update_or_create_object(cls, object_data) return cls.objects.filter(id__in=ids) def update_or_create_object( self, cls: Type[MoneybirdSynchronizableResourceModel], data: Dict[str, Any]): """Update or create a MoneybirdSynchronizableResourceModel object from JSON-like dict values.""" filtered = dict([(i, data[i]) for i in data if i in cls.get_moneybird_fields()]) self._logger.info( f"Updating or creating {cls.get_moneybird_resource_path_name()} {data['id']}: {filtered}" ) obj = cls(id=data["id"]).set_moneybird_resource_data(filtered) obj.processed = True # Prevent save() triggering a callback to Moneybird obj.save() return obj def create_moneybird_resource( self, cls: Type[MoneybirdSynchronizableResourceModel], data: Dict[str, Any]): """Create a new resource on Moneybird.""" data_filtered = dict([(x, data[x]) for x in data if x not in cls.get_moneybird_readonly_fields()]) try: self._logger.info( f"Creating Moneybird {cls.get_moneybird_resource_path_name()} {id}: {data_filtered}" ) reply = self.moneybird.post( cls.get_moneybird_resource_path_name(), {cls.get_moneybird_resource_name(): data_filtered}, self.administration_id, ) self._logger.info( f"Moneybird returned {cls.get_moneybird_resource_name()}: {reply}" ) return reply except moneybird.api.MoneyBird.InvalidData as e: raise MoneyBirdSynchronizationError(e.response["error"]) def patch_moneybird_resource( self, cls: Type[MoneybirdSynchronizableResourceModel], id: str, data: Dict[str, Any], ): """Patch an existing Moneybird resource.""" data_filtered = dict([(x, data[x]) for x in data if x not in cls.get_moneybird_readonly_fields()]) try: self._logger.info( f"Patching Moneybird {cls.get_moneybird_resource_path_name()} {id}: {data_filtered}" ) reply = self.moneybird.patch( f"{cls.get_moneybird_resource_path_name()}/{id}", {cls.get_moneybird_resource_name(): data_filtered}, self.administration_id, ) self._logger.info( f"Moneybird returned {cls.get_moneybird_resource_name()}: {reply}" ) return reply except moneybird.api.MoneyBird.InvalidData as e: raise MoneyBirdSynchronizationError(e.response["error"]) def delete_moneybird_resource( self, cls: Type[MoneybirdSynchronizableResourceModel], id: str): """Delete an existing Moneybird resource.""" try: self._logger.info( f"Deleting Moneybird {cls.get_moneybird_resource_path_name()} {id}" ) return self.moneybird.delete( f"{cls.get_moneybird_resource_path_name()}/{id}", self.administration_id, ) except moneybird.api.MoneyBird.APIError as e: if e.status_code == 204: pass else: raise MoneyBirdSynchronizationError(e.response)