def details_info(): """ Endpoint to get details of given items @Params: - values: <str> list of values - by: <str> field which the values are queried against (WHERE <by> = <value>) - cols: <str> can be item_uuid, gtin, name, description @Response: - resp: items list """ logger.info("Info details") params = request.args # Validation if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'values', 'by'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") if 'cols' not in params: cols = ['item_uuid', 'gtin', 'name', 'description'] # Call to delete Item values = params['values'].split(",") by = params['by'] _resp = Item.get(values, by=by, _cols=cols) return jsonify({ "status": "OK", "items": _resp })
def get_it_list(): ''' Get list of all items with their given id and name @Params: - p - ipp ''' logger.debug("List items") params = request.args # Validation if not params: raise errors.ApiError(70001, "Missing required key params") _needed_params = {'p', 'ipp'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params: {}".format(list(_needed_params))) if 'cols' not in params: cols = ','.join(['description']) else: cols = params['cols'] _resp = Item.it_list(cols=cols, p=params['p'], ipp=params['ipp']) if params.get('csv', '0') == '1': csv_ = pd.DataFrame(_resp, dtype=str).to_csv(quoting=csv.QUOTE_ALL) return Response( csv_, mimetype="text/csv", headers={"Content-disposition": "attachment; filename=item_data.csv"}) return jsonify({ "status": "OK", "items": _resp })
def reset_match(): """ Reset match by setting Item UUID to NULL """ logger.info("Reseting product...") params = request.get_json() if not params: raise errors.ApiError(70001, "Missing required key params") if 'puuid' not in params: raise errors.ApiError(70001, "Missing required key params") # Call to update Product return jsonify(Product.undo_match(params['puuid']))
def upload_normalized(): """ Endpoint to upsert normalized names to normalized table. """ logger.info('Upload Normalized Names of products.') if not request.files: raise errors.ApiError(70007, "Missing file, add attachement!") if 'normalized.csv' not in request.files: raise errors.ApiError(70007, "Missing file name, add attachement!") if 'append' in request.args: _mode = 'append' else: _mode = 'replace' resp = Product.upload_normalized(request.files['normalized.csv'], _mode) return jsonify(resp)
def add_prods(): """" Endpoint to add a new product """ logger.debug("Adding new product...") params = request.form logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'name', 'source'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Call to save product srch_prod = Search(params) _saved = srch_prod.add() message = 'Product {}saved'.format('' if _saved else 'not ') return jsonify({ "status": "OK", "message": message, }) ### In development # @mod.route('/products/csv', methods=["POST"]) # def csv_prods(): # """" Endpoint to add a new product from csv file # """ # logger.debug("Reading CSV...") # _file = request.files.get('data') # if _file: # data = _file.stream.read() # print(type(data)) # try: # # f = request.files['data_file'] # if True: # # output = io.StringIO(f.stream.read().decode("UTF8"), newline=None) # # df = pd.read_csv(output) # _saved = None # message = 'Products {}saved'.format('' if _saved else 'not ') # else: # message = "No file" # except Exception as e: # message = str(e) # return jsonify({ # "status": "OK", # "message": message, # })
def get_products(**kwargs): """ Get catalogue """ p = int(kwargs['p']) ipp = int(kwargs['ipp']) del kwargs['p'], kwargs['ipp'] # Columns if 'cols' not in kwargs or not kwargs['cols']: cols = ["*"] else: print(kwargs['cols']) cols = [ "i.item_uuid as item_uuid", "p.product_uuid as product_uuid", "i.gtin as gtin", "p.name as name" ] cols += [ c for c in kwargs['cols'].split(",") \ if c not in ['item_uuid', 'product_uuid', 'gtin', 'name'] ] del kwargs['cols'] where = [] where_qry = """ """ # Source query source = kwargs['source'] where.append(""" p.source = '{}' """.format(source)) del kwargs['source'] # Extras for k, vals in kwargs.items(): where.append(""" {} IN ({}) """.format(k, vals) ) if where: where_qry = """ where {}""".format(""" and """.join(where)) # Query qry = """ select {} from product p inner join item i on i.item_uuid = p.item_uuid {} limit {} offset {} """.format( """, """.join(cols), where_qry, ipp, (p - 1) * ipp ) try: rows = g._db.query(qry).fetch() except Exception as e: logger.error("Could not execute source catalogue query: {}".format(qry)) raise errors.ApiError(70007, "Could not execute query: ") return rows
def save(self, commit=True): """ Class method to save attr in DB """ logger.info("Saving attr...") if self.id_attr: if not Attr.exists({'id_attr': self.id_attr}, commit=commit): raise errors.ApiError(70006, "Cannot update, Attr not in DB!") elif Attr.exists({ 'key': self.key, 'source': self.source }, commit=commit): self.message = 'Attr already exists!' self.id_attr = Attr.get_id(self.key, self.source, commit=commit) return self.id_attr # Load model m_atr = g._db.model("attr", "id_attr") for _at in self.__attrs__: if self.__dict__[_at]: m_atr.__dict__[_at] = self.__dict__[_at] try: # Save record self.message = "Attr {} correctly!".format(\ 'updated' if self.id_attr else 'stored') m_atr.save(commit=commit) self.id_attr = m_atr.last_id logger.info(self.message \ + '({})'.format(self.id_attr)) return self.id_attr except Exception as e: logger.error(e) return None
def query_by(by): """ Endpoint to query items table by given values @Params: - by: <str> column to compare values with - keys: <str> can be item_uuid, gtin, name, description @Response: - resp: items list @Example: /query/gtin?keys=07501034691224,07501284858385 """ logger.info("Query Items by Item UUID...") params = request.args.to_dict() logger.debug(params) # Validate required params _needed_params = {'keys'} if not _needed_params.issubset(params): raise errors.ApiError(70001, "Missing required key params") # Complement optional params, and set default if needed _opt_params = {'cols': '', 'p':1, 'ipp': 50} for _o, _dft in _opt_params.items(): if _o not in params: params[_o] = _dft _items = Item.query(by, **params) return jsonify({ 'status': 'OK', 'items': _items })
def get_byitems_and_retailers(): """ Endpoint to fetch `Product`s by item_uuid's. """ logger.info("Query Product by Item UUID...") params = request.args.to_dict() logger.debug(params) # Validate required params _needed_params = {'items', 'retailers'} if not _needed_params.issubset(params): raise errors.ApiError(70001, "Missing required key params") # Complement optional params, and set default if needed '''_opt_params = {'cols': '', 'p':1, 'ipp': 50} for _o, _dft in _opt_params.items(): if _o not in params: params[_o] = _dft''' cols = ['gtin', 'item_uuid', 'name', 'product_uuid', 'source'] items = params['items'].split(',') retailers = params['retailers'].split(',') if 'cols' in params: cols += params['cols'].split(',') _prods = Product.bulk_query(items, retailers, cols) return jsonify({ 'status': 'OK', 'products': _prods })
def get_matchbysource(): """ Endpoint to fetch `Product`s by source's. """ logger.info("Query count Product by source...") params = request.args.to_dict() logger.debug(params) # Validate required params _needed_params = {'keys'} if not _needed_params.issubset(params): raise errors.ApiError(70001, "Missing required key params") # Complement optional params, and set default if needed _opt_params = {'cols': '', 'p':1, 'ipp': 50, 'items': 'all', 'csv':'0'} for _o, _dft in _opt_params.items(): if _o not in params: params[_o] = _dft _prods = Product.query_match('source', **params) if params['csv'] == '1': csv_ = pd.DataFrame(_prods, dtype=str).to_csv(quoting=csv.QUOTE_ALL) return Response( csv_, mimetype="text/csv", headers={"Content-disposition": "attachment; filename=data.csv"}) else: return jsonify({ 'status': 'OK', 'products': _prods })
def save(self, commit=True): """ Class method to save Clss in DB """ logger.info("Saving clss...") if self.id_clss: if not Clss.exists({'id_clss': self.id_clss}, commit=commit): raise errors.ApiError(70006, "Cannot update, Clss not in DB!") elif Clss.exists({ 'key': self.key, 'source': self.source }, commit=commit): self.message = 'Clss already exists!' self.id_clss = Clss.get_id(self.key, self.source, commit=commit) return self.id_clss # Load model m_cls = g._db.model("clss", "id_clss") for _at in self.__attrs__: if self.__dict__[_at]: m_cls.__dict__[_at] = self.__dict__[_at] try: # Save record self.message = "Clss {} correctly!".format(\ 'updated' if self.id_clss else 'stored') m_cls.save(commit=commit) self.id_clss = m_cls.last_id logger.info(self.message \ + '({})'.format(self.id_clss)) return self.id_clss except Exception as e: logger.error(e) return None
def update_img_prod(): """ Endpoint to update a `Product Image`. """ logger.info("Update Product image...") params = request.get_json() logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'product_uuid', 'image'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Call to update prod image return jsonify({ 'status': 'OK', 'message': Product.update_image(params)['message'] })
def get_one(): """ Testing connection method """ logger.debug("Testing connection with one product") prod = Product.get_one() if not prod: raise errors.ApiError("invalid_request", "Could not fetch data from Postgres Items") return jsonify(prod)
def get_bycategory(): """ Endpoint to get details of given items @Params: - id_category: <str> list of values - cols: <str> can be item_uuid, gtin, name, description @Response: - resp: items list @Example: /by/category?id_category=3618&p=3&ipp=5 """ logger.info("Searching by category") params = request.args.to_dict() # Validation if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'id_category'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Optional parameters cols = ['item_uuid', 'gtin', 'name', 'description'] _opt_params = {'cols': cols, 'p':1, 'ipp': 50} for _o, _dft in _opt_params.items(): if _o not in params: params[_o] = _dft try: _resp = Item.get_by_category( params['id_category'], _cols=cols, p=int(params['p']), ipp=int(params['ipp'])) except Exception as e: logger.error(e) raise errors.ApiError(70001, "Could not query items by category") return jsonify({ "status": "OK", "items": _resp })
def delete_prod_img(): """ Endpoint to delete `Product`s image by Prod Image ID """ logger.info("Delete Product Image...") params = request.args logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'uuid','id'} if not _needed_params.issubset(params): raise errors.ApiError(70001, "Missing required key params") # Call to delete Product extra _resp = Product.delete_extra(params['uuid'], params['id'], 'product_image') return jsonify({ "status": "OK", "message": _resp['message'] })
def get_all(): """ Testing connection method /provider?retailer=ims&p=1&ipp=200 """ retailer = request.args.get('retailer') or 'byprice' p = None ipp = None try: p = int(request.args.get('p')) if 'p' in request.args else 1 ipp = int(request.args.get('ipp')) if 'ipp' in request.args else 100000 except: raise errors.ApiError('invalid_data_type', "Query params with wrong data types!") provs = Provider.get_all(retailer=retailer, p=p, ipp=ipp) if not provs: raise errors.ApiError("invalid_request", "Could not fetch data from Postgres Providers") return jsonify(provs)
def get_all(): """ Get all brands of a given retailer /brand?retailer=ims&p=1&ipp=200 """ retailer = request.args.get('retailer') or 'byprice' p = None ipp = None try: p = int(request.args.get('p')) if 'p' in request.args else 1 ipp = int(request.args.get('ipp')) if 'ipp' in request.args else 100000 except: raise errors.ApiError('invalid_data_type', "Query params with wrong data types!") brands = Brand.get_all(retailer=retailer, p=p, ipp=ipp) if not brands: raise errors.ApiError("invalid_request", "Could not fetch data from Postgres Providers") return jsonify(brands)
def get_all(): """ List of attr classes """ source = request.args.get('source') or 'byprice' clsses = Attr.get_clss_list(source=source) if not clsses: raise errors.ApiError("catalogue_attr_error", "Could not fetch ingo from attributes") return jsonify(ings)
def delete_item(): """ Endpoint to delete an `Item` by item_uuid """ logger.info("Delete Item...") params = request.args logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'uuid'} if not _needed_params.issubset(params): raise errors.ApiError(70001, "Missing required key params") # Call to delete Item _resp = Item.delete(params['uuid']) return jsonify({ "status": "OK", "message": _resp['message'] })
def vademecum_info(): """ Endpoint to get info from vademecum """ logger.info("Fetching Vademecum additonal info..") params = request.args if 'uuid' not in params: raise errors.ApiError(70001, "Missing required UUID param") # Call values _resp = Item.get_vademecum_info(params['uuid']) return jsonify(_resp)
def details_item(): """ Endpoint to get details for FrontEnd info """ logger.info("Item details endpoint...") params = request.args # Validation if not params: raise errors.ApiError(70001, "Missing required key params") _needed_params = {'uuid'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Verify if item or product uuid_type = 'item_uuid' if not Item.exists({'item_uuid': params['uuid']}): uuid_type = 'product_uuid' _resp = Item.details(uuid_type, params['uuid']) logger.debug(_resp) logger.info("Delivering response: {}".format(params['uuid'])) return jsonify(_resp)
def get_bygtin(): """ Endpoint to get details of given items @Params: - gtins: <str> list of values - cols: <str> can be item_uuid, gtin, name, description @Response: - resp: items list @Example: /by/gtin?gtins=07501034691224,07501284858385 """ logger.info("Searching by gtin") params = request.args # Validation if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'gtins'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Get columns if 'cols' not in params: cols = ['item_uuid', 'gtin', 'name', 'description'] else: cols = list(set( ['item_uuid, gtin'] + params['cols'].split(",") )) # Call to delete Item gtins = params['gtins'].split(",") try: _resp = Item.get_by_gtin(gtins, _cols=cols) except Exception as e: logger.error(e) raise errors.ApiError(70001, "Could not query items by gtin") return jsonify({ "status": "OK", "items": _resp })
def get_all(): """ Get all categories from a given retailer """ logger.debug("Testing connection with one product") retailer = ctype = request.args.get('retailer') cats = Category.get_all(retailer=retailer) if not cats: raise errors.ApiError("invalid_request", "Could not fetch data from Postgres Categories") return jsonify(cats)
def modify_item(): """ Endpoint to modify a new `Item` """ logger.info("Modify Item...") params = request.get_json() logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'item_uuid'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Call to save Item _item = Item(params) _item.save() return jsonify({ "status": "OK", "message": _item.message, "item_uuid": _item.item_uuid })
def update(): """ Get items given some filters """ data = request.get_json() if not ('auth' in data and data['auth'] == "ByPrice123!"): raise errors.ApiError("unauthorized","No client ID found",401) if 'product_uuid' not in data: raise errors.ApiError("error","Invalid parameters",402) if 'key' not in data: raise errors.ApiError("error","Invalid parameters",402) print(data) Product.update( product_uuid=data['product_uuid'], item_uuid=None if 'item_uuid' not in data or not data['item_uuid'] else data['item_uuid'], product_id=None if 'product_id' not in data or not data['product_id'] else data['product_id'], key=data['key'] ) return jsonify({"result" : "OK"})
def modify_prod(): """ Endpoint to modify a `Product` with respective, product images, attributes and categories. """ logger.info("Modify existing Product...") params = request.get_json() logger.debug(params) if not params: raise errors.ApiError(70001, "Missing required key params") # Verify needed key-values _needed_params = {'product_uuid'} if not _needed_params.issubset(params.keys()): raise errors.ApiError(70001, "Missing required key params") # Call to save Product _prod = Product(params) _prod.save() return jsonify({ "status": "OK", "message": _prod.message, "product_uuid": _prod.product_uuid })
def save_product_id(): """ Get items given some filters """ data = request.get_json() print(data) if not ('auth' in data and data['auth'] == "ByPrice123!"): raise errors.ApiError("unauthorized","No client ID found",401) if 'item_uuid' not in data: raise errors.ApiError("error","Invalid parameters",401) if 'source' not in data: raise errors.ApiError("error","Invalid parameters",401) if 'product_id' not in data: raise errors.ApiError("error","Invalid parameters",401) Product.upsert_id( item_uuid=data['item_uuid'], source=data['source'], new_product_id=data['product_id'] ) return jsonify({"result" : "OK"})
def update(): """ Get items given some filters """ data = request.get_json() if not ('auth' in data and data['auth'] == "ByPrice123!"): raise errors.ApiError("unauthorized","No client ID found",401) if 'item_uuid' not in data: raise errors.ApiError("error","Invalid parameters",401) if 'name' not in data and 'gtin' not in data: raise errors.ApiError("error","Invalid parameters",401) name = None if 'name' not in data else data['name'] gtin = None if 'gtin' not in data else data['gtin'] Item.update( item_uuid=data['item_uuid'], name=name, gtin=gtin ) return jsonify({"result" : "OK"})
def get_all(): """ Fetch all Sources in DB """ logger.info("Fetch all sources...") params = request.args.to_dict() logger.debug(params) # Validate required params _needed_params = {'cols'} if not _needed_params.issubset(params): params['cols'] = '' rets = Source.get_all(params['cols']) if not rets: raise errors.ApiError(70003, "Could not fetch Sources data!") return jsonify(rets)
def ims(): """ Get ims categories given the level and type """ logger.info("Fetching Catalogue items per retailer") try: ctype = request.args.get('type') or 'atc' levels = request.args.get('levels').split(",") or [3, 4] nested = request.args.get('nested') == '1' or False except: raise errors.ApiError('invalid_data_type', "Query params with wrong data types!") # Call function to obtain items from certain retailer categories = Category.get_ims(ctype=ctype, levels=levels, nested=nested) return jsonify(categories)