Malith-Rukshan / Suno-API

SunoAI Unofficial Python API Library and REST API for Suno.ai — Create Music with Generative AI ! ✨
https://pypi.org/project/SunoAI
MIT License
42 stars 14 forks source link

[info] create a csv of all song of a user set as public? #6

Open spupuz opened 1 month ago

spupuz commented 1 month ago

is it possible to create and csv file with all song created and present in a user profile with these api?

kuhnchris commented 1 month ago

Would be interesting to know currently it looks like it just dumps all the data directly into their HTML, for example querying "https://suno.com/profile/liltingafrobeats036" gives us this in the HTML reply: image The only interacting with any API i see in the dev tools is a increase of the play counter...

BUT! There seems to be another API, if you hit the buttons for sorting on the page we get: https://studio-api.suno.ai/api/profiles/liltingafrobeats036?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at

Would that help you? It should contain all the necessary info of a user's songs profile, like profile, name, handle, no. of songs, clips and even the playlists, for example SirBitesAlot: https://studio-api.suno.ai/api/profiles/sirbitesalot?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at image

Writing a wrapper for this should be fairly trivial as it seems to contain most of the Clip data this API already uses for the "api/feed" endpoint anyways...

So, technically, yes, it is possible to create a csv file with the data, but there is no api function for it yet, implementing one would be rather easy given the data above.

spupuz commented 1 month ago

thanks i'm not a code but i'll try to play around that, i would like to dump at least some info of my profile in a csv and update it mainly name and url and possibly only for "public" songs. (not for trash)

spupuz commented 1 month ago

Would be interesting to know currently it looks like it just dumps all the data directly into their HTML, for example querying "https://suno.com/profile/liltingafrobeats036" gives us this in the HTML reply: image The only interacting with any API i see in the dev tools is a increase of the play counter...

BUT! There seems to be another API, if you hit the buttons for sorting on the page we get: https://studio-api.suno.ai/api/profiles/liltingafrobeats036?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at

Would that help you? It should contain all the necessary info of a user's songs profile, like profile, name, handle, no. of songs, clips and even the playlists, for example SirBitesAlot: https://studio-api.suno.ai/api/profiles/sirbitesalot?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at image

Writing a wrapper for this should be fairly trivial as it seems to contain most of the Clip data this API already uses for the "api/feed" endpoint anyways...

So, technically, yes, it is possible to create a csv file with the data, but there is no api function for it yet, implementing one would be rather easy given the data above.

ok then i was able

i'll post there just for any one that could be interested:

import requests
import csv
import math

base_url = "https://studio-api.suno.ai/api/profiles/sirbitesalot"
clips_per_page = 20

response = requests.get(f"{base_url}?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at")
data = response.json()

total_clips = data['num_total_clips']
total_pages = math.ceil(total_clips / clips_per_page)

songs_data = []
song_base_url = "https://suno.com/song/"

for page in range(1, total_pages + 1):
    url = f"{base_url}?page={page}&playlists_sort_by=upvote_count&clips_sort_by=created_at"
    response = requests.get(url)
    data = response.json()

    for clip in data.get('clips', []):
        title = clip.get('title')
        clip_id = clip.get('id')
        song_url = song_base_url + clip_id
        play_count = clip.get('play_count', 0)
        upvote_count = clip.get('upvote_count', 0)
        is_public = clip.get('is_public', False)
        major_model_version = clip.get('major_model_version', '')

        songs_data.append([title, song_url, play_count, upvote_count, is_public, major_model_version])

# Sort the songs_data list by upvote count (descending order)
songs_data.sort(key=lambda x: x[3], reverse=True)

csv_filename = "all_songs_list_sorted.csv"
with open(csv_filename, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Song Title', 'URL', 'Play Count', 'Upvote Count', 'Is Public', 'Major Model Version'])
    writer.writerows(songs_data)

print(f"CSV file '{csv_filename}' has been created with all {total_clips} songs, sorted by upvote count.")
kuhnchris commented 1 month ago

Hello, great that you managed to get it to work! :-)

Malith-Rukshan commented 1 month ago

Would be interesting to know currently it looks like it just dumps all the data directly into their HTML, for example querying "https://suno.com/profile/liltingafrobeats036" gives us this in the HTML reply: image The only interacting with any API i see in the dev tools is a increase of the play counter... BUT! There seems to be another API, if you hit the buttons for sorting on the page we get: https://studio-api.suno.ai/api/profiles/liltingafrobeats036?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at Would that help you? It should contain all the necessary info of a user's songs profile, like profile, name, handle, no. of songs, clips and even the playlists, for example SirBitesAlot: https://studio-api.suno.ai/api/profiles/sirbitesalot?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at image Writing a wrapper for this should be fairly trivial as it seems to contain most of the Clip data this API already uses for the "api/feed" endpoint anyways... So, technically, yes, it is possible to create a csv file with the data, but there is no api function for it yet, implementing one would be rather easy given the data above.

