It's possible to pass in a client class to the OAuth1Session constructor. From the docblock in the relevant file:
"""
:param client_class: A subclass of `oauthlib.oauth1.Client` to use with
`requests_oauthlib.OAuth1` instead of the default
"""
Within the oauthlib.oauth1.Client class, the _render(self, request, formencode=False, realm=None) method appears responsible for preparing the request. Since unrelated headers don't impact the base string that the request signature is created from, adding a new header/changing an existing User-Agent header shouldn't cause the signature to change in any way.
As such, we can create a custom client class, override the _render method and call the implementation in the parent class once we've added our header:
class CustomClient(Client):
def _render(self, request, formencode=False, realm=None):
request.headers['User-Agent'] = "FooClient/1.0"
return super()._render(request, formencode, realm)
The code that instantiates OAuth1Session then simply needs to reference the above class:
oauth = OAuth1Session(CONSUMER_KEY, client_secret=CONSUMER_SECRET,
signature_method=SIGNATURE_HMAC,
signature_type=SIGNATURE_TYPE_AUTH_HEADER, client_class=CustomClient)