4
\$\begingroup\$
import requests
import json
import time

f = open('ok.txt', 'r')
c = f.read()
r = []
start = time.perf_counter()


def steamCheck(name):
    return requests.get("https://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=removed&vanityurl=%s" % (name)).json()

for word in c.split():
    p = steamCheck(word)
    if p['response']['success'] == 42:
        with open('www.txt', 'a') as save:
            save.write(word + '\n')
            print('%s is available' % (word))
            r.append(word)
    else:
        print('%s is taken' % (word))


finish = time.perf_counter()
print(f'Finished in {round(finish-start, 2)} second(s)')

Hi this is a script I made to check if each word from a list exists as a vanityurl on steam or not. I removed the api key so if you wanted to test yourself you would have to get one here : https://steamcommunity.com/dev/apikey

I am a beginner in python and would like to know how you would change my script to make it better (faster, cleaner, etc..). So far it works as intended however it is fairly slow and believe I may be doing something inefficiently. Thanks for any advice you may have.

Example response from api if url is not taken:

{'response': {'success': 42, 'message': 'No match'}}

Example if the url IS taken:

{"response": {"steamid": "76561198868XXXXXX", "success": 1}}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hi, would be good if you can provide example response of that api request to give us better idea of the code without having to get api key :-) \$\endgroup\$
    – K.H.
    May 27, 2020 at 20:27
  • 2
    \$\begingroup\$ sorry about that @K.H. , i've added the 2 possible responses to the thread \$\endgroup\$
    – humid
    May 27, 2020 at 20:31

1 Answer 1

1
\$\begingroup\$

This is a good start for a script. The next step should be separating in-/output from the functions doing the actual work.

In addition, whenever you make multiple requests to the same server, you should use a requests.Session, which will re-use the connection. You can also pass a dictionary params which will be the URL-encoded parameters for the request. The Session can take a default value for that.

You should always use with when opening a file or resource. This way it is ensured that it is closed properly, even if an exception occurs during the intervening code.

You can write multiple rows at once using writelines. You can even pass an iterable to this function and it will iterate for you.

I would write your script something like this:

import requests

URL = "https://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/"
PARAMS = {"key": "removed"}

def url_available(session, url):
    response = session.get(URL, params={"vanityurl": url}).json()
    return response['response']['success'] == 42

def main():
    session = requests.Session()
    session.params = PARAMS
    with open('ok.txt') as in_file, open('www.txt', 'w') as out_file:
        out_file.writelines(url for url in in_file
                            if url_available(session, url.strip()))

if __name__ == "__main__":
    with Timer("main"):
        main()

To this you should add a docstring to each function describing what it does, but that is left as an exercise :).

Here Timer is a simple class that starts a timer when the context is entered and reports the result when the with block is finished:

from time import perf_counter

class Timer:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        self.start = perf_counter

    def __exit__(self, *args):
        diff = round(perf_counter() - self.start, 2)
        print(f'{self.name} finished in {diff} second(s)')
\$\endgroup\$
1
  • \$\begingroup\$ Thank you for your input, I will be sure to follow the advice you have given and this looks nice I will try my best to learn from this and implement it into my own code. @Graipher \$\endgroup\$
    – humid
    May 27, 2020 at 21:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.