3

I created a graphic model which simply creates multiple vector attributes. All attributes are empty to be filled manually. Only one attribute column (let's call it KEYS), needs a different process and I'm kind of stuck at that point. I was able to come up with a short Python script that requests random numbers from random.org API. Script works, and I'm able to print out random numbers as a list.

What I couldn't achieve is to get those numbers to be written to KEYS column for every feature. I am aware of the graphical modeler tool called Advanced Python Field Calculator. What would be the way to achieve this?

I previously used

lyr = iface.activeLayer()
fts = lyr.getFeatures()
lyr.startEditing()
for f in fts:
    f['KEYS']='API LIST SHOULD ITERATE HERE'
    lyr.updateFeature(f)
lyr.commitChanges()

For something that did not need to iterate over features (it just writes whatever string in the 'API LIST SHOULD ITERATE HERE' part to KEYS column.

Finally I am pasting the full script I was able to come up with (doesn't work).

import requests
lyr = iface.activeLayer()
fts = lyr.getFeatures()
reqData = {
    "jsonrpc":"2.0",
    "method":"generateStrings",
    "params":{"apiKey":"myapikeygoeshere",
    "n":10,
    "length":20,
    "characters":"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
    "replacement":True
    },
    "id":539
    }

output_file = open
response = requests.post('https://api.random.org/json-rpc/2/invoke', json = reqData)
response.raise_for_status()
json = response.json()
data = json['result']['random']['data']
print(data)
print(sorted(data))

lyr.startEditing()
for f in fts:
    f['KEYS']='API LIST SHOULD ITERATE HERE'
    lyr.updateFeature(f)
lyr.commitChanges()

How do I get that lists content to be written to features in a specific column?

1 Answer 1

2
import requests
lyr = iface.activeLayer()
count = lyr.featureCount()

reqData = {
        "jsonrpc":"2.0",
        "method":"generateStrings",
        "params":{"apiKey":"myapikeygoeshere",
            "n":count,
            "length":20,
            "characters":"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
            "replacement":True},
        "id":539}

response = requests.post('https://api.random.org/json-rpc/2/invoke', json = reqData)
response.raise_for_status()
json = response.json()
data = json['result']['random']['data']

lyr.startEditing()
i = 0
for f in lyr.getFeatures():
    f['KEYS'] = data[i]
    lyr.updateFeature(f)
    i+=1
lyr.commitChanges()
3
  • Thank you! Works like a charm. Could you possibly tell me how would I use this in Advanced Python Field Calculator in the Graphic Modeller? I have a model that adds a field to the attribute table (named KEYS). Currently I first run the model then run this Python script in order to first create my attribute table fields then populate random strings using the Python script and trying to combine these two processes into one. Currently I got the crucial parts working and I really appreciate your help about that. Combining these two processes would be cherry on the top but not crucial.
    – puredata
    Jan 12, 2020 at 20:14
  • "Advanced Python Field Calculator" gives you a new layer. Is that OK? And I guess this question is about what you ask in comment above, right? Jan 12, 2020 at 21:50
  • Yes, a new layer is okay and both questions are connected; I'm trying to either embed the Python script that creates strings from API to my graphical model or export my graphical model as a Python script, add my Python script that creates the strings and save them as a Python script. In the question linked I exported my graphical model as a Python script and attempted to merge those two scripts together but couldn't get it to work. Both solutions work for my purposes. Thanks in advance for your interest and time!
    – puredata
    Jan 12, 2020 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.