def push_blob(self,<EOL>filename=None,<EOL>progress=None,<EOL>data=None, digest=None,<EOL>check_exists=True):<EOL>
if filename is None:<EOL><INDENT>dgst = digest<EOL><DEDENT>else:<EOL><INDENT>dgst = hash_file(filename)<EOL><DEDENT>if check_exists:<EOL><INDENT>try:<EOL><INDENT>self._request('<STR_LIT>', '<STR_LIT>' + dgst)<EOL>return dgst<EOL><DEDENT>except requests.exceptions.HTTPError as ex:<EOL><INDENT>if ex.response.status_code != requests.codes.not_found:<EOL><INDENT>raise<EOL><DEDENT><DEDENT><DEDENT>r = self._request('<STR_LIT>', '<STR_LIT>')<EOL>upload_url = r.headers['<STR_LIT>']<EOL>url_parts = list(urlparse.urlparse(upload_url))<EOL>query = urlparse.parse_qs(url_parts[<NUM_LIT:4>])<EOL>query.update({'<STR_LIT>': dgst})<EOL>url_parts[<NUM_LIT:4>] = urlencode(query, True)<EOL>url_parts[<NUM_LIT:0>] = '<STR_LIT:http>' if self._insecure else '<STR_LIT>'<EOL>upload_url = urlparse.urlunparse(url_parts)<EOL>if filename is None:<EOL><INDENT>data = _ReportingChunks(dgst, data, progress) if progress else data<EOL>self._base_request('<STR_LIT>', upload_url, data=data)<EOL><DEDENT>else:<EOL><INDENT>with open(filename, '<STR_LIT:rb>') as f:<EOL><INDENT>data = _ReportingFile(dgst, f, progress) if progress else f<EOL>self._base_request('<STR_LIT>', upload_url, data=data)<EOL><DEDENT><DEDENT>return dgst<EOL>
Upload a file to the registry and return its (SHA-256) hash.

The registry is content-addressable so the file's content (aka blob)
can be retrieved later by passing the hash to :meth:`pull_blob`.

:param filename: File to upload.
:type filename: str

:param data: Data to upload if ``filename`` isn't given. The data is uploaded in chunks and you must also pass ``digest``.
:type data: Generator or iterator

:param digest: Hash of the data to be uploaded in ``data``, if specified.
:type digest: str (hex-encoded SHA-256, prefixed by ``sha256:``)

:param progress: Optional function to call as the upload progresses. The function will be called with the hash of the file's content (or ``digest``), the blob just read from the file (or chunk from ``data``) and if ``filename`` is specified the total size of the file.
:type progress: function(dgst, chunk, size)

:param check_exists: Whether to check if a blob with the same hash already exists in the registry. If so, it won't be uploaded again.
:type check_exists: bool

:rtype: str
:returns: Hash of file's content.