docstr: Uploads embeddings to the Lightly Platform.
  
  First checks that the specified embedding name is not on the server. If it is, the upload is aborted.
  Then creates a new csv file with the embeddings in the order specified on the server. Next uploads it
  to the Lightly Platform. The received embedding ID is stored in the API client.
  
  Args:
      path_to_embeddings_csv:
          The path to the .csv containing the embeddings, e.g. "path/to/embeddings.csv"
      name:
          The name of the embedding. If an embedding with such a name already exists on the server,
          the upload is aborted.
  
  :meta private:  # Skip docstring generation
docstr_tok: ["Uploads","embeddings","to","the","Lightly","Platform",".","First","checks","that","the","specified","embedding","name","is","not","on","the","server",".","If","it","is",",","the","upload","is","aborted",".","Then","creates","a","new","csv","file","with","the","embeddings","in","the","order","specified","on","the","server",".","Next","uploads","it","to","the","Lightly","Platform",".","The","received","embedding","ID","is","stored","in","the","API","client",".","Args",":","path_to_embeddings_csv",":","The","path","to","the",".csv","containing","the","embeddings",",","e.g",".","``","path\/to\/embeddings.csv","''","name",":","The","name","of","the","embedding",".","If","an","embedding","with","such","a","name","already","exists","on","the","server",",","the","upload","is","aborted",".",":","meta","private",":","#","Skip","docstring","generation"]
code: def upload_embeddings(
      self, path_to_embeddings_csv: str, name: str
  ) -> None:
      """Uploads embeddings to the Lightly Platform.
  
      First checks that the specified embedding name is not on the server. If it is, the upload is aborted.
      Then creates a new csv file with the embeddings in the order specified on the server. Next uploads it
      to the Lightly Platform. The received embedding ID is stored in the API client.
  
      Args:
          path_to_embeddings_csv:
              The path to the .csv containing the embeddings, e.g. "path/to/embeddings.csv"
          name:
              The name of the embedding. If an embedding with such a name already exists on the server,
              the upload is aborted.
  
      :meta private:  # Skip docstring generation
      """
      io_utils.check_embeddings(
          path_to_embeddings_csv, remove_additional_columns=True
      )
  
      # Try to append the embeddings on the server, if they exist
      try:
          embedding = self.get_embedding_by_name(
              name, ignore_suffix=True
          )
          # -> append rows from server
          print("Appending embeddings from server.")
          self.append_embeddings(path_to_embeddings_csv, embedding.id)
          now = datetime.now().strftime("%Y%m%d_%Hh%Mm%Ss")
          name = f"{name}_{now}"
      except EmbeddingDoesNotExistError:
          pass
  
      # create a new csv with the filenames in the desired order
      rows_csv = self._order_csv_by_filenames(
          path_to_embeddings_csv=path_to_embeddings_csv
      )
  
      # get the URL to upload the csv to
      response: WriteCSVUrlData = (
          self._embeddings_api.get_embeddings_csv_write_url_by_id(
              self.dataset_id, name=name
          )
      )
      self.embedding_id = response.embedding_id
      signed_write_url = response.signed_write_url
  
      # save the csv rows in a temporary in-memory string file
      # using a csv writer and then read them as bytes
      with tempfile.SpooledTemporaryFile(mode="rw") as f:
          writer = csv.writer(f)
          writer.writerows(rows_csv)
          f.seek(0)
          embeddings_csv_as_bytes = f.read().encode("utf-8")
  
      # write the bytes to a temporary in-memory byte file
      with tempfile.SpooledTemporaryFile(mode="r+b") as f_bytes:
          f_bytes.write(embeddings_csv_as_bytes)
          f_bytes.seek(0)
          retry(
              self.upload_file_with_signed_url,
              file=f_bytes,
              signed_write_url=signed_write_url,
          )
  
      # trigger the 2d embeddings job
      for dimensionality_reduction_method in [
          DimensionalityReductionMethod.PCA,
          DimensionalityReductionMethod.TSNE,
          DimensionalityReductionMethod.UMAP,
      ]:
          body = Trigger2dEmbeddingJobRequest(
              dimensionality_reduction_method=dimensionality_reduction_method
          )
          self._embeddings_api.trigger2d_embeddings_job(
              trigger2d_embedding_job_request=body,
              dataset_id=self.dataset_id,
              embedding_id=self.embedding_id,
          )
  
file_path: lightly/lightly/api/api_workflow_upload_embeddings.py
imports: import csv
  import io
  import tempfile
  import urllib.request
  from datetime import datetime
  from typing import List
  from urllib.request import Request
  from lightly.api.utils import retry
  from lightly.openapi_generated.swagger_client.models import DatasetEmbeddingData, DimensionalityReductionMethod, Trigger2dEmbeddingJobRequest, WriteCSVUrlData
  from lightly.utils import io
label_desc: Use image node_id 4 for calling the _UploadEmbeddingsMixin obj's underlying member method code with example usage: obj.upload_embeddings(path_to_embeddings_csv, name) without return types