def create_tenant(name): """ Create a tenant via cli, record its id and token for further use. """ cli = CliTenantadm() api = ApiClient(tenantadm.URL_INTERNAL) id = cli.create_tenant(name) page = 0 per_page = 20 qs_params = {} found = None while True: page = page + 1 qs_params['page'] = page qs_params['per_page'] = per_page r = api.call('GET', tenantadm.URL_INTERNAL_TENANTS, qs_params=qs_params) assert r.status_code == 200 api_tenants = r.json() found = [at for at in api_tenants if at['id'] == id] if len(found) > 0: break if len(api_tenants) == 0: break assert len(found) == 1 token = found[0]['tenant_token'] return Tenant(name, id, token)
def get_device_by_id_data(id_data, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) page = 0 per_page = 20 qs_params = {} found = None while True: page = page + 1 qs_params['page'] = page qs_params['per_page'] = per_page r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES, qs_params=qs_params) assert r.status_code == 200 api_devs = r.json() found = [d for d in api_devs if d['identity_data'] == id_data] if len(found) > 0: break if len(api_devs) == 0: break assert len(found) == 1 return found[0]
def test_authenticated_user_is_rejected(self, tenants_users): tc = ApiClient(tenantadm.URL_INTERNAL) uc = ApiClient(useradm.URL_MGMT) dc = ApiClient(deviceauth_v2.URL_MGMT) u = tenants_users[0].users[0] # log in r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 200 token = r.text # check can access an api r = dc.with_auth(token).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 # suspend tenant r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users[0].id}) assert r.status_code == 200 time.sleep(10) # check token is rejected r = dc.with_auth(token).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 401
def create_authset(id_data, pubkey, privkey, utoken, tenant_token=''): api = ApiClient(deviceauth_v1.URL_DEVICES) body, sighdr = deviceauth_v1.auth_req(id_data, pubkey, privkey, tenant_token) # submit auth req r = api.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 # dev must exist and have *this* aset api_dev = get_device_by_id_data(id_data, utoken) assert api_dev is not None aset = [ a for a in api_dev['auth_sets'] if util.crypto.rsa_compare_keys(a['pubkey'], pubkey) ] assert len(aset) == 1 aset = aset[0] assert aset['identity_data'] == id_data assert aset['status'] == 'pending' return Authset(aset['id'], api_dev['id'], id_data, pubkey, privkey, 'pending')
def change_authset_status(did, aid, status, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status(status), path_params={'did': did, 'aid': aid }) assert r.status_code == 204
def test_ok(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 3) # wait for devices to be provisioned time.sleep(3) for i, d in enumerate(devs): payload = [ { "name": "mac", "value": "mac-new-" + str(d.id) }, { #empty value for existing "name": "sn", "value": "", }, { #empty value for new "name": "new-empty", "value": "", } ] r = invd.with_auth(d.token).call('PATCH', inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 200 for d in devs: r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICE, path_params={'id': d.id}) assert r.status_code == 200 api_dev = r.json() assert len(api_dev['attributes']) == 3 for a in api_dev['attributes']: if a['name'] == 'mac': assert a['value'] == 'mac-new-' + str(api_dev['id']) elif a['name'] == 'sn': assert a['value'] == '' elif a['name'] == 'new-empty': assert a['value'] == '' else: assert False, 'unexpected attribute ' + a['name']
def health(): ApiClient.health_test_observable = current_app.config['HEALTH_OBSERVABLE'] client = ApiClient(api_key=get_api_key(), base_url=current_app.config['AUTOFOCUS_API_URL'], user_agent=current_app.config['USER_AGENT']) client.get_tic_indicator_data(current_app.config['HEALTH_OBSERVABLE']) return jsonify_data({'status': 'ok'})
def verify_dev_provisioned(self, dev, utoken): invm = ApiClient(inventory.URL_MGMT) r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json()
def get_device_by_id_data(id_data, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() found = [d for d in api_devs if d['identity_data'] == id_data] assert len(found) == 1 return found[0]
def test_accepted_dev_cant_authenticate(self, tenants_users_devices): dacd = ApiClient(deviceauth.URL_DEVICES) uc = ApiClient(useradm.URL_MGMT) tc = ApiClient(tenantadm.URL_INTERNAL) # accept a dev device = tenants_users_devices[0].devices[0] user = tenants_users_devices[0].users[0] r = uc.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text aset = device.authsets[0] change_authset_status(aset.did, aset.id, 'accepted', utoken) # suspend r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users_devices[0].id}) assert r.status_code == 200 time.sleep(10) # try requesting auth body, sighdr = deviceauth.auth_req( aset.id_data, aset.pubkey, aset.privkey, tenants_users_devices[0].tenant_token) r = dacd.call('POST', deviceauth.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 assert r.json()['error'] == 'Account suspended'
def test_user_cannot_log_in(self, tenants_users): tc = ApiClient(tenantadm.URL_INTERNAL) uc = ApiClient(useradm.URL_MGMT) for u in tenants_users[0].users: r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 200 # tenant's users can log in for u in tenants_users[0].users: r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 200 assert r.status_code == 200 # suspend tenant r = tc.call('PUT', tenantadm.URL_INTERNAL_SUSPEND, tenantadm.req_status('suspended'), path_params={'tid': tenants_users[0].id}) assert r.status_code == 200 time.sleep(10) # none of tenant's users can log in for u in tenants_users[0].users: r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 401 # but other users still can for u in tenants_users[1].users: r = uc.call('POST', useradm.URL_LOGIN, auth=(u.name, u.pwd)) assert r.status_code == 200
def get_context_data(self, **kwargs): context = super(SearchView, self).get_context_data(**kwargs) keyword = self.kwargs['keyword'] try: artists = Artist.objects.filter(name__icontains=keyword).values( 'name', 'slug', 'text', 'picture') except Artist.DoesNotExist: artists = [] try: albums = Album.objects.filter(name__icontains=keyword).values( 'name', 'date', 'picture', 'slug') except Album.DoesNotExist: albums = [] try: songs = Song.objects.filter(title__icontains=keyword).values( 'title', 'filepath', 'slug', 'album__name', 'album__slug', 'artist__slug', 'artist__name', 'style__name', 'style__name', 'album__picture') except Song.DoesNotExist: songs = [] try: playlists = Playlist.objects.filter(name__icontains=keyword) except Playlist.DoesNotExist: playlists = [] remote_instances = RemoteInstance.objects.all() for remote_instance in remote_instances: api_client = ApiClient() search = api_client.search(keyword) try: artists = self.merge_dict(artists, search['artists']) except KeyError: pass try: songs = self.merge_dict(songs, search['songs']) except KeyError: pass try: albums = self.merge_dict(albums, search['albums']) except KeyError: pass context['artists'] = artists context['albums'] = albums context['songs'] = songs context['playlists'] = playlists context['modal_playlists'] = Playlist.objects.all() context['active'] = "search" return context
def get_authset_id(pubkey, utoken): devadmm = ApiClient(deviceadm.URL_MGMT) r = devadmm.with_auth(utoken).call('GET', deviceadm.URL_AUTHSETS) assert r.status_code == 200 api_devs = r.json() api_dev = [ x for x in api_devs if util.crypto.rsa_compare_keys(x['key'], pubkey) ][0] return api_dev['id']
def create_device(id_data, pubkey, privkey, tenant_token=''): """ Simply submit an auth request for a device; it will result in a 'pending' device/authset.""" api = ApiClient(deviceauth_v1.URL_DEVICES) body, sighdr = deviceauth_v1.auth_req(id_data, pubkey, privkey, tenant_token) # submit auth req r = api.call('POST', deviceauth_v1.URL_AUTH_REQS, body, headers=sighdr) assert r.status_code == 401 return Device(id_data, pubkey, privkey, tenant_token)
def get_context_data(self, **kwargs): context = super(SongsView, self).get_context_data(**kwargs) remote_instances = RemoteInstance.objects.all() songs = [] if self.kwargs['type'] == 'album': album = Album.objects.filter(slug=self.kwargs['key']) context['album'] = album songs = Song.objects.filter(album__in=album).values( 'title', 'slug', 'filepath', 'album__slug', 'album__name', 'album__picture', 'artist__name', 'artist__slug', 'style__name', 'style__slug') api_client = ApiClient() remote_songs = api_client.songs(album=self.kwargs['key'], instances=remote_instances) try: songs = self.merge_dict(songs, remote_songs['songs']) except KeyError: pass elif self.kwargs['type'] == 'playlist': playlist = Playlist.objects.get(slug=self.kwargs['key']) context['playlist'] = playlist songs = Song.objects.filter(playlist=playlist).values( 'title', 'slug', 'filepath', 'album__slug', 'album__name', 'album__picture', 'artist__name', 'artist__slug', 'style__name', 'style__slug') elif self.kwargs['type'] == 'artist': artist = Artist.objects.filter(slug=self.kwargs['key']) context['artist'] = artist songs = Song.objects.filter(artist=artist).order_by( 'album__name').values( 'title', 'slug', 'filepath', 'album__slug', 'album__name', 'album__picture', 'artist__name', 'artist__slug', 'style__name', 'style__slug') api_client = ApiClient() remote_songs = api_client.songs(artist=self.kwargs['key'], instances=remote_instances) try: songs = self.merge_dict(songs, remote_songs['songs']) except KeyError: pass context['type'] = self.kwargs['type'] context['songs'] = songs context['active'] = "songs" context['modal_playlists'] = Playlist.objects.all() return context
def make_devs_with_authsets(user, tenant_token=''): """ create a good number of devices, some with >1 authsets, with different statuses. returns DevWithAuthsets objects.""" useradmm = ApiClient(useradm.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text devices = [] # some vanilla 'pending' devices, single authset for _ in range(5): dev = make_pending_device(utoken, 1, tenant_token=tenant_token) devices.append(dev) # some pending devices with > 1 authsets for i in range(2): dev = make_pending_device(utoken, 3, tenant_token=tenant_token) devices.append(dev) # some 'accepted' devices, single authset for _ in range(3): dev = make_accepted_device(utoken, 1, tenant_token=tenant_token) devices.append(dev) # some 'accepted' devices with >1 authsets for _ in range(2): dev = make_accepted_device(utoken, 3, tenant_token=tenant_token) devices.append(dev) # some rejected devices for _ in range(2): dev = make_rejected_device(utoken, 3, tenant_token=tenant_token) devices.append(dev) # preauth'd devices for i in range(2): dev = make_preauthd_device(utoken) devices.append(dev) # preauth'd devices with extra 'pending' sets for i in range(2): dev = make_preauthd_device_with_pending(utoken, num_pending=2, tenant_token=tenant_token) devices.append(dev) return devices
def test_fail_no_attr_value(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 1) # wait for devices to be provisioned time.sleep(3) for i, d in enumerate(devs): payload = [{ "name": "mac", }] r = invd.with_auth(d.token).call('PATCH', inventory.URL_DEVICE_ATTRIBUTES, payload) assert r.status_code == 400
def do_test_get_devices_ok(self, user, tenant_token=''): useradmm = ApiClient(useradm.URL_MGMT) devauthd = ApiClient(deviceauth_v1.URL_DEVICES) invm = ApiClient(inventory.URL_MGMT) invd = ApiClient(inventory.URL_DEV) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # prepare accepted devices devs = make_accepted_devices(utoken, devauthd, 40, tenant_token) # wait for devices to be provisioned time.sleep(3) r = invm.with_auth(utoken).call('GET', inventory.URL_DEVICES, qs_params={'per_page': 100}) assert r.status_code == 200 api_devs = r.json() assert len(api_devs) == 40
def do_test_put_status_failed(self, devs_authsets, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # not found: valid device, bogus authset r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('accepted'), path_params={ 'did': devs_authsets[0].id, 'aid': "foo" }) assert r.status_code == 404 # not found: bogus device r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('accepted'), path_params={ 'did': "foo", 'aid': "bar" }) assert r.status_code == 404 # bad request - invalid status r = devauthm.with_auth(utoken).call( 'PUT', deviceauth_v2.URL_AUTHSET_STATUS, deviceauth_v2.req_status('invalid'), path_params={ 'did': devs_authsets[0].id, 'aid': devs_authsets[0].authsets[0].id }) assert r.status_code == 400 # bad request - invalid payload r = devauthm.with_auth(utoken).call('PUT', deviceauth_v2.URL_AUTHSET_STATUS, '{"foo": "bar"}', path_params={ 'did': devs_authsets[0].id, 'aid': devs_authsets[0].authsets[0].id }) assert r.status_code == 400
def tenants_users_devices(tenants_users, mongo): uc = ApiClient(useradm.URL_MGMT) for t in tenants_users: user = t.users[0] r = uc.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text for _ in range(2): aset = create_random_authset(utoken, t.tenant_token) dev = Device(aset.did, aset.id_data, aset.pubkey, t.tenant_token) dev.authsets.append(aset) t.devices.append(dev) yield tenants_users
def devices(clean_migrated_mongo, user): uc = ApiClient(useradm.URL_MGMT) r = uc.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text devices = [] for _ in range(5): aset = create_random_authset(utoken) dev = Device(aset.did, aset.id_data, aset.pubkey) devices.append(dev) yield devices
def create_tenant(name): """ Create a tenant via cli, record its id and token for further use. """ cli = CliTenantadm() api = ApiClient(tenantadm.URL_INTERNAL) id = cli.create_tenant(name) r = api.call('GET', tenantadm.URL_INTERNAL_TENANTS) assert r.status_code == 200 api_tenants = r.json() api_tenant = [at for at in api_tenants if at['id'] == id] token = api_tenant[0]['tenant_token'] return Tenant(name, id, token)
def get_context_data(self, **kwargs): context = super(StylesView, self).get_context_data(**kwargs) context['styles'] = Style.objects.all().values('name', 'slug') remote_instances = RemoteInstance.objects.all() api_client = ApiClient() remote_styles = api_client.styles(instances=remote_instances) try: context['styles'] = self.merge_dict(context['styles'], remote_styles['styles']) except KeyError: pass context['active'] = "styles" context['modal_playlists'] = Playlist.objects.all() return context
def do_test_get_authset_status(self, devs_authsets, user): devauthm = ApiClient(deviceauth_v2.URL_MGMT) useradmm = ApiClient(useradm.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # try valid authsets for d in devs_authsets: for a in d.authsets: r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_AUTHSET_STATUS, path_params={'did': d.id, 'aid': a.id }) assert r.status_code == 200 assert r.json()['status'] == a.status # invalid authset or device for did, aid in [(devs_authsets[0].id, "foo"), ("foo", "bar")]: r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_AUTHSET_STATUS, path_params={'did': did, 'aid': aid }) assert r.status_code == 404
def do_test_delete_device_not_found(self, devs_authsets, user): ua = ApiClient(useradm.URL_MGMT) da = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # try delete r = da.with_auth(utoken).call('DELETE', deviceauth_v2.URL_DEVICE, path_params={'id': 'foo'}) assert r.status_code == 404 # check device list unmodified r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICES) assert r.status_code == 200 api_devs = r.json() self._compare_devs(devs_authsets, api_devs)
def do_test_get_device(self, devs_authsets, user): da = ApiClient(deviceauth_v2.URL_MGMT) ua = ApiClient(useradm.URL_MGMT) # log in user r = ua.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # existing devices for dev in devs_authsets: r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json() self._compare_dev(dev, api_dev) # non-existent devices for id in ['foo', 'bar']: r = da.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': id}) assert r.status_code == 404
def do_test_delete_status_failed(self, devs_authsets, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # not found: valid device, bogus authset r = devauthm.with_auth(utoken).call('DELETE', deviceauth_v2.URL_AUTHSET, path_params={ 'did': devs_authsets[0].id, 'aid': "foo" }) assert r.status_code == 404 # not found: bogus device r = devauthm.with_auth(utoken).call('DELETE', deviceauth_v2.URL_AUTHSET, path_params={ 'did': "foo", 'aid': "bar" }) assert r.status_code == 404
def test_fail_bad_request(self, user): useradmm = ApiClient(useradm.URL_MGMT) devauthm = ApiClient(deviceauth_v2.URL_MGMT) # log in user r = useradmm.call('POST', useradm.URL_LOGIN, auth=(user.name, user.pwd)) assert r.status_code == 200 utoken = r.text # id data not json priv, pub = util.crypto.rsa_get_keypair() id_data = '{\"mac\": \"foo\"}' body = deviceauth_v2.preauth_req( id_data, pub) r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 400 # not a valid key id_data = {'mac': 'foo'} body = deviceauth_v2.preauth_req( id_data, 'not a public key') r = devauthm.with_auth(utoken).call('POST', deviceauth_v2.URL_DEVICES, body) assert r.status_code == 400
def tenants(mongo): cli = CliTenantadm() api = ApiClient(tenantadm.URL_INTERNAL) tenants = [Tenant('tenant1'), Tenant('tenant2')] for t in tenants: t.id = cli.create_tenant(t.name) r = api.call('GET', tenantadm.URL_INTERNAL_TENANTS) api_tenants = r.json() for t in tenants: api_tenant = [at for at in api_tenants if at['id'] == t.id] t.tenant_token = api_tenant[0]['tenant_token'] yield tenants mongo_cleanup(mongo)
def verify_dev_after_status_update(self, dev, utoken): devauthm = ApiClient(deviceauth_v2.URL_MGMT) r = devauthm.with_auth(utoken).call('GET', deviceauth_v2.URL_DEVICE, path_params={'id': dev.id}) assert r.status_code == 200 api_dev = r.json() assert api_dev['status'] == dev.status assert len(api_dev['auth_sets']) == len(dev.authsets) for api_aset in api_dev['auth_sets']: aset = [a for a in dev.authsets if a.id == api_aset['id']] assert len(aset) == 1 aset = aset[0] compare_aset(aset, api_aset)
def devices(clean_migrated_mongo): devauthd = ApiClient(deviceauth_v1.URL_DEVICES) devices = [] for _ in range(5): d = create_random_device() devices.append(d) yield devices
def get_context_data(self, **kwargs): context = super(AlbumsView, self).get_context_data(**kwargs) remote_instances = RemoteInstance.objects.all() artist = None context['artists'] = None if ('artist' in self.kwargs.keys() and self.kwargs['artist'] is not None): try: artist = Artist.objects.filter(slug=self.kwargs['artist']) context['artists'] = artist context['albums'] = Album.objects.filter( song__artist__in=artist).distinct().values('picture', 'slug', 'name') api_client = ApiClient() remote_albums = api_client.albums( artist=self.kwargs['artist'], instances=remote_instances) try: context['albums'] = self.merge_dict( context['albums'], remote_albums['albums']) except KeyError: pass except Artist.DoesNotExist: context['albums'] = [] else: context['albums'] = Album.objects.all().values('picture', 'slug', 'name') api_client = ApiClient() remote_albums = api_client.albums(instances=remote_instances) try: context['albums'] = self.merge_dict(context['albums'], remote_albums['albums']) except KeyError: pass context['active'] = "albums" context['modal_playlists'] = Playlist.objects.all() return context
def get_context_data(self, **kwargs): context = super(ArtistsView, self).get_context_data(**kwargs) remote_instances = RemoteInstance.objects.all() style = None if 'style' in self.kwargs.keys() and self.kwargs['style'] is not None: try: style = Style.objects.filter(slug=self.kwargs['style']) context['artists'] = Artist.objects.filter( song__style__in=style).distinct().values('name', 'slug', 'text', 'picture') api_client = ApiClient() remote_artists = api_client.artists( style=self.kwargs['style'], instances=remote_instances) try: context['artists'] = self.merge_dict( context['artists'], remote_artists['artists']) except KeyError: pass except Style.DoesNotExist: context['artists'] = [] else: context['artists'] = Artist.objects.all().values('name', 'slug', 'text', 'picture') api_client = ApiClient() remote_artists = api_client.artists(instances=remote_instances) try: context['artists'] = self.merge_dict(context['artists'], remote_artists['artists']) except KeyError: pass context['active'] = "artists" context['modal_playlists'] = Playlist.objects.all() return context