Python - Simple wrapper class for a bot API Is the following in poor taste?

This would be contained within a groupme module. Does it make sense to re-define a RequestException class within this module? If I didn't, wouldn't consumers of the module need to be aware of the underlying requests.exceptions.RequestException being thrown:

...

class Bot(object):

    API_BASE_URL = 'http://api.groupme.com/v3/bots/{route}'
    API_POST_URL = API_BASE_URL.format(route='post')

    def __init__(self, bot_id):
        self.bot_id = bot_id

    def post(self, message):
        try:
            data = {'bot_id': self.bot_id, 'message': message}
            response = requests.post(Bot.API_POST_URL, data)
            response.raise_for_status()
        except requests.exceptions.RequestException as ex:
            raise RequestException('Failed to post bot message') from ex


class RequestException(Exception):

    ...


And the groupme module / above code would then be used in the following manner:

import groupme

bot = groupme.Bot('abcdef123')
try:
    bot.post('Hello, world!')
except groupme.RequestException as ex:  # this seems cleaner as opposed to requests.exceptions.RequestException
    print(ex)
Does it make sense to re-define a RequestException class within this module?


Yes, that makes total sense. Library users should never be expected to catch dependency exceptions. If there's even the slightest chance a user needs to interact with a dependency exception, you should 'copy' it.



If you wish to create a custom exception, it's nearly always better to derive it from an exception category (type error, value error, lookup error, ...) than directly from Exception. ConnectionError would suffice.



The from ex is unnecessary. The previous exception is already preserved as context.

You should also be asking yourself 'does the user really need to see the full stack trace?'. For trivial problems, things like HTTP 4XX or 5XX status codes, you could adjust the exception message to include the code.