What is the difference between warnings.warn() and logging.warn() in terms of what they do and how they should be used?
logging.warning just logs something at the WARNING level, in the same way that logging.info logs at the INFO level and logging.error logs at the ERROR level. It has no special behaviour.
warnings.warn emits a Warning, which may be printed to stderr, ignored completely, or thrown like a normal Exception (potentially crashing your application) depending upon the precise Warning subclass emitted and how you've configured your Warnings Filter. By default, warnings will be printed to stderr or ignored.
Warnings emitted by warnings.warn are often useful to know about, but easy to miss (especially if you're running a Python program in a background process and not capturing stderr). For that reason, it can be helpful to have them logged.
Python provides a built-in integration between the logging module and the warnings module to let you do this; just call logging.captureWarnings(True) at the start of your script and all warnings emitted by the warnings module will automatically be logged at level WARNING.