def filter(self, *args, **kwargs): """ Returns a ResourceSet object. The returned ResourceSet object will be filtered based on the arguments and keyword arguments. Arguments can be RQL filter expressions as strings or R objects. Ex. .. code-block:: python rs = collection.filter('eq(field,value)', 'eq(another.field,value2)') rs = collection.filter(R().field.eq('value'), R().another.field.eq('value2')) All the arguments will be combined with logical ``and``. Filters can be also specified as keyword argument using the ``__`` (double underscore) notation. Ex. .. code-block:: python rs = collection.filter( field=value, another__field=value, field2__in=('a', 'b'), field3__null=True, ) Also keyword arguments will be combined with logical ``and``. :raises TypeError: If arguments are neither strings nor R objects. :return: A ResourceSet with the filters applied. :rtype: ResourceSet """ query = R() for arg in args: if isinstance(arg, str): query &= R(_expr=arg) continue if isinstance(arg, R): query &= arg continue raise TypeError(f'arguments must be string or R not {type(arg)}') if kwargs: query &= R(**kwargs) return ResourceSet( self._client, self._path, query=query, )
def generate(client, parameters, progress_callback, renderer_type, extra_context): """ Extracts data from Connect using the ConnectClient instance and input parameters provided as arguments, applies required transformations (if any) and returns an iterator of rows that will be used to fill the Excel file. Each element returned by the iterator must be an iterator over the columns value. :param client: An instance of the CloudBlue Connect client. :type client: cnct.ConnectClient :param parameters: Input parameters used to calculate the resulting dataset. :type parameters: dict :param progress_callback: A function that accepts t argument of type int that must be invoked to notify the progress of the report generation. :type progress_callback: func """ filters = R().visibility.catalog.eq(True) & R().status.eq('published') count = client.products.filter(filters).count() i = 0 ctx = { 'products_count': count, 'vendors_count': 0, 'generation_date': date.today().strftime('%B %d, %Y'), } vendors = set() data = [] for prod in client.products.filter(filters): i += 1 data.append(prod) vendors.add(prod['owner']['id']) progress_callback(i, count) ctx['vendors_count'] = len(vendors) extra_context(ctx) return data
def test_collection_filter(col_factory): collection = col_factory(path='resource') rs = collection.filter() assert isinstance(rs, ResourceSet) assert rs._client == collection._client assert rs.path == collection.path assert bool(rs.query) is False rs = collection.filter('eq(field,value)') assert rs._client == collection._client assert rs.path == collection.path assert str(rs.query) == 'eq(field,value)' rs = collection.filter(R().field.eq('value')) assert rs._client == collection._client assert rs.path == collection.path assert str(rs.query) == 'eq(field,value)' rs = collection.filter(status__in=('status1', 'status2')) assert rs._client == collection._client assert rs.path == collection.path assert str(rs.query) == 'in(status,(status1,status2))'
def __init__( self, client, path, query=None, ): self._client = client self._path = path self._query = query or R() self._results = None self._limit = self._client.default_limit or 100 self._offset = 0 self._slice = False self._content_range = None self._fields = None self._search = None self._select = [] self._ordering = [] self._config = {}
def test_rs_filter(rs_factory): rs = rs_factory() assert rs.query is not None s1 = rs.filter() assert s1 != rs assert bool(s1.query) is False s1 = rs.filter('eq(field,value)') assert str(s1.query) == 'eq(field,value)' s1 = rs.filter(R().field.eq('value')) assert str(s1.query) == 'eq(field,value)' s2 = s1.filter(status__in=('status1', 'status2')) assert s1 != s2 assert str(s2.query) == 'and(eq(field,value),in(status,(status1,status2)))'
def sync(self): # noqa: CCR001 ws = self._wb["Items"] row_indexes = trange( 2, ws.max_row + 1, disable=self._silent, leave=True, bar_format=DEFAULT_BAR_FORMAT, ) for row_idx in row_indexes: data = _RowData( *[ws.cell(row_idx, col_idx).value for col_idx in range(1, 14)]) row_indexes.set_description( f'Processing item {data.id or data.mpn}') if data.action == '-': self._mstats.skipped() continue row_errors = self._validate_row(data) if row_errors: self._mstats.error(row_errors, row_idx) continue if data.action == 'create': rql = R().mpn.eq(data.mpn) item = (self._client.products[self._product_id].items.filter( rql).first()) if item: self._mstats.error( f'Cannot create item: item with MPN `{data.mpn}`' f' already exists with ID `{item["id"]}`.', row_idx, ) continue row_indexes.set_description(f"Creating item {data[1]}") try: item = create_item( self._client, self._product_id, self._get_item_payload(data), ) self._mstats.created() self._update_sheet_row(ws, row_idx, item) except Exception as e: self._mstats.error(str(e), row_idx) if data.action == 'update': item = self._get_item(data) if not item: field = 'ID' if data.id else 'MPN' value = data.id if data.id else data.mpn self._mstats.error( f'Cannot update item: item with {field} `{value}` ' f'the item does not exist.', row_idx, ) continue row_indexes.set_description(f"Updating item {item['id']}") if item['status'] == 'published': payload = { 'name': data.name, 'mpn': data.mpn, 'description': data.description, 'ui': { 'visibility': True }, } else: payload = self._get_item_payload(data) if item['type'] == 'ppu': del payload['period'] try: item = update_item( self._client, self._product_id, item['id'], payload, ) self._mstats.updated() self._update_sheet_row(ws, row_idx, item) except Exception as e: self._mstats.error(str(e), row_idx) if data.action == 'delete': item = self._get_item(data) if not item: field = 'ID' if data.id else 'MPN' value = data.id if data.id else data.mpn self._mstats.error( f'Cannot update item: item with {field} `{value}` ' f'the item does not exist.', row_idx, ) continue try: delete_item( self._client, self._product_id, item['id'], ) self._mstats.deleted() except Exception as e: self._mstats.error(str(e), row_idx)
def generate(client, parameters, progress_callback, renderer_type, extra_context): account = client.collection('accounts').all().first() account_id = account['id'] agreements_filter = R().type.eq('service') available_products = {} agreements_count = 0 for agreement in client.agreements.filter(agreements_filter): if agreement['owner']['id'] != account_id: agreements_count += 1 for product in client.collection('agreements', ).resource( agreement['id'], ).collection('products', ).all(): if not product['id'] in available_products: available_products[product['id']] = product available_products[product['id']]['agreements'] = [ agreement['id'] ] else: available_products[product['id']]['agreements'].append( agreement['id']) i = 0 count = len(available_products) * 2 ctx = { 'products_count': len(available_products), 'vendors_count': 0, 'distributors_count': agreements_count, 'generation_date': date.today().strftime('%B %d, %Y'), 'api_url': client.endpoint.replace('/public/v1', ''), 'account_name': account['name'], 'account_id': account['id'], } vendors = set() data = [] for prod in available_products: i += 1 available_products[prod]['marketplaces'] = [] for agreement in available_products[prod]['agreements']: marketplaces = client.collection('agreements', ).resource( agreement, ).collection('products', ).resource( prod, ).collection('marketplaces', ).all() for marketplace in marketplaces: available_products[prod]['marketplaces'].append(marketplace) progress_callback(i, count) for prod in client.collection('products').all().order_by('name'): if prod['id'] in available_products: prod['marketplaces'] = available_products[ prod['id']]['marketplaces'] data.append(prod) vendors.add(prod['owner']['id']) i += 1 progress_callback(i, count) ctx['vendors_count'] = len(vendors) extra_context(ctx) return data