<s> import collections <EOL> from rest_framework . parsers import JSONParser <EOL> from rest_framework . exceptions import ParseError <EOL> from api . base . utils import is_bulk_request <EOL> from api . base . renderers import JSONAPIRenderer <EOL> from api . base . exceptions import JSONAPIException <EOL> NO_ATTRIBUTES_ERROR = '<STR_LIT>' <EOL> NO_RELATIONSHIPS_ERROR = '<STR_LIT>' <EOL> NO_DATA_ERROR = '<STR_LIT>' <EOL> NO_TYPE_ERROR = '<STR_LIT>' <EOL> NO_ID_ERROR = '<STR_LIT>' <EOL> class JSONAPIParser ( JSONParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT>' <EOL> renderer_class = JSONAPIRenderer <EOL> def flatten_relationships ( self , relationships ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( relationships , dict ) : <EOL> raise ParseError ( ) <EOL> related_resource = relationships . keys ( ) [ <NUM_LIT:0> ] <EOL> if not isinstance ( relationships [ related_resource ] , dict ) or related_resource == '<STR_LIT:data>' : <EOL> raise ParseError ( ) <EOL> data = relationships [ related_resource ] . get ( '<STR_LIT:data>' ) <EOL> if not data : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' . format ( related_resource ) } , detail = NO_DATA_ERROR ) <EOL> target_type = data . get ( '<STR_LIT:type>' ) <EOL> if not target_type : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' . format ( related_resource ) } , detail = NO_TYPE_ERROR ) <EOL> id = data . get ( '<STR_LIT:id>' ) <EOL> return { '<STR_LIT:id>' : id , '<STR_LIT>' : target_type } <EOL> def flatten_data ( self , resource_object , parser_context , is_list ) : <EOL> """<STR_LIT>""" <EOL> relationships = resource_object . get ( '<STR_LIT>' ) <EOL> is_relationship = parser_context . get ( '<STR_LIT>' ) <EOL> request_method = parser_context [ '<STR_LIT>' ] . method <EOL> if is_relationship and request_method == '<STR_LIT:POST>' : <EOL> if not relationships : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_RELATIONSHIPS_ERROR ) <EOL> else : <EOL> if "<STR_LIT>" not in resource_object and request_method != '<STR_LIT>' : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_ATTRIBUTES_ERROR ) <EOL> object_id = resource_object . get ( '<STR_LIT:id>' ) <EOL> object_type = resource_object . get ( '<STR_LIT:type>' ) <EOL> if is_list and request_method == '<STR_LIT>' : <EOL> if object_id is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_ID_ERROR ) <EOL> if object_type is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_TYPE_ERROR ) <EOL> attributes = resource_object . get ( '<STR_LIT>' ) <EOL> parsed = { '<STR_LIT:id>' : object_id , '<STR_LIT:type>' : object_type } <EOL> if attributes : <EOL> parsed . update ( attributes ) <EOL> if relationships : <EOL> relationships = self . flatten_relationships ( relationships ) <EOL> parsed . update ( relationships ) <EOL> return parsed <EOL> def parse ( self , stream , media_type = None , parser_context = None ) : <EOL> """<STR_LIT>""" <EOL> result = super ( JSONAPIParser , self ) . parse ( stream , media_type = media_type , parser_context = parser_context ) <EOL> if not isinstance ( result , dict ) : <EOL> raise ParseError ( ) <EOL> data = result . get ( '<STR_LIT:data>' , { } ) <EOL> if data : <EOL> if is_bulk_request ( parser_context [ '<STR_LIT>' ] ) : <EOL> if not isinstance ( data , list ) : <EOL> raise ParseError ( '<STR_LIT>' ) <EOL> data_collection = [ ] <EOL> data_collection . extend ( [ self . flatten_data ( data_object , parser_context , is_list = True ) for data_object in data ] ) <EOL> return data_collection <EOL> else : <EOL> if not isinstance ( data , collections . Mapping ) : <EOL> raise ParseError ( '<STR_LIT>' ) <EOL> return self . flatten_data ( data , parser_context , is_list = False ) <EOL> else : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_DATA_ERROR ) <EOL> class JSONAPIParserForRegularJSON ( JSONAPIParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT:application/json>' <EOL> class JSONAPIRelationshipParser ( JSONParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT>' <EOL> def parse ( self , stream , media_type = None , parser_context = None ) : <EOL> res = super ( JSONAPIRelationshipParser , self ) . parse ( stream , media_type , parser_context ) <EOL> if not isinstance ( res , dict ) : <EOL> raise ParseError ( '<STR_LIT>' ) <EOL> data = res . get ( '<STR_LIT:data>' ) <EOL> if data : <EOL> if not isinstance ( data , list ) : <EOL> raise ParseError ( '<STR_LIT>' ) <EOL> for i , datum in enumerate ( data ) : <EOL> if datum . get ( '<STR_LIT:id>' ) is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' . format ( str ( i ) ) } , detail = NO_ID_ERROR ) <EOL> if datum . get ( '<STR_LIT:type>' ) is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' . format ( str ( i ) ) } , detail = NO_TYPE_ERROR ) <EOL> return { '<STR_LIT:data>' : data } <EOL> return { '<STR_LIT:data>' : [ ] } <EOL> class JSONAPIRelationshipParserForRegularJSON ( JSONAPIRelationshipParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT:application/json>' <EOL> class JSONAPIOnetoOneRelationshipParser ( JSONParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT>' <EOL> def parse ( self , stream , media_type = None , parser_context = None ) : <EOL> res = super ( JSONAPIOnetoOneRelationshipParser , self ) . parse ( stream , media_type , parser_context ) <EOL> if not isinstance ( res , dict ) : <EOL> raise ParseError ( '<STR_LIT>' ) <EOL> data = res . get ( '<STR_LIT:data>' ) <EOL> if data : <EOL> id_ = data . get ( '<STR_LIT:id>' ) <EOL> type_ = data . get ( '<STR_LIT:type>' ) <EOL> if id_ is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_ID_ERROR ) <EOL> if type_ is None : <EOL> raise JSONAPIException ( source = { '<STR_LIT>' : '<STR_LIT>' } , detail = NO_TYPE_ERROR ) <EOL> return data <EOL> return { '<STR_LIT:type>' : None , '<STR_LIT:id>' : None } <EOL> class JSONAPIOnetoOneRelationshipParserForRegularJSON ( JSONAPIOnetoOneRelationshipParser ) : <EOL> """<STR_LIT>""" <EOL> media_type = '<STR_LIT:application/json>' </s>
