Example #1
0
 def _make_token_request(self, data):
     headers = {
         'Content-Type':
         'application/x-www-form-urlencoded',
         'Authorization':
         'Basic ' +
         base64.b64encode(b'codalab_cli_client:').decode('utf-8'),
         'X-Requested-With':
         'XMLHttpRequest',
     }
     headers.update(self._extra_headers)
     request = urllib.request.Request(
         self._address + '/rest/oauth2/token',
         headers=headers,
         data=urllib.parse.urlencode(data).encode('utf-8'),
     )
     try:
         response = urlopen_with_retry(request)
         result = json.loads(response.read().decode())
         return result
     except urllib.error.HTTPError as e:
         if e.code == 401:
             return None
         elif e.code == 404:
             raise LoginPermissionError("Invalid username or password.")
         raise e
Example #2
0
def download_url(source_url, target_path, print_status=False):
    """
    Download the file at |source_url| and write it to |target_path|.
    """
    in_file = urlopen_with_retry(source_url)
    total_bytes = in_file.info().get('Content-Length')
    if total_bytes:
        total_bytes = int(total_bytes)

    num_bytes = 0
    out_file = open(target_path, 'wb')

    def status_str():
        if total_bytes:
            return 'Downloaded %s/%s (%d%%)' % (
                formatting.size_str(num_bytes),
                formatting.size_str(total_bytes),
                100.0 * num_bytes / total_bytes,
            )
        else:
            return 'Downloaded %s' % (formatting.size_str(num_bytes))

    while True:
        s = in_file.read(BUFFER_SIZE)
        if not s:
            break
        out_file.write(s)
        num_bytes += len(s)
        if print_status:
            print('\r' + status_str(), end=' ', file=sys.stderr)
            sys.stderr.flush()
    if print_status:
        print('\r' + status_str() + ' [done]', file=sys.stderr)
    def _authorize(self):
        request_data = {
            'grant_type': 'password',
            'username': self._username,
            'password': self._password,
        }
        headers = {
            'Authorization': 'Basic ' + base64.b64encode(b'codalab_worker_client:').decode('utf-8'),
            'Content-Type': 'application/x-www-form-urlencoded',
            'X-Requested-With': 'XMLHttpRequest',
        }
        request_to_send = urllib.request.Request(
            self._base_url + '/oauth2/token',
            data=urllib.parse.urlencode(request_data).encode('utf-8'),
        )
        for k, v in headers.items():
            request_to_send.add_unredirected_header(k, v)

        with closing(urlopen_with_retry(request_to_send)) as response:
            response_data = response.read().decode()
        try:
            token = json.loads(response_data)
        except ValueError:
            raise BundleServiceException('Invalid JSON: ' + response_data, False)
        if token['token_type'] != 'Bearer':
            raise BundleServiceException(
                'Unknown authorization token type: ' + token['token_type'], True
            )
        self._access_token = token['access_token']
        self._token_expiration_time = time.time() + token['expires_in']
    def upload_to_bundle_store(self, bundle: Bundle, source: Source, git: bool,
                               unpack: bool):
        """Uploads the given source to the bundle store.
        Given arguments are the same as UploadManager.upload_to_bundle_store().
        Used when uploading from rest server."""
        try:
            # bundle_path = self._bundle_store.get_bundle_location(bundle.uuid)
            is_url, is_fileobj, filename = self._interpret_source(source)
            if is_url:
                assert isinstance(source, str)
                if git:
                    bundle_path = self._update_and_get_bundle_location(
                        bundle, is_directory=True)
                    self.write_git_repo(source, bundle_path)
                else:
                    # If downloading from a URL, convert the source to a file object.
                    is_fileobj = True
                    source = (filename, urlopen_with_retry(source))
            if is_fileobj:
                source_filename, source_fileobj = cast(Tuple[str, IO[bytes]],
                                                       source)
                source_ext = zip_util.get_archive_ext(source_filename)
                if unpack and zip_util.path_is_archive(filename):
                    bundle_path = self._update_and_get_bundle_location(
                        bundle, is_directory=source_ext in ARCHIVE_EXTS_DIR)
                    self.write_fileobj(source_ext,
                                       source_fileobj,
                                       bundle_path,
                                       unpack_archive=True)
                else:
                    bundle_path = self._update_and_get_bundle_location(
                        bundle, is_directory=False)
                    self.write_fileobj(source_ext,
                                       source_fileobj,
                                       bundle_path,
                                       unpack_archive=False)

        except UsageError:
            if FileSystems.exists(bundle_path):
                path_util.remove(bundle_path)
            raise
    def _make_request(
        self,
        method,
        path,
        query_params=None,
        headers=None,
        data=None,
        return_response=False,
        authorized=True,
        timeout_seconds=URLOPEN_TIMEOUT_SECONDS,
    ):
        """
        `data` can be one of the following:
        - bytes
        - string (text/plain)
        - dict (application/json)
        """
        # Set headers
        if headers is None:
            headers = {}
        headers['X-Requested-With'] = 'XMLHttpRequest'
        access_token = self._get_access_token()
        if authorized and access_token:
            headers['Authorization'] = 'Bearer ' + self._get_access_token()

        if isinstance(data, dict):
            headers['Content-Type'] = 'application/json'
            data = json.dumps(data)  # Turn dict into string
        if isinstance(data, str):
            data = data.encode()  # Turn string into bytes

        # Emphasize utf-8 for non-bytes data.
        if headers.get('Content-Type') in ('text/plain', 'application/json'):
            headers['Content-Type'] += '; charset=utf-8'

        headers.update(self._extra_headers)

        # Set path
        if query_params is not None:
            path = path + '?' + urllib.parse.urlencode(query_params)
        request_url = self._base_url + path

        # Make the actual request
        request = urllib.request.Request(request_url, data=data, headers=headers)
        request.get_method = lambda: method
        if return_response:
            # Return a file-like object containing the contents of the response
            # body, transparently decoding gzip streams if indicated by the
            # Content-Encoding header.
            response = urlopen_with_retry(request, timeout=timeout_seconds)
            encoding = response.headers.get('Content-Encoding')
            if not encoding or encoding == 'identity':
                return response
            elif encoding == 'gzip':
                return un_gzip_stream(response)
            else:
                raise RestClientException('Unsupported Content-Encoding: ' + encoding, False)

        with closing(urlopen_with_retry(request, timeout=timeout_seconds)) as response:
            # If the response is a JSON document, as indicated by the
            # Content-Type header, try to deserialize it and return the result.
            # Otherwise, just ignore the response body and return None.
            if response.headers.get('Content-Type') == 'application/json':
                response_data = response.read().decode()
                try:
                    return json.loads(response_data)
                except ValueError:
                    raise RestClientException('Invalid JSON: ' + response_data, False)