ValvePython / steam

☁️ Python package for interacting with Steam
http://steam.readthedocs.io
MIT License
1.05k stars 127 forks source link

WebAPI bootstrap failing #388

Closed Sorahawk closed 2 years ago

Sorahawk commented 2 years ago

Hello! I have been dealing with an issue for far too long and have been unable to resolve it, and was hoping I could get some help here, as Google results have been unhelpful.

I have a Discord bot that periodically queries the Steam API to get the latest product info for a specific app. The following four lines of code are called about every 15 minutes.

steam_session = SteamClient()
steam_session.anonymous_login()
app_info = steam_session.get_product_info([962130])
steam_session.logout()

It works fine most of the time, however there are rare cases where get_product_info() will fail and log "WebAPI boostrap failed" messages, the source of which is line 491 of cm.py: self._LOG.error("WebAPI boostrap failed: %s" % str(exp))

I have seen the following two different error messages:

WebAPI boostrap failed: HTTPSConnectionPool(host='api.steampowered.com', port=443): Read timed out. (read timeout=3)

WebAPI boostrap failed: 503 Server Error: Service Unavailable for url: https://api.steampowered.com/ISteamDirectory/GetCMList/v1/?cellid=0&format=json

Having said all this, 100% reliability of the Steam querying is not necessary. The real problem is that I am unable to catch any exceptions at all.

Even if I place get_product_info() within a try-except block, the entire script still fails, somehow causing a cascading failure which pulls down the entire bot together with it.

Really hope someone can help me shed some light on this. Thank you so much!

rossengeorgiev commented 2 years ago

That call pulls out a list of CM servers via the WebAPI, which may fail or be down. It is not fatal, as there is DNS fallback. One thing you can do is use set_credential_location, and then CM servers will be persistent locally, and will only get updated once in a while. Alternatively, you can write something and manage the list of CM servers yourself, or override the existing CMServerList. For example, bypassing use of WebAPI for boostrap:

from steam.client import SteamClient
from steam.core.cm import  CMServerList

class  MyCMServerList(CMServerList):
  def bootstrap_from_webapi(*args, **kwargs):
    return False

client = SteamClient()
client.cm_servers = MyCMServerList()
Sorahawk commented 2 years ago

Hi Rossen, thanks for following up on my issue! I have since found a workaround for the purposes of my project, so have not had a chance to try out the recommendations, but am glad to have it if necessary.

For posterity, if anyone is looking for something to just pull the latest product info from Steam, the workaround I found was a web API (https://www.steamcmd.net) that was created to serve that exact purpose.

rossengeorgiev commented 2 years ago

There is also steamctl apps product_info [appid]. https://github.com/ValvePython/steamctl