Reputation: 339
I can see:
s = boto3.client('s3')
print(type(s))
prints
<class 'botocore.client.S3'>
But if I try
print(botocore.client.S3)
I get
AttributeError: module 'botocore.client' has no attribute 'S3'
How come?
Side note: My end goal is to return a mock that is speced to what botocore.client.S3 has to offer, but the technical aspect of what is being returned has alluded me for some time, and from knowing that, I'll probably know how to answer my ultimate question.
Upvotes: 23
Views: 14713
Reputation: 3463
If you ask what the type is - because you need to import the class, then it's not possible. Because the class definition does not exist at all (at least not "nowadays", like in 2024, version around 1.34).
The Boto3 implementation creates the client classes at runtime. You cannot import any of them. The only class defined in the SDK is BaseClient
.
I believe that they do this abracadabra to create all its methods from an externally defined list.
Upvotes: 0
Reputation: 5590
As pointed out in @J.Doe's comment, the following lines appear in botocore.client.py
and are the likely culprits:
cls = type(str(class_name), tuple(bases), class_attributes)
return cls
What we can see here is that a class is being dynamically created at runtime, rather than being defined in the source code. Many of the other answers do correctly point out that the resulting class is an instance of BaseClient
, but any of the other dynamically created classes will also be an instance of BaseClient
, so it's unclear how much use you'll get out of knowing it's a subclass of BaseClient
.
Upvotes: 2
Reputation: 81
This module should be helpful.
https://github.com/j4c0bs/boto3-type
In essence...
>>> import boto3
>>> import botocore
>>> client = boto3.client('s3')
>>> isinstance(client, botocore.client.BaseClient)
True
>>> client.meta.service_model.service_name
's3'
>>>
Specific code from the mentioned module follows.
def is_client(client):
return isinstance(client, botocore.client.BaseClient)
if is_client(client):
return (
client.meta.service_model.service_name.lower()
== service_name.strip().lower()
)
Upvotes: 0
Reputation: 432
Through a bit of trial and error, found out the instance type that can be used:
>>> import boto3
>>> import botocore
>>> isinstance(boto3.client('s3'), botocore.client.BaseClient)
True
Upvotes: 17
Reputation: 1088
There's not really a notion of printing a class object like this (they have no repr or str methods). If you want to get to the class itself and have a look at all of the methods and parameters, you could do this (using your examples above), if you don't know where botocore and boto3 are installed:
>> import boto3
>> import botocore
>> s = boto3.client('s3')
>> print(type(s))
<class 'botocore.client.S3'>
>> print(botcore.client)
<module 'botocore.client' from '/usr/local/lib/python3.7/site-packages/botocore/client.py'>
Now, open the module, '/usr/local/lib/python3.7/site-packages/botocore/client.py', in your favorite editor and see how it works. Additionally, you could have a look at the boto3 and botocore documentation to see how to consume these objects.
Upvotes: 0