Package: affen
Affen: plone.restapi for Humans™Affenis arequestsSession equiped to
easily consumeplone.restapiIterating without Affen>>>importrequests>>>response=requests.get('https://plonedemo.kitconcept.com/@search?sort_on=path',...headers={'Accept':'application/json'},auth=('admin','admin'))>>>fori,iteminenumerate(response.json()['items']):...print(i,item['@id'])...0https://plonedemo.kitconcept.com/de1https://plonedemo.kitconcept.com/de/Assets2https://plonedemo.kitconcept.com/de/demo3https://plonedemo.kitconcept.com/de/demo/a-image.jpg4https://plonedemo.kitconcept.com/de/demo/big_buck_bunny.mp45https://plonedemo.kitconcept.com/de/demo/ein-link6https://plonedemo.kitconcept.com/de/demo/ein-ordner7https://plonedemo.kitconcept.com/de/demo/ein-ordner/eine-seite-in-einem-ordner8https://plonedemo.kitconcept.com/de/demo/ein-termin9https://plonedemo.kitconcept.com/de/demo/eine-nachricht10https://plonedemo.kitconcept.com/de/demo/eine-seite11https://plonedemo.kitconcept.com/de/demo/ploneconf-plone5.pdf12https://plonedemo.kitconcept.com/de/frontpage13https://plonedemo.kitconcept.com/en14https://plonedemo.kitconcept.com/en/assets15https://plonedemo.kitconcept.com/en/demo16https://plonedemo.kitconcept.com/en/demo/a-event17https://plonedemo.kitconcept.com/en/demo/a-file.pdf18https://plonedemo.kitconcept.com/en/demo/a-folder19https://plonedemo.kitconcept.com/en/demo/a-folder/a-page-inside-a-folder20https://plonedemo.kitconcept.com/en/demo/a-link21https://plonedemo.kitconcept.com/en/demo/a-news-item22https://plonedemo.kitconcept.com/en/demo/a-page23https://plonedemo.kitconcept.com/en/demo/a-photo.jpg24https://plonedemo.kitconcept.com/en/demo/a-video.mp4>>>And then follow thebatchingfor more.
(and remember to startenumerateat the right number)>>>response=requests.get(response.json()['batching']['next'],...headers={'Accept':'application/json'},auth=2*('admin',))>>>fori,iteminenumerate(response.json()['items'],start=i+1):...print(i,item['@id'])...25https://plonedemo.kitconcept.com/en/frontpage26https://plonedemo.kitconcept.com/my-document>>>An Affen Session can take credentials and an api_root in the contructor, and
has anitemsfunction that iterates over anything in restapi that uses the
batching protocol; like Folders, Collectors and restapi endpoints like@search:>>>fromaffenimportSession>>>plone=Session('admin','admin','https://plonedemo.kitconcept.com')>>>fori,iteminenumerate(plone.items('@search?sort_on=path')):...print(i,item['@id'])...0https://plonedemo.kitconcept.com/de1https://plonedemo.kitconcept.com/de/Assets2https://plonedemo.kitconcept.com/de/demo3https://plonedemo.kitconcept.com/de/demo/a-image.jpg4https://plonedemo.kitconcept.com/de/demo/big_buck_bunny.mp45https://plonedemo.kitconcept.com/de/demo/ein-link6https://plonedemo.kitconcept.com/de/demo/ein-ordner7https://plonedemo.kitconcept.com/de/demo/ein-ordner/eine-seite-in-einem-ordner8https://plonedemo.kitconcept.com/de/demo/ein-termin9https://plonedemo.kitconcept.com/de/demo/eine-nachricht10https://plonedemo.kitconcept.com/de/demo/eine-seite11https://plonedemo.kitconcept.com/de/demo/ploneconf-plone5.pdf12https://plonedemo.kitconcept.com/de/frontpage13https://plonedemo.kitconcept.com/en14https://plonedemo.kitconcept.com/en/assets15https://plonedemo.kitconcept.com/en/demo16https://plonedemo.kitconcept.com/en/demo/a-event17https://plonedemo.kitconcept.com/en/demo/a-file.pdf18https://plonedemo.kitconcept.com/en/demo/a-folder19https://plonedemo.kitconcept.com/en/demo/a-folder/a-page-inside-a-folder20https://plonedemo.kitconcept.com/en/demo/a-link21https://plonedemo.kitconcept.com/en/demo/a-news-item22https://plonedemo.kitconcept.com/en/demo/a-page23https://plonedemo.kitconcept.com/en/demo/a-photo.jpg24https://plonedemo.kitconcept.com/en/demo/a-video.mp425https://plonedemo.kitconcept.com/en/frontpage26https://plonedemo.kitconcept.com/my-document>>>Wrangling the RegistryAnd if you have the permissions, you can read and write to the registry as if it were a dictionary:>>>plone=Session('admin','admin','http://127.0.0.1:8080/Plone')>>>plone.registry['plone.allowed_sizes']['large 768:768','preview 400:400','mini 200:200','thumb 128:128','tile 64:64','icon 32:32','listing 16:16']>>>plone.registry['plone.allowed_sizes']=['supersize_me 3840:2160']>>>plone.registry['plone.allowed_sizes']['supersize_me 3840:2160']>>>But my requests.Session does almost the same!>>>vanilla=requests.Session()>>>vanilla.auth=('admin','admin')>>>vanilla.headers['accept']='application/json'>>>ROOT='http://127.0.0.1:8080/Plone'>>># these two lines make it almost as short as Affen...>>>[t['title']fortinvanilla.get(f'{ROOT}/@types').json()]['Collection','Event','File','Folder','Image','Link','News Item','Page']>>># see? f-strings were such a great idea!>>># Affen is hardly shorter>>>[t['title']fortinplone.get('@types').json()]['Collection','Event','File','Folder','Image','Link','News Item','Page']>>>Sure, until you accidentally reuse the session for requests to a different
host. It's so conveniently close, and seems to behave likerequests.get. So
your mypy powered IDE didn't catch it. In fact, it provided handy
autocompletion, so it looked like the Right Thing™.>>>vanilla.get('https://httpbin.org/headers').json()['headers']['Authorization']'Basic YWRtaW46YWRtaW4='>>>OOPS, did we just send our 'Authorization' header to the nice people of httpbin.org?
An Affen Session will throw a fit when you try to do that:>>>plone.get('https://httpbin.org/headers').json()Traceback(mostrecentcalllast):...ValueError:Makingrequeststootherhoststhanhttp://127.0.0.1:8080/Plone/mayleakcredentials.Useadifferentrequests.Sessionforthoseorchangeroot>>># and even when whe change the api root>>>plone.root='https://httpbin.org'>>>plone.get('headers').json()['headers']['Authorization']Traceback(mostrecentcalllast):...KeyError:'Authorization'>>># it won't send the secrets