tb1337 / paperless-api

Little api client for paperless(-ngx).
https://pypi.org/p/pypaperless/
MIT License
24 stars 5 forks source link

Inconsistency between search and reduce #225

Open madduck opened 3 weeks ago

madduck commented 3 weeks ago

Hello,

I am writing a tool that uses either search or reduce to get a list of documents. The two work differently. search returns an AsyncIterator alright, but reduce returns an AsyncGeneratorContextManager, for which I have to use an async with clause before being able to loop over the results:

if args.path:
    dociter = paperless.documents.reduce(id__in=docids)

else:
    dociter = paperless.documents.search(args.search)

async for item in dociter:
    print(item.title)

This won't work when I provide args.path, but rather dies with

TypeError: 'async for' requires an object with __aiter__ method, got _AsyncGeneratorContextManager

I don't quite understand why reduce can't just be an iterator itself, but I think it would be better to have a consistent way to iterate over result sets returned by the API, rather than having to use context managers at times, and not at others.

tb1337 commented 2 weeks ago

Technically, document.search("foo") is a shortcut for

async with p.documents.reduce(query="foo") as docs:
  async for item in docs:
    # ...

I made reduce a context manager as it magically applies to the http-GET methods __aiter__, all and pages, and later built search as a shortcut on top of that. I cannot turn reduce into an iterator for that reason, as it is meant to apply temporarily and to be used with one of the above mentioned methods, which are iterators theirselves in some cases.

Gonna check if creating another iterator class makes sense here, but it has to wait until I am back from holidays. :)

madduck commented 2 weeks ago

I am not sure I follow, but I've now stopped using search altogether and that's fine.