<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def put_stream(self, rel_path, metadata=None, cb=None):
 """return a file object to write into the cache. The caller is responsibile for closing the stream """

        from io import IOBase

        if not isinstance(rel_path, basestring):
            rel_path = rel_path.cache_key

        repo_path = os.path.join(self.cache_dir, rel_path.strip("/"))

        if not os.path.isdir(os.path.dirname(repo_path)):
            os.makedirs(os.path.dirname(repo_path))

        if os.path.exists(repo_path):
            os.remove(repo_path)

        sink = open(repo_path, 'wb')

        upstream = self.upstream

        class flo(IOBase):

            '''This File-Like-Object class ensures that the file is also
            sent to the upstream after it is stored in the FSCache. '''

            def __init__(self, sink, upstream, repo_path, rel_path):

                self._sink = sink
                self._upstream = upstream
                self._repo_path = repo_path
                self._rel_path = rel_path

            @property
            def rel_path(self):
                return self._rel_path

            def write(self, str_):
                self._sink.write(str_)

            def close(self):
                if not self._sink.closed:
                    # print "Closing put_stream.flo {}
                    # is_closed={}!".format(self._repo_path, self._sink.closed)

                    self._sink.close()

                    if self._upstream and not self._upstream.readonly and not self._upstream.usreadonly:
                        self._upstream.put(
                            self._repo_path,
                            self._rel_path,
                            metadata=metadata)

            def __enter__(self): # Can be used as a context!
                return self

            def __exit__(self, type_, value, traceback):
                if type_:
                    return False

                self.close()

        self.put_metadata(rel_path, metadata)

        return flo(sink, upstream, repo_path, rel_path)