[RESOLVED] How to programmatically create users without stopping a (standalone) instance?

If I remember right, this is not a problem with the add-on, but a problem with (reading) your CSV file.

You need to figure out 'how to save the CSV file'.
There are so many options with CSV-files… from Excel (or whatever you use), try to save 'most of the versions' (encoding etc).

(you could try to save one from Windows (Excel) and now form OSX (Excel) and see it it differs.

UPDATE; It looks like reading CSV has changed in Python 3. Google your error and you will find it.

In this case, it is often best to ignore many of @zopyx responses. His technical advice if often excellent but he tends to accompany it with deprecative remarks. Just ignore those.

REST is a special approach to call functions (e.g. "create a user") on a Web server programmatically via HTTP requests. The natural way to do this would be to have a command/verb for each function to call. But, this is not the REST approach: it wants to limit itself to the small verb set of HTTP (GET, POST, PUT, DELETE, HEAD). To nevertheless be able to call functions, the functions are represented by resources, often true objects and sometimes pseudo objects representing a function.

The meaning of the cited documentation is as follows: To use the RESTApi, you construct an HTTP request (e.g. with the requests package). Such a request has a method (e.g. GET), an url, a set of headers and potentially a body. As url, you use the url to your portal; as headers, you provide Accept with value application/json; you provide authentication information (technically, this uses the Authentication header. but the request library likely provide a more convenient way to set this header). You will get back a JSON result (the above mentioned requests package can directly decode such results into a dict; otherwise, you can use Python's json module). In this result, you will likely find the resources representing the various functions provided by the RESTApi - and likely explained further down the documentation.

You can use Plone 5.2 with Python 2.7. If you are a non prefessional and depend on many 3rd party packages, this is likely still your best option, as many such packages are not yet Python 3 compatible (such as obviuosly collective.mass_subscriptions).

I created the .csv file in Emacs hence I guess the problem doesn't come from the way it was saved.

OK, I'll look at it.

@dieter Many thanks for your detailed answer! About @zopyx answers, it is was I noticed in the threads I read :slight_smile:

I decided to use Plone 5.2 with Python 3 because EOL of Python 2 will happen in few months and I wanted to not be annoyed by the necessity to upgrade later (when all the Plone machinery will be far from my brain :wink:).

Get over it :zipper_mouth_face:

For those like me, at a first glance scared by (Plone) REST(ful) API:

  1. follow the advice about Postman:
    1. install it,
    2. read how to explore the API using Postman,
  2. e.g. look at this video.

Et voilà! :grinning:

Could you give me a pointer to this requests package?

Visit PyPI, type "requests" in the search box, press enter. In Python 3, you could use services from urllib.request.

Ah, OK. I was looking in Plone packages (add-ons).

Outch! 10,000+ projects for "requests" :wink:.

Outch! 218 projects for "urllib.request" :wink:.

But OK :grinning:.

PyPI sorts by relevance: the requests distribution I had in mind is among the first 3 hits (was a few minutes ago).

urllib.request is a standard Python 3 module. You look for it in the Python (library) documentation (not PyPI).

After a quick test, it looks (to me) that the problem is not in collective.mass_subscription, but in how (Plone) 'reads the file' from the input field.

I didn't find time to investigate this problem. Did you find a workaround?

I don't need this, so it was just out of curiosity.

I would make a form using 'schema' (instead of a template) so one could choose another widget, or you could make a field where you could paste the CSV instead of uploading it (should be easy(?)).

The alternative is to find out 'where FileUploadObject comes from' (note: the name 'FileUploadObject' is taken from memory, so it could be something else

OK, but I didn't know you had in mind :wink:

OK, thanks.

OK, I'll maybe investigate this. But, since I succeeded to understand (a small bit) of plone.restapi, I'll follow this route for the moment.

Thanks!

This could also be possible with so called “External Methods”. https://zope.readthedocs.io/en/latest/zopebook/ScriptingZope.html

They should be configured in a special place in filesystem, in your case probably in directory parts/instance/Extensions and then added through ZMI.

They are considered “trusted code” so they can call plone.api methods, but you should take care they cannot be called without proper permission (either by managing permissions in ZMI or testing current user permissions with plone.api.

Thanks for this. Nevertheless, I'll probably stick with plone.restapi: it is very powerful and I suffered for learning it :slight_smile: