示例#1
0
def _upload_loop(file_chunk_stream: FileChunkStream, query_params: dict, **kwargs):
    for iteration, chunk in enumerate(file_chunk_stream.generate()):
        if "reset" in query_params and iteration != 0:
            query_params["reset"] = str(False)
        result = _upload_loop_chunk(
            chunk, file_chunk_stream, query_params=query_params.copy(), **kwargs
        )
        _attribute_upload_response_handler(result)

    file_chunk_stream.close()
示例#2
0
def upload_to_storage(upload_entries, upload_api_fun, upload_tar_api_fun, warn_limit=None, **kwargs):
    unique_upload_entries = scan_unique_upload_entries(upload_entries)
    progress_indicator = SilentProgressIndicator()

    if warn_limit is not None:
        total_size = 0
        for entry in unique_upload_entries:
            if not entry.is_stream():
                total_size += os.path.getsize(entry.source_path)
        if total_size >= warn_limit:
            progress_indicator = LoggingProgressIndicator(total_size)

    for package in split_upload_files(unique_upload_entries):
        if package.is_empty():
            continue

        uploading_multiple_entries = package.len > 1
        creating_a_single_empty_dir = package.len == 1 and not package.items[0].is_stream() \
                                      and os.path.isdir(package.items[0].source_path)

        if uploading_multiple_entries or creating_a_single_empty_dir:
            data = compress_to_tar_gz_in_memory(upload_entries=package.items)
            upload_tar_api_fun(**dict(kwargs, data=data))
            progress_indicator.progress(package.size)
        else:
            file_chunk_stream = FileChunkStream(package.items[0])
            upload_api_fun(**dict(kwargs, data=file_chunk_stream, progress_indicator=progress_indicator))

    progress_indicator.complete()
示例#3
0
    def test_permissions_to_unix_string_for_nonexistent_file(self):
        # when
        permissions_string = FileChunkStream.permissions_to_unix_string(
            '/some/path')

        # then
        self.assertEqual('-' * 10, permissions_string)
示例#4
0
    def test_generate_chunks_from_stream(self):
        # given
        text = u"ABCDEFGHIJKLMNOPRSTUWXYZ"

        # when
        stream = FileChunkStream(UploadEntry(StringIO(text), "some/path"))
        chunks = list()
        for chunk in stream.generate(chunk_size=10):
            chunks.append(chunk)

        # then
        self.assertEqual(stream.length, None)
        self.assertEqual(chunks, [
            FileChunk(b"ABCDEFGHIJ", 0, 10),
            FileChunk(b"KLMNOPRSTU", 10, 20),
            FileChunk(b"WXYZ", 20, 24)
        ])
    def test_permissions_to_unix_string_for_directory(self, lstat):
        # given
        lstat.return_value.st_mode = 0o642

        # when
        permissions_string = FileChunkStream.permissions_to_unix_string('/some/path')

        # then
        self.assertEqual('drw-r---w-', permissions_string)
    def test_permissions_to_unix_string_for_file(self, lstat):
        # given
        lstat.return_value.st_mode = 0o731

        # when
        permissions_string = FileChunkStream.permissions_to_unix_string('/some/path')

        # then
        self.assertEqual('-rwx-wx--x', permissions_string)
示例#7
0
def upload_file_attribute(
    swagger_client: SwaggerClient,
    container_id: str,
    attribute: str,
    source: Union[str, bytes],
    ext: str,
    multipart_config: Optional[MultipartConfig],
) -> List[NeptuneException]:
    if isinstance(source, str) and not os.path.isfile(source):
        return [FileUploadError(source, "Path not found or is a not a file.")]

    target = attribute
    if ext:
        target += "." + ext

    try:
        upload_entry = UploadEntry(
            source if isinstance(source, str) else BytesIO(source), target
        )
        if multipart_config is None:
            # the legacy upload procedure
            url = build_operation_url(
                swagger_client.swagger_spec.api_url,
                swagger_client.api.uploadAttribute.operation.path_name,
            )
            upload_configuration = DEFAULT_UPLOAD_CONFIG

            _upload_loop(
                file_chunk_stream=FileChunkStream(upload_entry, upload_configuration),
                http_client=swagger_client.swagger_spec.http_client,
                url=url,
                query_params={
                    "experimentId": container_id,
                    "attribute": attribute,
                    "ext": ext,
                },
            )
        else:
            _multichunk_upload(
                upload_entry,
                query_params={
                    "experimentIdentifier": container_id,
                    "attribute": attribute,
                    "ext": ext,
                },
                swagger_client=swagger_client,
                multipart_config=multipart_config,
                target=FileUploadTarget.FILE_ATOM,
            )
    except MetadataInconsistency as e:
        return [e]
示例#8
0
    def test_generate_chunks_from_stream(self):
        # given
        text = u"ABCDEFGHIJKLMNOPRSTUWXYZ"

        # when
        stream = FileChunkStream(
            UploadEntry(BytesIO(bytes(text, "utf-8")), "some/path"),
            AttributeUploadConfiguration(10),
        )
        chunks = list()
        for chunk in stream.generate():
            chunks.append(chunk)

        # then
        self.assertEqual(stream.length, 24)
        self.assertEqual(
            chunks,
            [
                FileChunk(b"ABCDEFGHIJ", 0, 10),
                FileChunk(b"KLMNOPRSTU", 10, 20),
                FileChunk(b"WXYZ", 20, 24),
            ],
        )
示例#9
0
def upload_to_storage(files_list, upload_api_fun, upload_tar_api_fun,
                      **kwargs):
    for package in split_upload_files(files_list):
        if package.is_empty():
            break

        uploading_multiple_entries = package.len > 1
        creating_a_single_empty_dir = package.len == 1 and os.path.isdir(
            package.items[0].source_path)

        if uploading_multiple_entries or creating_a_single_empty_dir:
            data = compress_to_tar_gz_in_memory(upload_entries=package.items)
            upload_tar_api_fun(**dict(kwargs, data=data))
        else:
            file_chunk_stream = FileChunkStream(package.items[0])
            upload_api_fun(**dict(kwargs, data=file_chunk_stream))
示例#10
0
def upload_file_set_attribute(
    swagger_client: SwaggerClient,
    container_id: str,
    attribute: str,
    file_globs: Iterable[str],
    reset: bool,
    multipart_config: Optional[MultipartConfig],
) -> List[NeptuneException]:
    unique_upload_entries = get_unique_upload_entries(file_globs)

    try:
        upload_configuration = DEFAULT_UPLOAD_CONFIG
        for package in split_upload_files(
            upload_entries=unique_upload_entries,
            upload_configuration=upload_configuration,
        ):
            if package.is_empty() and not reset:
                continue

            uploading_multiple_entries = package.len > 1
            creating_a_single_empty_dir = (
                package.len == 1
                and not package.items[0].is_stream()
                and os.path.isdir(package.items[0].source_path)
            )

            if (
                uploading_multiple_entries
                or creating_a_single_empty_dir
                or package.is_empty()
            ):
                data = compress_to_tar_gz_in_memory(upload_entries=package.items)
                url = build_operation_url(
                    swagger_client.swagger_spec.api_url,
                    swagger_client.api.uploadFileSetAttributeTar.operation.path_name,
                )
                result = upload_raw_data(
                    http_client=swagger_client.swagger_spec.http_client,
                    url=url,
                    data=data,
                    headers={"Content-Type": "application/octet-stream"},
                    query_params={
                        "experimentId": container_id,
                        "attribute": attribute,
                        "reset": str(reset),
                    },
                )
                _attribute_upload_response_handler(result)
            else:
                upload_entry = package.items[0]
                if multipart_config is None:
                    # the legacy upload procedure
                    url = build_operation_url(
                        swagger_client.swagger_spec.api_url,
                        swagger_client.api.uploadFileSetAttributeChunk.operation.path_name,
                    )
                    file_chunk_stream = FileChunkStream(
                        upload_entry=upload_entry,
                        upload_configuration=upload_configuration,
                    )
                    _upload_loop(
                        file_chunk_stream=file_chunk_stream,
                        http_client=swagger_client.swagger_spec.http_client,
                        url=url,
                        query_params={
                            "experimentId": container_id,
                            "attribute": attribute,
                            "reset": str(reset),
                            "path": upload_entry.target_path,
                        },
                    )
                else:
                    _multichunk_upload(
                        upload_entry,
                        query_params={
                            "experimentIdentifier": container_id,
                            "attribute": attribute,
                            "subPath": upload_entry.target_path,
                        },
                        swagger_client=swagger_client,
                        multipart_config=multipart_config,
                        target=FileUploadTarget.FILE_SET,
                    )

            reset = False
    except MetadataInconsistency as e:
        if len(e.args) == 1:
            return [e]
        else:
            return [MetadataInconsistency(desc) for desc in e.args]