sigma67 / ytmusicapi

Unofficial API for YouTube Music
https://ytmusicapi.readthedocs.io
MIT License
1.71k stars 194 forks source link

reusing ytmusic after uploads - Unknown Error #79

Closed tonyhallett closed 4 years ago

tonyhallett commented 4 years ago

The code below does not throw an error but does if the same instance is used.

Uploading all tracks in a folder, then getting their video ids ( using the difference from before ) and adding to existing playlist.

def getYTMusic():
  return YTMusic('headers_auth.json')

def UploadFolderTracksAndAddToPlaylistWorker(folder:str,playlistId:str,initialFetchLimit:int,sleepTime:float) -> UploadFolderTracksAndAddToPlaylistResult:
  # ytmusic.get_library_upload_songs 
  uploadVideoIdsBefore = GetLatestUploadVideoIds(getYTMusic(),initialFetchLimit)
  ytmusic = getYTMusic();

  notUploadable = []
  uploadResponses = []  
  numSuccessfulUploads = 0
  for root, dirs, files in os.walk(folder, topdown=False):
    for name in files:
      fullPath = os.path.join(root, name)
      if IsUploadable(name):
        response = ytmusic.upload_song(fullPath)
        if successfulResponse(response):
          uploadResponses.append(UploadResponse(fullPath,True))
          numSuccessfulUploads = numSuccessfulUploads + 1
        else:
          uploadResponses.append(UploadResponse(fullPath,False))
      else:
        notUploadable.append(fullPath)

  newFetchLimit = initialFetchLimit + len(uploadResponses)

  print("sleeping to allow for videoIds *********************")
  time.sleep(sleepTime)

  uploadVideoIdsAfter = GetLatestUploadVideoIds(getYTMusic(),newFetchLimit)

  newUploadVideoIds = list(filter(lambda videoId:not videoId in uploadVideoIdsBefore,uploadVideoIdsAfter))

  numNewUploadVideoIds = len(newUploadVideoIds)
  if numNewUploadVideoIds != numSuccessfulUploads:
    print("Not all videoids present") # could sleep and retrieve again

  updatePlaylistResponse = getYTMusic().add_playlist_items(playlistId,newUploadVideoIds)
  return UploadFolderTracksAndAddToPlaylistResult(notUploadable,uploadResponses,newFetchLimit,updatePlaylistResponse)

response object

{'error': {'code': 400, 'errors': [...], 'message': 'Unknown error.', 'status': 'INVALID_ARGUMENT'}} 
special variables: 
function variables: 'error': {'code': 400, 'errors': [{...}], 'message': 'Unknown error.', 'status': 'INVALID_ARGUMENT'} 
special variables: 
function variables: 
'code': 400 
'message': 'Unknown error.' 
'errors': [{'domain': 'gdata.CoreErrorDomain', 'location': 'client', 'locationType': 'other', 'message': 'Unknown error.', 'reason': 'INVALID_VALUE'}] 
special variables: 
function variables: 
0: {'domain': 'gdata.CoreErrorDomain', 'location': 'client', 'locationType': 'other', 'message': 'Unknown error.', 'reason': 'INVALID_VALUE'} 
len(): 1 
'status': 'INVALID_ARGUMENT' 
len(): 4 
len(): 1
sigma67 commented 4 years ago

Ah yes, I believe this error is caused by assigning a reference to self.headers and then modifying it, instead of making a shallow copy. Good catch.

Can you change https://github.com/sigma67/ytmusicapi/blob/9bded79ea22627fc35d2a9f235fb4d76e8948e68/ytmusicapi/mixins/uploads.py#L223

in your local install to

headers = self.headers.copy()

and report back?

I believe that should fix it.