def put(self, id): """ update one item """ # 1. parsing reqest try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 2. get orm from db r = obj.query.filter(obj.id == id, obj.isdel == False).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # 3. assign request data to orm try: t = datetime.utcnow() r = PrepareObjORM(r, self.args.items()) r.mtime = t except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.merge(r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 next(iter(out))[field_inputs_wrap_head].update({'id': id}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'rate' return out
def put(self, id): """ update one record @api {put} /rest/objects/ipaddr/:id update a IP Address item @apiVersion 0.0.1 @apiName UpdateIpAddr @apiVersion 0.0.1 @apiGroup objects @apiPermission registered user @apiParam {Number} id ipdate IP Address ID. @apiDescription todo validation<br /> todo certificate with cookies / oauth 2.0 @apiParam {Object} ipaddrs List of IP Addresses. @apiParam {String{..16}} ipaddrs.addr1 1st IP Address. @apiParam {String{..16}} ipaddrs.addr2 2ed IP Address. @apiParam {String{..255}} [ipaddrs.description] this items's description. @apiParam {String="IPv4","IPv6"} ipaddrs.ipVersion IP Address version. @apiParam {String{..50}} ipaddrs.name items uniq name for record. @apiParam {String="Single","Range","Subnet"} ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'. @apiExample Example usage: BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7 @apiSuccess {Object} ipaddrs List of IP Addresses. @apiSuccess {String} ipaddrs.addr1 1st IP Address. @apiSuccess {String} ipaddrs.addr2 2ed IP Address. @apiSuccess {String} ipaddrs.description this items's description. @apiSuccess {Number} ipaddrs.id index in database. @apiSuccess {String} ipaddrs.ipVersion IP Address version. @apiSuccess {String} ipaddrs.name items uniq name for record. @apiSuccess {String} ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'. @apiError CE_INVALID_PARAM invalid parameter @api {put} /rest/objects/ipaddr/:id @apiErrorExample {json} we use invalid member type1 in request body BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type1" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7 ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2001, "message": "ValueError('[type]: (type Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)" } @apiError CE_NAME_CONFLICT name conflict @api {post} /rest/objects/ipaddr/:id @apiErrorExample {json} we use duplicate name. BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/7 ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2004, "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: objects_ipaddrs.name',)" } @apiError CE_NOT_EXIST item not found @api {get} /rest/objects/ipaddr/:id @apiErrorExample {json} we use not exist id curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddr/17 ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2003, "message": "id 17 not found" } """ # 1. parsing reqest try: orgArgs, self.args = GetRequestArgs(__head__, field_inputs) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 try: checkInputIsValid(self.args) except Exception as error: return error.args # 2. get orm from db r = obj.query.filter(obj.id == id).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # 3. assign request data to orm try: r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.merge(r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user return SerialObjOutput(r, objname=__head__, resource_fields=resource_fields), 200
def post(self): """create data """ # 1. parsing reqest # 1.1 parsing 1st layer reqest try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 1.3 check name unique r = obj.query.filter(obj.user_id == self.args['user_id'], obj.business_id == self.args['business_id'], obj.isdel == False).scalar() if r is not None: return omitError( 'CE_DATA_DUPLICATE', 'user_id {}, business_id {} are duplicate'.format( self.args['user_id'], self.args['business_id'])), 400 # 2. validate follows spec if db.session.query(obj).filter(obj.isdel == False).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 r = obj() try: r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.add(r) db.session.flush() db.session.refresh(r) db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 next(iter(out))[field_inputs_wrap_head].update({'id': r.id}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'rate' return out
def put(self, id): """ update one item """ # 1. parsing reqest try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 2. get orm from db r = obj.query.filter(obj.id == id, obj.isdel == False).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # 3. assign request data to orm try: t = datetime.utcnow() if not self.args['passHash']: self.args['passHash'] = r.passHash # not allow others change expect itself # TODO: raise custome error check_permission(self.args['login'], r.login) # not allow change login name self.args['login'] = r.login r = PrepareObjORM(r, self.args.items()) r.mtime = t except Exception as error: if RuntimeError == type(error): return omitError('CE_UNAUTHORIZED', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.merge(r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user _resource_fields_post = resource_fields_post.copy() _resource_fields_post.pop('access_token', None) out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=_resource_fields_post), 200 next(iter(out))['type'] = 'system' next(iter(out))['subtype'] = 'regist' return out
def post(self): """create data @api {post} /rest/objects/ipaddrs Create a IP Address item @apiVersion 0.0.1 @apiName CreateIpAddr @apiVersion 0.0.1 @apiGroup objects @apiPermission registered user @apiDescription todo validation <br/> todo certificate with cookies / oauth 2.0 <br/> todo muti-create @apiParam {Object} ipaddrs List of IP Addresses. @apiParam {String{..16}} ipaddrs.addr1 1st IP Address. @apiParam {String{..16}} ipaddrs.addr2 2ed IP Address. @apiParam {String{..255}} [ipaddrs.description] this items's description. @apiParam {String="IPv4","IPv6"} ipaddrs.ipVersion IP Address version. @apiParam {String{..50}} ipaddrs.name items uniq name for record. @apiParam {String="Single","Range","Subnet"} ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'. @apiExample Example usage: BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs @apiSuccess {Object} ipaddrs List of IP Addresses. @apiSuccess {String} ipaddrs.addr1 1st IP Address. @apiSuccess {String} ipaddrs.addr2 2ed IP Address. @apiSuccess {String} ipaddrs.description this items's description. @apiSuccess {Number} ipaddrs.id index in database. @apiSuccess {String} ipaddrs.ipVersion IP Address version. @apiSuccess {String} ipaddrs.name items uniq name for record. @apiSuccess {String} ipaddrs.type IP Address type, the possible values are 'Single', 'Range', 'Subnet'. @apiError CE_INVALID_PARAM invalid parameter @api {post} /rest/objects/ipaddrs @apiErrorExample {json} we use invalid parameter pages BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type1" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2001, "message": "ValueError('[type]: (type Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)" } @apiError CE_NAME_CONFLICT name conflict @api {post} /rest/objects/ipaddrs @apiErrorExample {json} we use duplicate name. BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2004, "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: objects_ipaddrs.name',)" } @apiError CE_EXCEED_LIMIT exceed max limit @api {post} /rest/objects/ipaddrs @apiErrorExample {json} we create item exceed max. BODY=$(cat <<'EOF' { "ipaddr" : { "name" : "test-ipaddr-${i}8", "type" : "Single", "ipVersion" : "IPv4", "addr1" : "1.1.1.1", "description" : "xxx" } } EOF ); curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d "${BODY}" http://localhost/rest/objects/ipaddrs ================================================ HTTP/1.0 400 BAD REQUEST { "errorId": 2005, "message": "limit is 5" } """ # 1. parsing reqest # 1.1 parsing 1st layer reqest try: orgArgs, self.args = GetRequestArgs(__head__, field_inputs) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 1.2 parsing 2ed layer reqest try: for v in set((v) for v in set(field_inputs).intersection(orgArgs) if isinstance(field_inputs[v]['validator'], set)): _type = field_inputs[v]['validator'] validator = next(iter(_type)).container.nested.items() \ if type(_type) is set else _type.items() # validate 2ed value # if is list, such as [{id: 1, name:2}, {id: 2, name:2}] for _k, _v in validator: for __v in orgArgs[v]: if (_v.get('required', False)): _v['type'](__v[_k]) self.args[v] = self.args[v] if self.args.get(v, False) else [] self.args[v].append(__v) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 logger.debug('parsed args = (%s)', self.args) # 2. validate follows spec if db.session.query(obj.id).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 try: checkInputIsValid(self.args) except Exception as error: return error.args r = obj() try: r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.add(r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user return SerialObjOutput(r, objname=__head__, resource_fields=resource_fields), 200
def put(self, id): """ update one item @api {put} /rest/customer/business/:id Update a item @apiVersion 0.0.5 @apiName UpdateCustomerBusiness @apiGroup business @apiPermission registered user @apiDescription todo certificate with cookies / oauth 2.0<br /> todo long/lat validation<br /> todo error / success return code in api <br /> @apiParam {Object} data object of business. @apiParam {Number} data.id item's uniq id. @apiParam {String} data.name item's name. @apiParam {Number} data.cat item's business industry category. @apiParam {float} data.lat item's entered latitude. @apiParam {float} data.long item's entered longitude. @apiParam {String} data.address item's address @apiParam {String} data.description item's description. @apiParam {String} data.image_url items's image url. @apiParam {Float} data.rate item's rate, average from each comments @apiParam {Number} data.deal one of item's deal for display in list @apiParam {Object[]} data.deals item's deals @apiParam {String} data.deals.title item's deal title @apiParam {String} data.deals.description item's deal description @apiParam {String} data.open item open time with 24h format @apiParam {String} data.open item close time with 24h format @apiParam {Number} data.dist item's distance farward with your current location, the unit is meter @apiParam {Object} data.images_url item images' path @apiParam {String} data.images_url.bg item backgound images' path @apiParam {String} data.images_url.icon item icon images' path @apiExample {curl} Example usage: curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d " { "data":{ "dist":12245, "close":"2200", "lat":120.678, "features":"this is features", "address":"this is address", "deals":[ { "title":"10% Off Any Order", "description":"Use this promo code and save on coffee, tea, and..." } ], "cat":1, "long":23.5383, "meals":"this is meals", "deal":200, "open":"0600", "description":"early Bird Special: Get off.", "name":"Starbucks Coffee 31", "images_url":{ "icon":"/img/business/1/icon", "bg":"/img/business/1/bg" }, "id":1 }, "type":"business", "subtype":"overview" } " http://localhost/rest/customer/business/1 @apiError CE_INVALID_PARAM invalid parameter HTTP/1.0 400 BAD REQUEST { "errorId": 2001, "message": "ValueError('[cat]: (cat Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)" } @apiError CE_NAME_CONFLICT name conflict HTTP/1.0 400 BAD REQUEST { "errorId": 2004, "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: customer_businesses.name',)" } @apiError CE_NOT_EXIST item not found HTTP/1.0 400 BAD REQUEST { "errorId": 2003, "message": "id 17 not found" } """ # 1. parsing reqest try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) RemoveRequestArgs(field_inputs_post) j = request.get_json() orgdetailImgsUrlArgs, self.detailimgsurlargs = GetTwoLayerRequestArgs( None, field_inputs_detail_images_url, j[field_inputs_wrap_head][__head_detail_images_url__]) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 2. get orm from db r = obj.query.filter(obj.id == id, obj.isdel == False).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # 3. assign request data to orm try: t = datetime.utcnow() _item = [] for k, v in self.args.items(): if k != "deals": _item.append((k, v)) r = PrepareObjORM(r, _item) r.mtime = t d = detail.query.filter(detail.business_id == id, detail.isdel == False).scalar() __deals = deals.query.filter(deals.business_id == id, deals.isdel == False).all() # TODO: mark isdel = True? #for v in __deals: # v.isdel = True; _deals = [] for k, v in self.args.items(): if v != None: if k == 'deals': deal = deals() for v1 in v: # each entry for k2, v2 in v1.items(): setattr(deal, k2, v2) _deals.append(deal) else: setattr(d, k, v) d.mtime = t _pics = [] _ps = pics.query.filter(pics.business_id == id, pics.isdel == False).all() # FIXME: hard code mapping for k, v in self.detailimgsurlargs.items(): # (1, 'icon'), (2, 'bg'), (3, 'gallery') p = pics() if k == 'icon': p.type = 1 elif k == 'bg': p.type = 2 if p.type: p.path = v _pics.append(p) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: #db.session.merge(r) for v in __deals: db.session.delete(v) for v in _ps: db.session.delete(v) for v in _pics: db.session.add(v) for v in _deals: db.session.add(v) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user out = SerialObjOutput(d, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 for k, v in field_inputs.items(): if k not in ['id', 'image_url']: next(iter(out))[field_inputs_wrap_head].update({k: orgArgs[k]}) next(iter(out))[field_inputs_wrap_head].update( {'deals': orgArgs['deals']}) next(iter(out))[field_inputs_wrap_head].update( {'images_url': orgArgs['images_url']}) next(iter(out))[field_inputs_wrap_head].update({'id': id}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'overview' return out
def post(self): """regist local user @api {post} /rest/admins regist local account @apiVersion 0.0.5 @apiName RegistOneUser @apiGroup account @apiPermission registered user @apiDescription todo certificate with cookies / oauth 2.0<br /> todo validation<br /> todo error / success return code in api @apiParam {Object[]} user user object @apiParam {String{..254}} user.name user name for display @apiParam {String{..254}} user.login user email for login @apiParam {String{..254}} user.passHash user password encode with sha1 @apiExample {curl} Example usage: curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d " { 'data':{ 'id':2, 'login':'******', 'passHash':'c4f9375f9834b4e7f0a528cc65c055702bf5f24a', 'name':'test' }, 'type':'system', 'subtype':'regist' } " http://localhost/rest/admins """ # 1. check id exist try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError('CE_INVALID_PARAM', 'not found'), 400 # 2. validate follows spec if db.session.query(obj).filter(obj.isdel == False).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 # 3 check name unique r = obj.query.filter(obj.login == self.args['login'], obj.isdel == False).scalar() if r is not None: return omitError( 'CE_DATA_DUPLICATE', 'login {} is duplicate'.format(self.args['login'])), 400 r = obj() try: r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.add(r) db.session.flush() db.session.refresh(r) db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user _resource_fields_post = resource_fields_post.copy() _resource_fields_post.pop('access_token', None) out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=_resource_fields_post), 200 next(iter(out))[field_inputs_wrap_head].update({'id': r.id}) next(iter(out))['type'] = 'system' next(iter(out))['subtype'] = 'regist' return out
def post(self): """create data @api {post} /rest/customer/businesses Create a item @apiVersion 0.0.3 @apiName CreateCustomerBusiness @apiGroup business @apiPermission registered user @apiDescription todo validation <br/> todo certificate with cookies / oauth 2.0 <br/> todo muti-create <br /> todo error / success return code in api @apiParam {Object} data object of business. @apiParam {Number} data.id item's uniq id. @apiParam {String} data.name item's name. @apiParam {Number} data.cat item's business industry category. @apiParam {float} data.lat item's entered latitude. @apiParam {float} data.long item's entered longitude. @apiParam {String} data.address item's address @apiParam {String} data.description item's description. @apiParam {String} data.image_url items's image url. @apiParam {Float} data.rate item's rate, average from each comments @apiParam {Number} data.deal one of item's deal for display in list @apiParam {Object[]} data.deals item's deals @apiParam {String} data.deals.title item's deal title @apiParam {String} data.deals.description item's deal description @apiParam {String} data.open item open time with 24h format @apiParam {String} data.open item close time with 24h format @apiParam {Number} data.dist item's distance farward with your current location, the unit is meter @apiParam {Object} data.images_url item images' path @apiParam {String} data.images_url.bg item backgound images' path @apiParam {String} data.images_url.icon item icon images' path @apiExample {curl} Example usage: curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d ' { "data":{ "dist":12245, "close":"2200", "lat":120.678, "features":"this is features", "address":"this is address", "deals":[ { "title":"10% Off Any Order", "description":"Use this promo code and save on coffee, tea, and..." } ], "cat":1, "long":23.5383, "meals":"this is meals", "deal":200, "open":"0600", "description":"early Bird Special: Get off.", "name":"Starbucks Coffee 31", "images_url":{ "icon":"/img/business/1/icon", "bg":"/img/business/1/bg" }, "id":1 }, "type":"business", "subtype":"overview" }' http://localhost/rest/customer/businesses @apiError CE_INVALID_PARAM invalid parameter HTTP/1.0 400 BAD REQUEST { "errorId": 2001, "message": "ValueError('[cat]: (cat Valid Error) Missing required parameter in dataDict, error=400: Bad Request',)" } @apiError CE_NAME_CONFLICT name conflict HTTP/1.0 400 BAD REQUEST { "errorId": 2004, "message": "IntegrityError('(sqlite3.IntegrityError) UNIQUE constraint failed: customer_businesses.name',)" } @apiError CE_EXCEED_LIMIT exceed max limit HTTP/1.0 400 BAD REQUEST { "errorId": 2005, "message": "limit is 5" } """ # 1. parsing reqest # 1.1 parsing 1st layer reqest try: #orgArgs = {'type': 'business', 'subtype': 'overview', 'data': {'name': 'Starbucks Coffee 1', 'description': 'early Bird Special: Get off.', 'address': 'this is address', 'close': '2200', 'meals': 'this is meals', 'long': 23.5383, 'open': '0600', 'lat': 120.678, 'dist': 12245, 'cat': 1, 'images_url': {'icon': '/img/business/1/icon', 'bg': '/img/business/1/bg'}, 'features': 'this is features', 'deal': 200, 'deals': [{'description': 'Use this promo code and save on coffee, tea, and...', 'title': '10% Off Any Order'}]}}' orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) RemoveRequestArgs(field_inputs_post) j = request.get_json() orgdetailImgsUrlArgs, self.detailimgsurlargs = GetTwoLayerRequestArgs( None, field_inputs_detail_images_url, j[field_inputs_wrap_head][__head_detail_images_url__]) #self.args= {'name': 'Starbucks Coffee 1', 'description': 'early Bird Special: Get off.', 'address': 'this is address', 'close': '2200', 'meals': 'this is meals', 'long': '23.5383', 'open': '0600', 'lat': '120.678', 'dist': 12245, 'cat': 1, 'features': 'this is features', 'deal': 200, 'deals': [{'description': 'Use this promo code and save on coffee, tea, and...', 'title': '10% Off Any Order'}]} self.detailimgsurlargs= {'icon': '/img/business/1/icon', 'bg': '/img/business/1/bg'}} #print("self.args=", self.args, "self.detailimgsurlargs=", self.detailimgsurlargs) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 1.3 check name unique r = obj.query.filter(obj.name == self.args['name'], obj.isdel == False).scalar() if r is not None: return omitError('CE_NAME_CONFLICT', 'name {} conflict'.format(self.args['name'])), 400 # 2. validate follows spec if db.session.query(obj).filter(obj.isdel == False).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 r = obj() d = detail() _pics = [] _deals = [] try: _item = [] for k, v in self.args.items(): if k != "deals": _item.append((k, v)) r = PrepareObjORM(r, _item) # FIXME: hard code mapping for k, v in self.detailimgsurlargs.items(): # (1, 'icon'), (2, 'bg'), (3, 'gallery') p = pics() if k == 'icon': p.type = 1 elif k == 'bg': p.type = 2 if p.type: p.path = v _pics.append(p) for k, v in self.args.items(): if v != None: if k == 'deals': deal = deals() for v1 in v: # each entry for k2, v2 in v1.items(): setattr(deal, k2, v2) _deals.append(deal) else: setattr(d, k, v) #print("d.__dict__ = ", d.__dict__) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: db.session.add(r) # At this point, the object f has been pushed to the DB, # and has been automatically assigned a unique primary key id db.session.flush() # refresh updates given object in the session with its state in the DB # (and can also only refresh certain attributes - search for documentation) db.session.refresh(r) d.business_id = r.id #print("d.__dict__ = ", d.__dict__) db.session.add(d) for v in _deals: v.business_id = r.id db.session.add(v) for v in _pics: v.business_id = r.id db.session.add(v) db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user _d = db.session.query(detail).filter(detail.business_id == r.id).one() out = SerialObjOutput(_d, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 for k, v in field_inputs.items(): if k not in ['id', 'image_url']: next(iter(out))[field_inputs_wrap_head].update({k: orgArgs[k]}) next(iter(out))[field_inputs_wrap_head].update( {'deals': orgArgs['deals']}) next(iter(out))[field_inputs_wrap_head].update( {'images_url': orgArgs['images_url']}) next(iter(out))[field_inputs_wrap_head].update({'id': r.id}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'overview' return out
def put(self, id): """ update one item """ """update comment @api {put} /rest/customer/comment/:id create comment @apiVersion 0.0.5 @apiName UpdateComment @apiGroup campaign @apiPermission registered user @apiParam {Number} id comment id @apiDescription todo certificate with cookies / oauth 2.0<br /> todo long/lat validation<br /> todo metadata for counter of registerd devices<br /> todo error / success return code in api @apiParam {Object} data object @apiParam {String{..254}} data.content message's title @apiParam {Number} data.business_id comment belong to the business_id @apiParam {Number} data.user_id user who create it @apiParam {Number={0..5}} data.rate comment's rate @apiParam {String} type request's type @apiParam {String} subtype request's subtype @apiExample {curl} Example usage: curl -X PUT -H "mTag: xx" -H "Content-Type:application/json" -d " { "subtype":"comment", "type":"business", "data":{ "content":"Starbucks were all over Singapore and the quality ", "business_id":1, "user_id":2, "rate":1 } }" http://localhost/rest/customer/comment/1 HTTP/1.0 200 OK { "data":{ "content":"Starbucks were all over Singapore and the quality ", "user_id":1, "business_id":1, "rate":1, "mtime":"2016-08-31 04:16:42.091706", "id":2 }, "type":"business", "subtype":"comment" } @apiSuccess {Object} data object @apiSuccess {String{..254}} data.content message's title @apiSuccess {Number} data.business_id comment belong to the business_id @apiSuccess {Number} data.user_id user who create it @apiSuccess {Number} data.id comment's id @apiSuccess {String{..254}} data.mtime comment's modify time @apiSuccess {Number={0..5}} data.rate comment's rate @apiSuccess {String} type request's type @apiSuccess {String} subtype request's subtype """ # 1. parsing reqest try: orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 2. get orm from db r = obj.query.filter(obj.id == id, obj.isdel == False).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # 3. assign request data to orm try: t = datetime.utcnow() r = PrepareObjORM(r, self.args.items()) r.mtime = t except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # TODO: make sure tranaction _r = rates.query.filter(rates.user_id == self.args['user_id'], rates.business_id == self.args['business_id'], rates.isdel == False).scalar() if _r is None: return omitError( 'CE_NOT_EXIST', 'user_id {}, business_id {} '.format( self.args['user_id'], self.args['business_id'])), 400 _r.rate = self.args['rate'] # 4. commit to save try: db.session.merge(r) db.session.merge(_r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 next(iter(out))[field_inputs_wrap_head].update({'id': id}) next(iter(out))[field_inputs_wrap_head].update( {'rate': self.args['rate']}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'comment' return out
def post(self): """create data """ """create comment @api {post} /rest/customer/comments create comment @apiVersion 0.0.5 @apiName CreateComment @apiGroup campaign @apiPermission registered user @apiDescription todo certificate with cookies / oauth 2.0<br /> todo long/lat validation<br /> todo metadata for counter of registerd devices<br /> todo error / success return code in api @apiParam {Object} data object @apiParam {String{..254}} data.content message's title @apiParam {Number} data.business_id comment belong to the business_id @apiParam {Number} data.user_id user who create it @apiParam {Number={0..5}} data.rate comment's rate @apiParam {String} type request's type @apiParam {String} subtype request's subtype @apiExample {curl} Example usage: curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d " { "subtype":"comment", "type":"business", "data":{ "content":"Starbucks were all over Singapore and the quality ", "business_id":1, "user_id":2, "rate":1 } }" http://localhost/rest/customer/comments HTTP/1.0 200 OK { "data":{ "content":"Starbucks were all over Singapore and the quality ", "user_id":1, "business_id":1, "rate":1, "mtime":"2016-08-31 04:16:42.091706", "id":2 }, "type":"business", "subtype":"comment" } @apiSuccess {Object} data object @apiSuccess {String{..254}} data.content message's title @apiSuccess {Number} data.business_id comment belong to the business_id @apiSuccess {Number} data.user_id user who create it @apiSuccess {Number} data.id comment's id @apiSuccess {String{..254}} data.mtime comment's modify time @apiSuccess {Number={0..5}} data.rate comment's rate @apiSuccess {String} type request's type @apiSuccess {String} subtype request's subtype """ # 1. parsing reqest # 1.1 parsing 1st layer reqest try: #orgArgs = {'type': 'business', 'subtype': 'comment', 'data': {"content": "Starbucks were all over Singapore and the quality" ,"business_id": 1, "user_id": 1}}' orgArgs, self.args = GetTwoLayerRequestArgs( field_inputs_wrap_head, field_inputs_post) #print("self.args=", self.args) #return {}, 400 except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 1.3 check name unique r = obj.query.filter(obj.user_id == self.args['user_id'], obj.business_id == self.args['business_id'], obj.isdel == False).scalar() if r is not None: return omitError( 'CE_DATA_DUPLICATE', 'user_id {}, business_id {} are duplicate'.format( self.args['user_id'], self.args['business_id'])), 400 # 2. validate follows spec if db.session.query(obj).filter(obj.isdel == False).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 r = obj() try: r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # TODO: make sure tranaction # 1.3 check name unique _r = rates.query.filter(rates.user_id == self.args['user_id'], rates.business_id == self.args['business_id'], rates.isdel == False).scalar() if _r is not None: return omitError( 'CE_DATA_DUPLICATE', 'user_id {}, business_id {} are duplicate'.format( self.args['user_id'], self.args['business_id'])), 400 _r = rates() _r.business_id = self.args['business_id'] _r.user_id = self.args['user_id'] _r.rate = self.args['rate'] # 4. commit to save try: db.session.add(r) db.session.add(_r) db.session.flush() db.session.refresh(r) db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 next(iter(out))[field_inputs_wrap_head].update({'id': r.id}) next(iter(out))[field_inputs_wrap_head].update( {'rate': self.args['rate']}) next(iter(out))['type'] = 'business' next(iter(out))['subtype'] = 'comment' return out
def post(self, id): """regist devices to one business for push notification @api {post} /rest/pushno/reg/:id regist devices @apiVersion 0.0.4 @apiName RegistOneDevice @apiGroup pushno @apiPermission registered user @apiParam {Number} id business id, you can get from GetAllCustomerBusinesses. @apiDescription todo certificate with cookies / oauth 2.0<br /> todo long/lat validation<br /> todo metadata for counter of registerd devices<br /> todo error / success return code in api @apiParam {Object[]} devices List of devices @apiParam {Number} devices.user_id registered user id @apiParam {Number=1, 2} devices.type device's type, 1 for andriod, 2 for ios @apiParam {String{..254}} devices.dev_id device's id @apiExample {curl} Example usage: curl -X POST -H "mTag: xx" -H "Content-Type:application/json" -d " { "data":[ { "type":1, "user_id":1, "dev_id":"eh2AM5l18K8:APA91bFsjAU_FmdkdTeErJ_BRSiz7_Iipi_r12QTscHciTVJmj1gcSK_p9l6BfgYtudntv0Ht7JNiyCe8lS-WdrL8zHOwCdGFdRutEDglPV1I9EeROVbhwVX0rcd_PS_jdCTQZ22inFq" } ] }" http://localhost/rest/pushno/reg/1 """ # 1. parsing reqest try: # TODO:validate by array #orgArgs, self.args = GetTwoLayerRequestArgs(field_inputs_wrap_head, field_inputs_post) self.args = [] j = request.get_json() for v in j[field_inputs_wrap_head]: v['business_id'] = id self.args.append(v) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 2. get orm from db r = business.query.filter(business.id == id, business.isdel == False).scalar() if r is None: return omitError('CE_NOT_EXIST', 'id {} not found'.format(id)), 400 # TODO: UniqueConstraint at __pushno_tablename__ # 3. assign request data to orm _r = [] try: for v in self.args: #print("v=", v) r = obj() _r.append(PrepareObjORM(r, v.items())) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 # 4. commit to save try: for v in _r: db.session.add(v) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user # FIXME: return array out = SerialObjOutput(r, objname=field_inputs_wrap_head, resource_fields=resource_fields_post), 200 next(iter(out))['type'] = 'pushno' next(iter(out))['subtype'] = 'reg' return out
def post(self): """Create new record, the content recieve from http such as below: Cookie: sid=<string> mTag: <string> Content: { "secpolicy" : { "name" : <string>, "interface" : { "ifName" : <string> }, "srcIpGroups" : [ { "id" : <long> }, (more IpGroup objects...) ], "srcIpAddrs" : [ { "id" : <long> }, (more IpAddr objects...) ], "dstIpGroups" : [ { "id" : <long> }, (more IpGroup objects...) ], "dstIpAddrs" : [ { "id" : <long> }, (more IpAddr objects...) ], "vlanGroups" : [ { "id" : <long> }, (more VlanGroup objects...) ], "vlans" : [ { "id" : <long> }, (more Vlan objects...) ], "servGroups" : [ { "id" : <long> }, (more ServGroup objects...) ], "servs" : [ { "id" : <long> }, (more Serv objects...) ], "userGroups" : [ { "id" : <long> }, (more UserGroup objects...) ], "schds" : [ { "id" : <long> } ], "ipprofile" : { "id" : <long> }, "ipprofileLogOnly" : <boolean>, "acprofile" : { "id" : <long> }, "acprofileLogOnly" : <boolean>, "scprofile" : { "id" : <long> }, "scprofileLogOnly" : <boolean>, "action" : <string>, "logging" : <string>, "enabled" : <string>, "description" : <string> } } """ # 1. parsing reqest # 1.1 parsing 1st layer reqest try: orgArgs, self.args = GetRequestArgs(__sec_head__, field_inputs) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 # 1.2 parsing 2ed layer reqest #def t(x): # print('ooooo', x, field_inputs[x], type(field_inputs[x])) # return isinstance(field_inputs[x], set) try: #print(filter(t, field_inputs.keys()), # 'xxxx', field_inputs.items(), # dict((k, v) for k, v in field_inputs.items() if isinstance(v['validator'], set))) #for k, v in field_inputs.items(): # print('bbbbb', v, type(v)) for v in set((v) for v in set(field_inputs).intersection(orgArgs) if isinstance(field_inputs[v]['validator'], set)): #for v in dict((k, v) for k, v in field_inputs.items() # if isinstance(v['validator'], set)): #for v in filter(lambda v: isinstance(field_inputs[v], set), field_inputs): print('set(field_inputs).intersection(orgArgs)', field_inputs[v], v) _type = field_inputs[v]['validator'] validator = next(iter(_type)).container.nested.items() \ if type(_type) is set else _type.items() # validate 2ed value # if is list, such as [{id: 1, name:2}, {id: 2, name:2}] for _k, _v in validator: for __v in orgArgs[v]: if (_v.get('required', False)): _v['type'](__v[_k]) #print('self.args[v]',self.args.get(v)) #self.args[v] = [self.args.get(v, None)] self.args[v] = self.args[v] if self.args.get(v, False) else [] self.args[v].append(__v) except Exception as error: logger.debug('traceback.format_exc(%s)', traceback.format_exc()) return omitError(ErrorMsg=repr(error)), 400 logger.debug('parsed args = (%s)', self.args) # 2. validate follows spec if db.session.query(sec.id).count() > max: return omitError('CE_EXCEED_LIMIT', 'limit is {}'.format(max)), 400 # 3. assign request data to orm r = sec() try: print(type(self.args.items()), self.args.items()) r = PrepareObjORM(r, self.args.items()) except Exception as error: return omitError(ErrorMsg=repr(error)), 400 print('self.args.items()=', self.args.items()) # 4. commit to save try: db.session.add(r) db.session.flush() db.session.commit() except Exception as error: db.session.rollback() logger.warning('session commit error(%s)', error) if exc.IntegrityError == type(error): return omitError('CE_NAME_CONFLICT', repr(error)), 400 return omitError(ErrorMsg=repr(error)), 400 # 5. return all data to user return SerialObjOutput(r, resource_fields=resource_fields), 200