API to CSV
Calls a JSON endpoint, puts one row per record into an in-memory table keyed on id, and
writes the table out as CSV. No browser, so it needs no robot window and finishes in a
fraction of a second.
The workflow
users = HttpRequest("https://jsonplaceholder.typicode.com/users", "GET")
WriteLine("{{ len(users) }} records returned")
CreateTable("contacts", schema={"columns": [{"name": "id", "isKey": True}, {"name": "name"}, {"name": "email"}, {"name": "city"}]})
for user in users: # _name="Collect contacts" _description="One row per API record, keyed on id so a rerun updates rather than duplicates"
TableUpsertRow("contacts", {"id": "{{ user.id }}", "name": "{{ user.name }}", "email": "{{ user.email }}", "city": "{{ user.address.city }}"})
export = TableExport("contacts", "C:/Temp/rinkt-examples/contacts.csv", format="csv")
WriteLine("Wrote {{ export.rows }} rows to {{ export.filePath }}")
The run
Activity completed [Create Table] -> {"columns": 4, "rows": 0, "tableName": "contacts"}
Activity completed [Upsert Row in Table] -> {"action": "inserted", "totalRows": 1}
...
Activity completed [Upsert Row in Table] -> {"action": "inserted", "totalRows": 10}
Activity completed [Export Table to File] -> {"filePath": "C:/Temp/rinkt-examples/contacts.csv", "format": "csv", "rows": 10}
Activity completed [Print to Console] -> Wrote 10 rows to C:/Temp/rinkt-examples/contacts.csv
And the file:
id,name,email,city
1,Leanne Graham,Sincere@april.biz,Gwenborough
2,Ervin Howell,Shanna@melissa.tv,Wisokyburgh
3,Clementine Bauch,Nathan@yesenia.net,McKenziehaven
What it got wrong first
The first version had a Parse JSON between the request and the loop:
response = HttpRequest("https://jsonplaceholder.typicode.com/users", "GET")
users = ParseJson(response) # wrong
It failed in a second:
Failed to parse JSON — invalid character 'm' looking for beginning of value
HTTP Request already returns parsed JSON. Its output is typed
json, not string. Handing that to ParseJson hands it a map, and the 'm' the parser
complains about is the first character of the map's own printed form. Use ParseJson for a
JSON string you got from somewhere else — a file, a page, a column — not for a response.
Worth taking from it
Key columns decide what a rerun does. {"name": "id", "isKey": True} is what makes
Upsert Row in Table update record 4 on the second run instead of
appending a second copy of it. Without a key column the activity requires append=True, and
then reruns grow the file.
Name the loop, not the step inside it. # _name="Collect contacts" on the for line
names the For Each on the canvas and in the logs. Control-flow metadata goes in a comment
on the header line, because the statement has no argument list to put it in.
A Group hides its variables from the validator. Wrapping the request and the parse in
with Group("Fetch"): made the loop below fail validation with Variable 'users' is not
defined — the collection could not see a name assigned inside the group. Assign at the top
level and group the steps that do not produce anything you need later.