<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read(self, fh, api_version=None):
 """Read info.json from file like object. Parameters: fh -- file like object supporting fh.read() api_version -- IIIF Image API version expected If api_version is set then the parsing will assume this API version, else the version will be determined from the incoming data. NOTE that the value of self.api_version is NOT used in this routine. If an api_version is specified and there is a @context specified then an IIIFInfoError will be raised unless these match. If no known @context is present and no api_version set then an IIIFInfoError will be raised. """

        j = json.load(fh)
        #
        # @context and API version
        self.context = None
        if (api_version == '1.0'):
            # v1.0 did not have a @context so we simply take the version
            # passed in
            self.api_version = api_version
        elif ('@context' in j):
            # determine API version from context
            self.context = j['@context']
            api_version_read = None
            for v in CONF:
                if (v > '1.0' and self.context == CONF[v]['context']):
                    api_version_read = v
                    break
            if (api_version_read is None):
                raise IIIFInfoError(
                    "Unknown @context, cannot determine API version (%s)" %
                    (self.context))
            else:
                if (api_version is not None and
                        api_version != api_version_read):
                    raise IIIFInfoError(
                        "Expected API version '%s' but got @context for API version '%s'" %
                        (api_version, api_version_read))
                else:
                    self.api_version = api_version_read
        else:  # no @context and not 1.0
            if (api_version is None):
                raise IIIFInfoError("No @context (and no default given)")
            self.api_version = api_version
        self.set_version_info()
        #
        # @id or identifier
        if (self.api_version == '1.0'):
            if ('identifier' in j):
                self.id = j['identifier']
            else:
                raise IIIFInfoError("Missing identifier in info.json")
        else:
            if ('@id' in j):
                self.id = j['@id']
            else:
                raise IIIFInfoError("Missing @id in info.json")
        #
        # other params
        for param in self.params:
            if (param == 'identifier'):
                continue  # dealt with above
            if (param in j):
                if (param in self.complex_params):
                    # use function ref in complex_params to parse, optional
                    # dst to map to a different property name
                    self._setattr(param, self.complex_params[
                                  param](self, j[param]))
                else:
                    self._setattr(param, j[param])
        return True