code: def upload(self, filename, filedata=None, filepath=None, **kwargs):
          
          if filepath is None and filedata is None:
              raise GitlabUploadError("No file contents or path specified")
  
          if filedata is not None and filepath is not None:
              raise GitlabUploadError("File contents and file path specified")
  
          if filepath is not None:
              with open(filepath, "rb") as f:
                  filedata = f.read()
  
          url = ('/projects/%(id)s/uploads' % {
              'id': self.id,
          })
          file_info = {
              'file': (filename, filedata),
          }
          data = self.manager.gitlab.http_post(url, files=file_info)
  
          return {
              "alt": data['alt'],
              "url": data['url'],
              "markdown": data['markdown']
          }
docs: Upload the specified file into the project.
  
          .. note::
  
              Either ``filedata`` or ``filepath`` *MUST* be specified.
  
          Args:
              filename (str): The name of the file being uploaded
              filedata (bytes): The raw data of the file being uploaded
              filepath (str): The path to a local file to upload (optional)
  
          Raises:
              GitlabConnectionError: If the server cannot be reached
              GitlabUploadError: If the file upload fails
              GitlabUploadError: If ``filedata`` and ``filepath`` are not
                  specified
              GitlabUploadError: If both ``filedata`` and ``filepath`` are
                  specified
  
          Returns:
              dict: A ``dict`` with the keys:
                  * ``alt`` - The alternate text for the upload
                  * ``url`` - The direct url to the uploaded file
                  * ``markdown`` - Markdown for the uploaded file