Most "pythonic" syntax to use for an API client library

Peter Otten __peter__ at web.de
Tue Apr 30 03:52:42 EDT 2019


Thomas Jollans wrote:

> On 29/04/2019 09.18, Peter Otten wrote:
>> Jonathan Leroy - Inikup via Python-list wrote:
>> 
>>> Hi all,
>>>
>>> I'm writing a client library for a REST API. The API endpoints looks
>>> like this: /customers
>>> /customers/1
>>> /customers/1/update
>>> /customers/1/delete
>>>
>>> Which of the following syntax do you expect an API client library to
>>> use, and why?
>>>
>>> 1/
>>> api.customers_list()
>>> api.customers_info(1)
>>> api.customers_update(1, name='Bob')
>>> api.customers_delete(1)
>>>
>>> 2/
>>> api.customers.list()
>>> api.customers.info(1)
>>> api.customers.update(1, name='Bob')
>>> api.customers.delete(1)
>>>
>>> 3/
>>> api.customers.list()
>>> api.customers(1).info()
>>> api.customers(1).update(name='Bob')
>>> api.customers(1).delete()
>>>
>>> ...any other?
>> 
>> How about mimicking (to some extent) an existing interface, like a list,
>> dict, or set:
>> 
>> customers = api.customers
>> 
>> list(customers)  # __iter__
>> 
>> alice = customers[1]  # __getitem__
>> 
>> print(alice)  # __str__
> 
> This was my first thought seeing the third option as well, but...
> 
>> 
>> alice.name = "Bob"  # __setattr__
>> 
>> del customers[42]  # __delitem__
> 
> do you want this sort of thing to update the upstream database directly?

I thought so. However, you have to answer this question no matter which of 
the suggested APIs you choose.

> Maybe there should be a commit() method on every object. Maybe not.

I originally had

db = api.connect(...)
customers = db.customers

but then decided this was out of scope for the question. It would however 
allow

with db:
    ...  # modify db
    # implicit commit, or rollback on exception

> I imagine it would be best if the data is cached locally (i.e. alice =
> customers[1] does a query, print(alice.name) does not). In this case you
> probably want the local/database separation to be consistent for both
> getting and setting things.

That looks like a lot of work, with the potential to introduce additional 
inconsistencies. But there's probably prior art.

How do ORMs like SQLObject handle this?
 
>> del customers[alice]
> 
> Are you sure about this?

On a scale from one to ten? Yes ;)

>>> #3 seems to be more "pretty" to me, but I did not find any "official"
>>> recommendation online.
> 
> I'd like #3 if it had square brackets after .customers. Of the
> suggestions as they are I prefer #2.




More information about the Python-list mailing list