ok then i was able

i'll post there just for any one that could be interested:

import requests
import csv
import math

base_url = "https://studio-api.suno.ai/api/profiles/sirbitesalot"
clips_per_page = 20

response = requests.get(f"{base_url}?page=1&playlists_sort_by=upvote_count&clips_sort_by=created_at")
data = response.json()

total_clips = data['num_total_clips']
total_pages = math.ceil(total_clips / clips_per_page)

songs_data = []
song_base_url = "https://suno.com/song/"

for page in range(1, total_pages + 1):
    url = f"{base_url}?page={page}&playlists_sort_by=upvote_count&clips_sort_by=created_at"
    response = requests.get(url)
    data = response.json()

    for clip in data.get('clips', []):
        title = clip.get('title')
        clip_id = clip.get('id')
        song_url = song_base_url + clip_id
        play_count = clip.get('play_count', 0)
        upvote_count = clip.get('upvote_count', 0)
        is_public = clip.get('is_public', False)
        major_model_version = clip.get('major_model_version', '')

        songs_data.append([title, song_url, play_count, upvote_count, is_public, major_model_version])

# Sort the songs_data list by upvote count (descending order)
songs_data.sort(key=lambda x: x[3], reverse=True)

csv_filename = "all_songs_list_sorted.csv"
with open(csv_filename, mode='w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerow(['Song Title', 'URL', 'Play Count', 'Upvote Count', 'Is Public', 'Major Model Version'])
    writer.writerows(songs_data)

print(f"CSV file '{csv_filename}' has been created with all {total_clips} songs, sorted by upvote count.")

Thanks for sharing 🤝

spupuz commented 1 month ago

Pu play around I created a containerized app to Monitor my songs

Now the question is: is there a way to monitor the trending songs of the homepage?

spupuz commented 1 month ago

Screenshot_20240802_072222_Chrome

kuhnchris commented 1 month ago

"Trending" seems to be just a special playlist with the id "07653cdf-8f72-430e-847f-9ab8ac05af40" on the mainpage.

https://studio-api.suno.ai/api/playlist/07653cdf-8f72-430e-847f-9ab8ac05af40/?page=0

image

spupuz commented 1 month ago

"Trending" seems to be just a special playlist with the id "07653cdf-8f72-430e-847f-9ab8ac05af40" on the mainpage.

https://studio-api.suno.ai/api/playlist/07653cdf-8f72-430e-847f-9ab8ac05af40/?page=0

image

in fact i have found this https://studio-api.suno.ai/api/trending/

kuhnchris commented 1 month ago

Even better, thanks for looping this info back. @Malith-Rukshan should we try to add those 2 endpoints (get_profile and get_trending) to the API as another PR?

spupuz commented 4 weeks ago

Ssems that trending list url I provided is not properly updated and can create discrepancies the play list you gave me may be is more precise will try to check against this

spupuz commented 2 weeks ago

do you guys know if it's possible to look at a user profile and find followers? i want to extract data of new follower name in a week??

spupuz commented 2 weeks ago

ok got it:

https://studio-api.suno.ai/api/profiles/followers?page=1

but it says not authorized, how can i be authorized?

cookie? token??

any idea?

kuhnchris commented 2 weeks ago

Hello,

you can only get your own followers, as it seems. And yes, to do so you need to have the cookie/authentication enabled, so if you add this code to your suno.py you should be able to fetch it using the library (this is just quick and dirty, one should add a model for it, etc. but this is just a quick PoC to see if this fulfills your need. :-) ) image

  def get_followers(self):
        self._keep_alive()
        logger.info("Get followers...")
        response = self.client.get(
            f"{Suno.BASE_URL}/api/profiles/followers")
        logger.debug(response.text)

        self._check_for_error(response)

        if response.status_code != 200:
            logger.error("Get followers failed.")
            raise Exception(f"Error response: {response.text}")

        followers = response.json()["profiles"]
        return followers
spupuz commented 2 weeks ago

Not worried about hot to get them but how to authenticate and how to integrate authentication into the script.

kuhnchris commented 2 weeks ago

Yeah you need to use the cookie: image

spupuz commented 2 weeks ago

Can you post without sensible data I text format? I'm not using this Suno library in fact up to now since operation I'm doing are not supported by it

spupuz commented 2 weeks ago

