Soundcloud to CSV File This program connects to Soundcloud and turns the supplied username into a CSV file with the user's like list. The code accomplishes this although it looks rather messy and was wondering what I could change to improve it.

import soundcloud
import urllib.request
import json
import requests

client = soundcloud.Client(client_id="********************************")


def get_username():
    """
    Asks user for their Soundcloud username.
    """
    username = input("Please enter your Soundcloud username: ")
    user_id = (valid_username(username))
    print(user_id)


def valid_username(username):
    """
    Checks if supplied username is valid.
    """
    global user
    try:
        user = client.get("/resolve", url="http://soundcloud.com/{}/".format(username))
        user_info(user.id)
    except requests.HTTPError:  # Runs if account cannot be found.
        print("The username you entered is invalid, please try again")
        get_username()


def user_info(user_id):
    """
    Retrieves the users information from their user ID
    and prints the number of tracks they have liked.
    """
    global number_of_user_likes
    retrieve = urllib.request.urlopen("https://api.soundcloud.com/users/{}.json?consumer_key="
                                      "********************************".format(user_id)).read()
    decode_user_info = json.loads(retrieve.decode())
    number_of_user_likes = decode_user_info['public_favorites_count']
    username = decode_user_info['username']
    print("You have liked a total of {} tracks".format(number_of_user_likes))
    save_likes(username)


def save_likes(username):
    """
    Creates a CSV file with headers and then saves the users likes to the CSV file.
    """
    csv_file = open("{}s like list.csv".format(username), 'w', encoding='UTF-8')
    csv_file.write("Track Title, Track URL\n")  # Writes headers to CSV file.
    offset_number = 0
    complete = False
    while number_of_user_likes &gt; 0 and complete is False:
        if offset_number &lt; number_of_user_likes:
            try:
                track_fetch = urllib.request.urlopen(
                    "http://api.soundcloud.com/users/{}/favorites.json?client_id="
                    "********************************&amp;offset={}&amp;limit1".format(user.id, offset_number)).read()
                track_data = json.loads(track_fetch.decode())
                if "," in track_data[0]["title"]:
                    track_title = track_data[0]["title"].replace(",",
                                                                 "")  # Removes commas as causes issues with .csv files
                else:
                    track_title = track_data[0]["title"]
                csv_file.write("{},{}\n".format(track_title, track_data[0]["permalink_url"]))
                offset_number += 1
                print("{} of {} ({}%)".format(offset_number, number_of_user_likes,
                                              round(float(100 / number_of_user_likes * offset_number), 2)))
            except IndexError:
                print("There is an issue with Soundcloud, please try again")
            except requests.HTTPError:
                print("There is an issue with Soundcloud, please try again")
            except requests.ConnectionError:
                print("Check your internet connection")
        else:
            complete = True
            finished()


def finished():
    """
    Runs after the users like list has finished being saved.
    """
    print("Finished")


get_username()
Use of functions

Functions can return values.  You should do that instead of passing back results indirectly via global variables.

In get_username(), user_id = (valid_username(username)) is nonsense, since the valid_username() function never returns anything.

Worse, you are misusing functions as if they were goto labels.  get_username() and valid_username() are mutually recursive, which is inappropriate.  Furthermore, get_username() triggers all of the activity in the program, which is much more than getting the username as the function name would suggest.

Rearranging everything…

def prompt_username():
    return input("Please enter your Soundcloud username: ")

def get_account(username):
    try:
        return client.get("/resolve", url="http://soundcloud.com/{}/".format(username))
    except requests.HTTPError:
        raise ValueError("Invalid username")

def prompt_account():
    while True:
        try:
            return get_account(prompt_username())
        except ValueError:
            print("The username you entered is invalid.  Please try again")

def get_favorites(account):
    req = urllib.request.urlopen("https://api.soundcloud.com/users/{}.json?consumer_key={}",
                                 account.id, consumer_key)
    …
    return decoded_user_info['username']

def save_favorites(account, favorites):
    …


Now you can write this, which does convey what the program does, unlike your get_username() "function" which was really just a goto label:

account = prompt_account()
save_favorites(account, get_favorites(account))