linkedin-developers / linkedin-api-python-client

Official Python client library for LinkedIn APIs
Other
175 stars 35 forks source link

How would you get the ad accounts by authenticated user? #31

Closed nbro10 closed 1 year ago

nbro10 commented 1 year ago

The documentation says that we can get the ad accounts by authenticated user by making a GET request to:

GET https://api.linkedin.com/rest/adAccountUsers?q=authenticatedUser

I was trying to use this library to get this data using something like

from linkedin_api.clients.restli.client import RestliClient

restli_client = RestliClient()
access_token = "my-access-token"

response = restli_client.get(
            resource_path="/adAccountUsers",
            access_token=access_token,
            path_keys=None,
            query_params={"q": "authenticatedUser"},
            version_string="202209",
        )

But response.entity is

{'code': 'ILLEGAL_ARGUMENT',
 'message': 'Resource method could not be resolved from request parameters.',
 'status': 400}

But, using the same access token, I can call the /me endpoint, and get the data I need

response = restli_client.get(
            resource_path="/me",
            access_token=access_token,
            path_keys=None,
            version_string="202209")

Previously, I was able to make a request to https://api.linkedin.com/rest/adAccountUsers?q=authenticatedUser using the same access token without this library, so this may be a bug or a misuse of the library.

shimizust commented 1 year ago

@nbro10 The issue is that this is actually a FINDER call (I know, it's not very clear in the docs). Basically any "q=" parameter indicates this is a FINDER request. When you use the client to make a .get() request, instead of .finder(), it will set the "X-Restli-Method" header as "GET" instead of "FINDER", hence the error.

You can try doing something like this:

restli_client.finder(
   resource_path="/adAccountUsers",
   access_token=access_token,
   finder_name="authenticatedUser",
   version_string="202209"
)
shimizust commented 1 year ago

You'll also notice that the response payload looks something like:

{
   "elements": [{<AdAccountUser>}, ...]
}

Using the finder method ensures you get the correct response interface.

nbro10 commented 1 year ago

@shimizust Thanks! Using .finder I was able to get the adAccountsUsers.

I looked into the code and it seems that .finder just adds q to the parameters, so I wonder if it's really necessary to have the finder method. I suppose it might still make sense to have it because it's an interface to a xrestli method, although we still make a GET request, but maybe this difference is not really relevant to the end user, which only wants to make a get request

shimizust commented 1 year ago

@nbro10 Cool, glad that worked for you

There are 14 Rest.li methods that map to GET/POST/PUT/DELETE HTTP methods, so you could make this argument for most of the client methods.

I think there are a few reasons to keep the finder() method:

I think updating the documentation to specify the Rest.li method being used would really help in easily translating docs to api client calls vs. just showing the raw HTTP request. Things start to make a lot more sense with that context. (cc @swathivshenoy )

nbro10 commented 1 year ago

@shimizust Thanks for providing more context! Yes, it might be a good idea to emphasize these differences in the docs (here and in the API docs)