I'm not a real Coder so I have doubts 😂 but I have done a lot maybe I'll post a video of what I'm doing.

kuhnchris commented 2 weeks ago

Basically we use do this:

Suno(
      cookie='__client_uat=aa; __client=bb; ajs_anonymous_id=cc; _cfuvid=dd; __cf_bm=ee; mp_ff_mixpanel=gg',
      model_version=ModelVersions.CHIRP_V3_5)

All it does is sending the cookie from the SUNO website as the "Cookies:" Header in the request, based on that we get a "Authorization: bearer ..." token, and with that you just call the API url endpoints. image

So, basically,

Hope that helps a little, else let us know if I can try to explain it differently. :-)

spupuz commented 2 weeks ago

I'll try so then I have to authenticate with your library api and use it Un the script correct?

spupuz commented 2 weeks ago

Another question why if I open

https://studio-api.suno.ai/api/profiles/followers?page=1

From a browser where I'm already authenticated to suno in got:

{"detail": "Unauthorized"}

Shouldn't be able to use it?

kuhnchris commented 2 weeks ago

No, because the browser sends an AJAX request in the website (basically it opens the URL with other things in the header) - you can see that by pressing F12 while being on the Suno page and if you click on the Network tab (and then go to "Followers") you should see the /followers?page=1 request, if you go to "Request headers" you see there is a Auth bearer + alot of data, that is basically what is being sent everytime you click on that, and that is what your browser doesn't send if you just click on that link - it's done via javascript on the suno.com page :-)

I'll try so then I have to authenticate with your library api and use it Un the script correct?

Either that, or roll your own login + the 3 requests, basically, the important thing is: you need the JWT token, and with that token you can access the followers API page

spupuz commented 2 weeks ago

No, because the browser sends an AJAX request in the website (basically it opens the URL with other things in the header) - you can see that by pressing F12 while being on the Suno page and if you click on the Network tab (and then go to "Followers") you should see the /followers?page=1 request, if you go to "Request headers" you see there is a Auth bearer + alot of data, that is basically what is being sent everytime you click on that, and that is what your browser doesn't send if you just click on that link - it's done via javascript on the suno.com page :-)

I'll try so then I have to authenticate with your library api and use it Un the script correct?

Either that, or roll your own login + the 3 requests, basically, the important thing is: you need the JWT token, and with that token you can access the followers API page

i have to integrate your api into my script correct? can't do it in different way correct?

kuhnchris commented 2 weeks ago

No you don't, those are regular requests. calls, I gave you the generic way of doing it, you can use the library, then you do not have to do it per requests (just use Suno (...) as I wrote a couple of posts above). I can write you the boiled down non-library version later today if you struggle with extracting the code from the library.

spupuz commented 2 weeks ago

i can use the library too but not sure if it is already covering trending list, or follower... just that i'm not an expert coder and i'm not using python to generate songs, more interested in metrics and statistics :) trending and more over.

spupuz commented 2 weeks ago

No you don't, those are regular requests. calls, I gave you the generic way of doing it, you can use the library, then you do not have to do it per requests (just use Suno (...) as I wrote a couple of posts above). I can write you the boiled down non-library version later today if you struggle with extracting the code from the library.

anyway if you are so kind to draft me some sort of code for extract follower with auth i will be really glad

kuhnchris commented 2 weeks ago

So, the stripped down version is here: https://gist.github.com/kuhnchris/443c5e69da2dd327a0b74c8f18ce0770 Don't forget to get your cookie from suno.com and set the "cookie = " variable on top image

spupuz commented 2 weeks ago

So, the stripped down version is here: https://gist.github.com/kuhnchris/443c5e69da2dd327a0b74c8f18ce0770 Don't forget to get your cookie from suno.com and set the "cookie = " variable on top image

thank you su much integrated the code perfectly! :) and i'ts working

spupuz commented 2 weeks ago

they just changed trending list here is the new trending data structure:

https://studio-api.suno.ai/api/discover/

kuhnchris commented 2 weeks ago

Yeah i noticed, they also added some search filters (like by language, weekly, monthly, all time, etc.) so we'll probabbly have to check how to refactor it

spupuz commented 2 weeks ago

i have no time for now going in holiday tomorrow will see in 2 weeks i suppose, old trending playlist is still available and working and updated

kuhnchris commented 2 weeks ago

Alright, enjoy your holidays! :-)

spupuz commented 2 weeks ago

can you share your suno or discord nick so i can follow :) don't want to chat here :)

spupuz commented 1 week ago

Alright, enjoy your holidays! :-)

did you figure out something on the new tranding? Have you a discord account?