<s> import re <EOL> import sys <EOL> import json <EOL> import time <EOL> import inspect <EOL> import datetime <EOL> from django . http import HttpResponse <EOL> import httpStatusCodes <EOL> import globalVariables as globVars <EOL> import validatorFunctions as vFuncs <EOL> DEVELOPER_MODE = True <EOL> isCallable = lambda a : hasattr ( a , '<STR_LIT>' ) <EOL> isCallableAttr = lambda obj , attr : hasattr ( obj , attr ) and isCallable ( getattr ( obj , attr ) ) <EOL> isImmutableAttr = lambda s : s . startswith ( '<STR_LIT:_>' ) or s in onlyServerCanWrite <EOL> isMutableAttr = lambda s : not isImmutableAttr ( s ) <EOL> setSuffixCompile = re . compile ( globVars . SET_SUFFIX_RE , re . UNICODE ) <EOL> __TABLE_CACHE__ = dict ( ) <EOL> trivialSerialzdDict = { <EOL> lambda e : e is None : lambda e : "<STR_LIT:null>" , <EOL> lambda s : hasattr ( s , globVars . NUMERICAL_DIV_ATTR ) : str , <EOL> lambda s : isinstance ( s , datetime . date ) : lambda s : str ( s . strftime ( '<STR_LIT:%s>' ) ) <EOL> } <EOL> tableDefinitions = dict ( ) <EOL> onlyServerCanWrite = [ <EOL> globVars . ID_KEY , globVars . DATE_CREATED_KEY , globVars . LAST_EDIT_TIME_KEY <EOL> ] <EOL> sortKeyCompile = re . compile ( <EOL> r"<STR_LIT>" % ( globVars . REVERSE_KEY ) , re . UNICODE | re . IGNORECASE <EOL> ) <EOL> pyVersion = sys . version_info . major <EOL> if pyVersion >= <NUM_LIT:3> : <EOL> byteFyArgs = { '<STR_LIT>' : '<STR_LIT:utf-8>' } <EOL> else : <EOL> byteFyArgs = { } <EOL> byteFy = lambda byteableObj : bytes ( byteableObj , ** byteFyArgs ) <EOL> def translateSortKey ( sortKey ) : <EOL> if not sortKey : <EOL> return globVars . ID_KEY , True <EOL> sortKeySearch = sortKeyCompile . search ( sortKey ) <EOL> if sortKeySearch : <EOL> return sortKeySearch . groups ( <NUM_LIT:1> ) [ <NUM_LIT:0> ] , True <EOL> else : <EOL> return sortKey , False <EOL> def attemptJSONParse ( strContent ) : <EOL> outCode = httpStatusCodes . BAD_REQUEST <EOL> deserial = None <EOL> try : <EOL> deserial = json . loads ( strContent ) <EOL> except Exception as e : <EOL> deserial = e <EOL> outCode = httpStatusCodes . INTERNAL_SERVER_ERROR <EOL> else : <EOL> outCode = httpStatusCodes . OK <EOL> finally : <EOL> return outCode , deserial <EOL> def _altParseRequestBody ( request , methodName , mustHaveContent = False ) : <EOL> if not mustHaveContent : <EOL> mustHaveContent = methodName == globVars . POST_KEY <EOL> if methodName != globVars . PUT_KEY : <EOL> reqBody = getattr ( request , methodName , None ) <EOL> else : <EOL> reqBody = request . GET <EOL> qParams = reqBody . get ( '<STR_LIT>' , '<STR_LIT:{}>' ) <EOL> uBody = reqBody . get ( '<STR_LIT>' , '<STR_LIT:{}>' ) <EOL> try : <EOL> updateParams = json . loads ( uBody ) <EOL> queryParams = json . loads ( qParams ) <EOL> except Exception , e : <EOL> print ( '<STR_LIT>' , e ) <EOL> reqBody = None <EOL> else : <EOL> reqBody = dict ( queryParams = queryParams , updateParams = updateParams ) <EOL> if not reqBody : <EOL> if reqBody is None or mustHaveContent : <EOL> data = request . read ( ) if pyVersion < <NUM_LIT:3> else request . read ( ) . decode ( ) <EOL> if not data : <EOL> reqBody = request . GET <EOL> else : <EOL> status , deserialized = attemptJSONParse ( data ) <EOL> if status == httpStatusCodes . OK : <EOL> reqBody = deserialized <EOL> else : <EOL> return status , deserialized <EOL> return httpStatusCodes . OK , reqBody <EOL> def isSerializable ( pyObj ) : <EOL> try : iter ( pyObj ) <EOL> except : return False <EOL> else : return True <EOL> def getTablesInModels ( models ) : <EOL> tableNameToTypeDict = __TABLE_CACHE__ . get ( models , None ) <EOL> if tableNameToTypeDict is None : <EOL> tableNameToTypeDict = dict ( ) <EOL> for elem in inspect . getmembers ( models , inspect . isclass ) : <EOL> name , obj = elem <EOL> tableNameToTypeDict [ name ] = obj <EOL> __TABLE_CACHE__ [ models ] = tableNameToTypeDict <EOL> return tableNameToTypeDict <EOL> def captureUserMutableAttrsFromObj ( samplerObj , mapUnderInspection ) : <EOL> return captureUserMutableAttrs ( getUserMutableFilters ( samplerObj ) , mapUnderInspection ) <EOL> def captureUserMutableAttrs ( objEditableAttrs , mapUnderInspection ) : <EOL> if not isCallableAttr ( mapUnderInspection , '<STR_LIT>' ) : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> mappedValues = tuple ( ) <EOL> for key in objEditableAttrs : <EOL> retrV = mapUnderInspection . get ( key , None ) <EOL> if retrV is not None : <EOL> mappedValues += ( ( key , retrV , ) , ) <EOL> return mappedValues <EOL> def getTableObjByKey ( tableKeyName , models = None ) : <EOL> if not tableKeyName : <EOL> return None <EOL> else : <EOL> tablesInDB = getTablesInModels ( models ) <EOL> return tablesInDB . get ( tableKeyName , None ) <EOL> def getSerializableElems ( pyObj , salvageConverters = trivialSerialzdDict ) : <EOL> if not pyObj : <EOL> return { } <EOL> if hasattr ( pyObj , '<STR_LIT>' ) : <EOL> dictRepr = pyObj . __dict__ <EOL> else : <EOL> dictRepr = pyObj <EOL> objDict = { } <EOL> for key , value in dictRepr . items ( ) : <EOL> if isSerializable ( value ) : <EOL> objDict [ key ] = value <EOL> else : <EOL> serializedValue = passBasedOffFunc ( value , salvageConverters ) <EOL> if serializedValue : <EOL> objDict [ key ] = serializedValue <EOL> return objDict <EOL> def passBasedOffFunc ( value , salvageConverters ) : <EOL> if not salvageConverters : <EOL> return False <EOL> for quantifier , converter in salvageConverters . items ( ) : <EOL> if inspect . isfunction ( quantifier ) and quantifier ( value ) : <EOL> converted = converter ( value ) <EOL> if isSerializable ( converted ) : return converted <EOL> def suffixStrip ( key , suffix ) : <EOL> if not ( key and suffix ) : return None <EOL> beforeSuffixSearch = re . search ( "<STR_LIT>" % ( suffix ) , key ) <EOL> if not beforeSuffixSearch : return None <EOL> return beforeSuffixSearch . groups ( <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> def matchTable ( tableKey , models ) : <EOL> allTables = getTablesInModels ( models ) <EOL> for key in allTables : <EOL> if re . search ( "<STR_LIT>" % ( tableKey ) , key , re . IGNORECASE ) : <EOL> return allTables . get ( key ) <EOL> def getForeignKeys ( queryTable ) : <EOL> return filter ( <EOL> lambda attr : attr . endswith ( globVars . ID_SUFFIX ) , queryTable <EOL> ) <EOL> def getForeignKeyElems ( pyObj , parentMap = { } , models = None ) : <EOL> if not pyObj : <EOL> return None <EOL> if pyObj . __hash__ : <EOL> hashOfObj = hash ( pyObj ) <EOL> if hashOfObj in parentMap : <EOL> return None <EOL> parentMap [ hashOfObj ] = hashOfObj <EOL> foreignKeys = getForeignKeys ( <EOL> pyObj . __dict__ if hasattr ( pyObj , '<STR_LIT>' ) else pyObj <EOL> ) <EOL> if not foreignKeys : return None <EOL> dataDict = dict ( ) <EOL> for foreignKey in foreignKeys : <EOL> foreignId = getattr ( pyObj , foreignKey , None ) <EOL> if not foreignId : continue <EOL> tableName = suffixStrip ( foreignKey , globVars . ID_SUFFIX ) <EOL> tablePrototype = matchTable ( tableName , models = None ) <EOL> if not tablePrototype : continue <EOL> connObjs = tablePrototype . objects . filter ( ( globVars . ID_KEY , foreignId ) ) <EOL> if not connObjs : continue <EOL> connObj = connObjs [ <NUM_LIT:0> ] <EOL> if connObj . __hash__ and ( hash ( connObj ) in parentMap ) : <EOL> continue <EOL> serializdDict = getSerializableElems ( connObj ) <EOL> dataDict [ tableName ] = serializdDict <EOL> return dataDict <EOL> def getConnectedElems ( pyObj , alreadyVisited , models ) : <EOL> if not pyObj : <EOL> return None <EOL> objsets = [ attr for attr in dir ( pyObj ) if setSuffixCompile . search ( attr ) ] <EOL> setElemsDict = dict ( ) <EOL> for objset in objsets : <EOL> connElems = getattr ( pyObj , objset , None ) <EOL> if not isCallableAttr ( connElems , '<STR_LIT:all>' ) : <EOL> continue <EOL> objList = list ( ) <EOL> for connElem in connElems . all ( ) : <EOL> serializDict = getSerializableElems ( connElem ) <EOL> if not serializDict : <EOL> continue <EOL> objHash = hash ( pyObj ) <EOL> if objHash in alreadyVisited : <EOL> continue <EOL> alreadyVisited [ objHash ] = objHash <EOL> connConnElems = getForeignKeyElems ( connElem , alreadyVisited , models ) <EOL> refObjs = getConnectedElems ( connElem , alreadyVisited , models ) <EOL> if refObjs : <EOL> serializDict . update ( refObjs ) <EOL> if connConnElems : <EOL> serializDict . update ( connConnElems ) <EOL> objList . append ( serializDict ) <EOL> setElemsDict [ objset ] = objList <EOL> return setElemsDict <EOL> def getTableByKey ( tableName , models ) : <EOL> if tableName : <EOL> tables = getTablesInModels ( models ) <EOL> return tables . get ( tableName , None ) <EOL> def updateTable ( tableObj , bodyFromRequest , updateBool = False ) : <EOL> if not ( tableObj and bodyFromRequest ) : <EOL> return None <EOL> errorID = - <NUM_LIT:1> <EOL> changeCount = duplicatesCount = <NUM_LIT:0> <EOL> if not isinstance ( bodyFromRequest , dict ) : <EOL> print ( "<STR_LIT>" ) <EOL> return errorID , changeCount , duplicatesCount <EOL> allowedKeys = None <EOL> if not updateBool : <EOL> objectToChange = tableObj ( ) <EOL> updateParams = bodyFromRequest <EOL> allowedKeys = getUserMutableFilters ( objectToChange ) <EOL> else : <EOL> queryParams = bodyFromRequest . get ( '<STR_LIT>' , None ) <EOL> if not isinstance ( queryParams , dict ) : <EOL> print ( '<STR_LIT>' ) <EOL> return errorID , changeCount , duplicatesCount <EOL> elif tableObj . objects . count ( ) < <NUM_LIT:1> : <EOL> return errorID , changeCount , duplicatesCount <EOL> else : <EOL> allowedFilters = captureUserMutableAttrsFromObj ( <EOL> tableObj . objects . first ( ) , queryParams ) <EOL> objMatch = tableObj . objects . filter ( * allowedFilters ) <EOL> if not objMatch : <EOL> print ( <EOL> '<STR_LIT>' , queryParams ) <EOL> return errorID , changeCount , duplicatesCount <EOL> else : <EOL> allowedKeys = getUserMutableFilters ( objMatch [ <NUM_LIT:0> ] ) <EOL> if objMatch . count ( ) == <NUM_LIT:1> : <EOL> objectToChange = objMatch [ <NUM_LIT:0> ] <EOL> else : <EOL> objectToChange = objMatch <EOL> updateParams = bodyFromRequest . get ( '<STR_LIT>' , None ) <EOL> if updateParams is None : <EOL> updateParams = { } <EOL> cherryPickedAttrs = dict ( <EOL> ( str ( k ) , updateParams [ k ] ) for k in updateParams if isMutableAttr ( k ) and k in allowedKeys <EOL> ) <EOL> if isCallableAttr ( objectToChange , '<STR_LIT>' ) : <EOL> objectToChange . update ( ** cherryPickedAttrs ) <EOL> changeCount = objectToChange . count ( ) <EOL> return changeCount , changeCount , - <NUM_LIT:1> <EOL> else : <EOL> for attr in cherryPickedAttrs : <EOL> attr = str ( attr ) <EOL> attrValue = updateParams . get ( attr ) <EOL> if updateBool : <EOL> origValue = getattr ( objectToChange , attr , None ) <EOL> if ( attrValue == origValue ) : <EOL> duplicatesCount += <NUM_LIT:1> <EOL> continue <EOL> setattr ( objectToChange , attr , attrValue ) <EOL> changeCount += <NUM_LIT:1> <EOL> if not changeCount : <EOL> return objectToChange . id , changeCount , duplicatesCount <EOL> else : <EOL> savedBoolean = saveToMemory ( objectToChange ) <EOL> if savedBoolean : <EOL> return objectToChange . id , changeCount , duplicatesCount <EOL> else : <EOL> return errorID , - <NUM_LIT:1> , - <NUM_LIT:1> <EOL> def deleteByAttrs ( objProtoType , attrDict ) : <EOL> if not objProtoType : <EOL> msg = "<STR_LIT>" <EOL> print ( msg , "<STR_LIT>" , objProtoType ) <EOL> return dict ( <EOL> successful = [ ] , failed = [ ] , id = globVars . DELETION_FAILURE_CODE , msg = msg ) <EOL> elif not isinstance ( attrDict , dict ) : <EOL> msg = '<STR_LIT>' <EOL> print ( msg ) <EOL> return dict ( <EOL> successful = [ ] , failed = [ ] , id = globVars . DELETION_FAILURE_CODE , msg = msg ) <EOL> else : <EOL> tupledIdentifiers = tuple ( attrDict . items ( ) ) <EOL> matchedElems = objProtoType . objects . filter ( * tupledIdentifiers ) <EOL> if not matchedElems : <EOL> msg = "<STR_LIT>" <EOL> print ( msg , tupledIdentifiers ) <EOL> return dict ( successful = [ ] , failed = [ ] , msg = msg ) <EOL> else : <EOL> failed , successful = [ ] , [ ] <EOL> for elem in matchedElems : <EOL> elemId = elem . id <EOL> selector = failed <EOL> try : <EOL> elem . delete ( ) <EOL> selector = successful <EOL> except Exception , ex : <EOL> print ( ex ) <EOL> finally : <EOL> selector . append ( elemId ) <EOL> return dict ( successful = successful , failed = failed ) <EOL> def saveToMemory ( newObj ) : <EOL> if not hasattr ( newObj , '<STR_LIT>' ) : <EOL> return False <EOL> savedBool = False <EOL> try : <EOL> newObj . save ( ) <EOL> except Exception , ex : <EOL> print ( ex ) <EOL> else : <EOL> savedBool = True <EOL> return savedBool <EOL> def handleHTTPRequest ( request , tableName , models ) : <EOL> startTime = time . time ( ) <EOL> requestMethod = request . method <EOL> resultsDict = None <EOL> response = HttpResponse ( ) <EOL> statusCode = httpStatusCodes . BAD_REQUEST <EOL> parseStatus , content = _altParseRequestBody ( request , requestMethod ) <EOL> if parseStatus != httpStatusCodes . OK : <EOL> statusCode = httpStatusCodes . BAD_REQUEST <EOL> resultsDict = { '<STR_LIT>' : '<STR_LIT>' } <EOL> else : <EOL> tableProtoType = getTableByKey ( tableName , models ) <EOL> if requestMethod == globVars . GET_KEY : <EOL> statusCode , resultsDict = handleGET ( content , tableProtoType , models ) <EOL> elif requestMethod == globVars . POST_KEY : <EOL> statusCode , resultsDict = handlePOST ( content , tableProtoType ) <EOL> elif requestMethod == globVars . DELETE_KEY : <EOL> statusCode , resultsDict = handleDELETE ( content , tableProtoType ) <EOL> elif requestMethod == globVars . PUT_KEY : <EOL> statusCode , resultsDict = handlePUT ( content , tableProtoType ) <EOL> else : <EOL> resultsDict = { '<STR_LIT>' : '<STR_LIT>' } <EOL> statusCode = httpStatusCodes . METHOD_NOT_ALLOWED <EOL> addTypeInfo ( resultsDict ) <EOL> response . status_code = statusCode <EOL> resultsDict [ '<STR_LIT>' ] = time . time ( ) - startTime <EOL> response . write ( json . dumps ( resultsDict ) ) <EOL> return response <EOL> def getUserMutableFilters ( tableProtoType ) : <EOL> if not tableProtoType : <EOL> return None <EOL> else : <EOL> userDefFields = __TABLE_CACHE__ . get ( tableProtoType , None ) <EOL> if userDefFields is None : <EOL> objDict = tableProtoType . __dict__ <EOL> userDefFields = tuple ( attr for attr in objDict if isMutableAttr ( attr ) ) <EOL> __TABLE_CACHE__ [ tableProtoType ] = userDefFields <EOL> return userDefFields <EOL> def addTypeInfo ( outDict ) : <EOL> if isinstance ( outDict , dict ) : <EOL> outDict [ "<STR_LIT>" ] = "<STR_LIT>" <EOL> outDict [ "<STR_LIT>" ] = "<STR_LIT:application/json>" <EOL> outDict [ "<STR_LIT>" ] = getCurrentTime ( ) <EOL> def getCurrentTime ( ) : <EOL> return time . time ( ) <EOL> def currentTime ( request ) : <EOL> response = HttpResponse ( ) <EOL> response . write ( json . dumps ( dict ( time = getCurrentTime ( ) ) ) ) <EOL> return response <EOL> def handlePUT ( putBody , tableProtoType ) : <EOL> results = updateTable ( <EOL> tableProtoType , bodyFromRequest = putBody , updateBool = True <EOL> ) <EOL> if results : <EOL> changedID , changeCount , duplicatesCount = results <EOL> return httpStatusCodes . OK , dict ( <EOL> id = changedID , changeCount = changeCount , duplicatesCount = duplicatesCount <EOL> ) <EOL> else : <EOL> return httpStatusCodes . BAD_REQUEST , dict ( id = - <NUM_LIT:1> ) <EOL> def handleGET ( getBody , tableObj , models = None ) : <EOL> if not tableObj : <EOL> print ( "<STR_LIT>" ) <EOL> return httpStatusCodes . NOT_FOUND , { '<STR_LIT>' : "<STR_LIT>" } <EOL> tableObjManager = tableObj . objects <EOL> objCount = tableObjManager . count ( ) <EOL> objProto = tableObj ( ) <EOL> bodyAttrs = getUserMutableFilters ( objProto ) <EOL> dbObjs = tableObjManager <EOL> nFiltrations = <NUM_LIT:0> <EOL> allowedFilters = captureUserMutableAttrs ( bodyAttrs , getBody ) <EOL> if '<STR_LIT:id>' in getBody : <EOL> cId = None <EOL> rId = getBody [ '<STR_LIT:id>' ] <EOL> if vFuncs . isUIntLike ( rId ) : <EOL> cId = rId <EOL> elif type ( rId ) == '<STR_LIT:list>' and len ( rId ) : <EOL> cId = rId [ <NUM_LIT:0> ] <EOL> if cId is not None : <EOL> allowedFilters += ( ( '<STR_LIT:id>' , int ( cId ) ) , ) <EOL> selectAttrs = getBody . get ( globVars . SELECT_KEY , None ) <EOL> selectKeys = None <EOL> if selectAttrs : <EOL> splitKeys = selectAttrs . split ( '<STR_LIT:U+002C>' ) <EOL> if globVars . ID_KEY not in splitKeys : <EOL> splitKeys . append ( globVars . ID_KEY ) <EOL> selectKeys = tuple ( key for key in splitKeys if key in bodyAttrs ) <EOL> bodyAttrs = selectKeys <EOL> dbObjs = dbObjs . values ( * selectKeys ) . all ( ) if not allowedFilters else dbObjs . values ( * selectKeys ) . filter ( * allowedFilters ) <EOL> else : <EOL> dbObjs = dbObjs . filter ( * allowedFilters ) <EOL> limit = getBody . get ( globVars . LIMIT_KEY , None ) <EOL> if limit is None : <EOL> limit = <NUM_LIT:0> <EOL> elif not vFuncs . isUIntLike ( limit ) : <EOL> limit = globVars . THRESHOLD_LIMIT <EOL> else : <EOL> limit = int ( limit ) <EOL> offSet = getBody . get ( globVars . OFFSET_KEY , None ) <EOL> if not ( offSet and vFuncs . isUIntLike ( offSet ) ) : <EOL> offSet = globVars . THRESHOLD_OFFSET <EOL> else : <EOL> offSet = int ( offSet ) <EOL> maxSize = dbObjs . count ( ) <EOL> if limit > maxSize : <EOL> limit = maxSize <EOL> elif limit : <EOL> limit += offSet <EOL> sortKey = getBody . get ( globVars . SORT_KEY , None ) <EOL> sortKey , reverseTrue = translateSortKey ( sortKey ) <EOL> if sortKey not in bodyAttrs : <EOL> sortKey = "<STR_LIT>" % ( globVars . ID_KEY ) <EOL> elif reverseTrue : <EOL> sortKey = "<STR_LIT>" % ( sortKey ) <EOL> formatKey = getBody . get ( globVars . FORMAT_KEY , globVars . LONG_FMT_KEY ) <EOL> connectedObjsBool = re . search ( formatKey , globVars . SHORT_FMT_KEY ) == None <EOL> data = list ( ) <EOL> if not limit : <EOL> dbObjIterator = dbObjs . order_by ( sortKey ) [ offSet : ] <EOL> else : <EOL> dbObjIterator = dbObjs . order_by ( sortKey ) [ offSet : limit ] <EOL> foreignVisited = { } <EOL> connectedVisited = { } <EOL> idMap = { } <EOL> for dbObj in dbObjIterator : <EOL> connmap = { } <EOL> foreignKeyElems = getForeignKeyElems ( dbObj , foreignVisited , models = models ) <EOL> if foreignKeyElems : <EOL> connmap . update ( foreignKeyElems ) <EOL> if connectedObjsBool : <EOL> connElems = getConnectedElems ( dbObj , connectedVisited , models ) <EOL> if connElems : <EOL> connmap . update ( connElems ) <EOL> if hasattr ( dbObj , '<STR_LIT:id>' ) : <EOL> itemId = dbObj . id <EOL> else : <EOL> itemId = dbObj . get ( '<STR_LIT:id>' , None ) <EOL> if itemId is None : <EOL> continue <EOL> idMap [ itemId ] = connmap <EOL> qs = dbObjIterator . values ( '<STR_LIT:id>' , * bodyAttrs ) <EOL> for item in qs : <EOL> itId = item . get ( '<STR_LIT:id>' , - <NUM_LIT:1> ) <EOL> retrObj = idMap . get ( itId , { } ) <EOL> if retrObj : <EOL> item . update ( retrObj ) <EOL> data = [ getSerializableElems ( qi ) for qi in qs ] <EOL> metaDict = dict ( <EOL> collectionCount = objCount , count = len ( data ) , <EOL> format = formatKey , sort = sortKey , limit = limit , offset = offSet <EOL> ) <EOL> if selectKeys : <EOL> metaDict [ globVars . SELECT_KEY ] = selectKeys <EOL> return httpStatusCodes . OK , dict ( meta = metaDict , data = data ) <EOL> def handlePOST ( postBody , tableProtoType ) : <EOL> statusCode = httpStatusCodes . BAD_REQUEST <EOL> results = updateTable ( <EOL> tableProtoType , bodyFromRequest = postBody , updateBool = False <EOL> ) <EOL> resultsDict = dict ( ) <EOL> if results : <EOL> changedID , changeCount , duplicatesCount = results <EOL> resultsDict = { <EOL> '<STR_LIT:data>' : { <EOL> '<STR_LIT:id>' : changedID , '<STR_LIT>' : changeCount , '<STR_LIT>' : duplicatesCount <EOL> } <EOL> } <EOL> statusCode = httpStatusCodes . OK <EOL> return statusCode , resultsDict <EOL> def handleDELETE ( deleteBody , tableProtoType ) : <EOL> return httpStatusCodes . OK , dict ( data = deleteByAttrs ( tableProtoType , deleteBody ) ) </s>
