{"id":322,"date":"2021-03-27T21:43:24","date_gmt":"2021-03-27T21:43:24","guid":{"rendered":"https:\/\/andrejacobs.org\/?p=322"},"modified":"2022-04-11T20:24:23","modified_gmt":"2022-04-11T20:24:23","slug":"100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue","status":"publish","type":"post","link":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/","title":{"rendered":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue"},"content":{"rendered":"\n

Photo by Eden Constantino<\/a> on Unsplash<\/a><\/p>\n\n\n\n

Here is my Log book<\/a><\/p>\n

Git repository<\/a> for the functions.<\/p>\n

The next part in my Lego database learning project will be to schedule tasks that will go and download the Images. In order to do this I will need a task queue system.<\/p>\n

In the past I have used Celery but I came across RQ<\/a> (Redis Queue) while reading the Flask Mega Tutorial<\/a> and decided since I like using Redis this will be a natural fit.<\/p>\n

Redis<\/a> is an in-memory data structure store, used as a database, cache, and message broker.<\/p>\n

Installing Redis on faasd instance<\/h2>\n

As luck would have it, the book Serverless for Everyone Else<\/a> covers how to install redis directly on your faasd instance.<\/p>\n

Learning action point:<\/strong> Ideally all the extra services will be installed and configured from a single config file and not needing me to manually do it. I am guessing cloud-init can take care of that.<\/p>\n

SSH into the faasd instance.<\/p>\n

# SSH into the faasd instance\n$ ssh -i ~\/.ssh\/id_rsa -o PreferredAuthentications=publickey ubuntu@192.168.64.4\n...\nubuntu@faasd:~$\n<\/code><\/pre>\n

Create the directory in which the Redis data will be stored.<\/p>\n

ubuntu@faasd:~$ sudo mkdir -p \/var\/lib\/faasd\/redis\/data\nubuntu@faasd:~$ sudo chown -R 1000:1000 \/var\/lib\/faasd\/redis\/data\n\n# Confirm\nubuntu@faasd:~$ sudo ls -la \/var\/lib\/faasd\/redis\ntotal 12\ndrwxr-xr-x 3 root   root   4096 Mar 27 20:05 .\ndrw-r--r-- 4 root   root   4096 Mar 27 20:05 ..\ndrwxr-xr-x 2 ubuntu ubuntu 4096 Mar 27 20:05 data\n<\/code><\/pre>\n

Who is user and group with ID 1000?<\/p>\n

ubuntu@faasd:~$ whoami\nubuntu\nubuntu@faasd:~$ id\nuid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev),118(lxd)\nubuntu@faasd:~$ id root\nuid=0(root) gid=0(root) groups=0(root)\n\n# The default user 'ubuntu' has user and group ID of 1000\n<\/code><\/pre>\n

Add the Redis server to be installed and managed by faasd.<\/p>\n

ubuntu@faasd:~$ sudo nano \/var\/lib\/faasd\/docker-compose.yaml\n\n# Add this to the file\n  redis:\n    image: docker.io\/library\/redis:6.2.1-alpine\n    volumes:\n      - type: bind\n        source: .\/redis\/data\n        target: \/data\n    cap_add:\n      - CAP_NET_RAW\n    entrypoint: \/usr\/local\/bin\/redis-server --appendonly yes\n    user: "1000"\n    ports:\n      - "9988:6379"\n<\/code><\/pre>\n

I will be exposing the Redis server on port 9988 from the faasd instance (the multipass VM).<\/p>\n

Restart faasd and verify<\/p>\n

ubuntu@faasd:~$ sudo systemctl daemon-reload && sudo systemctl restart faasd\n\n# Tail (follow) the redis logs\nubuntu@faasd:~$ sudo journalctl -f -t openfaas:redis\n\n# On my Mac I checked if the faasd VM port is exposed\n$ nmap -Pn -p9988 192.168.64.4\n...\nPORT     STATE SERVICE\n9988\/tcp open  nsesrvr\n<\/code><\/pre>\n

Installing Python RQ (Redis Queue)<\/h2>\n

I will first be installing RQ locally and testing it from my Mac before adding to the OpenFaaS project.<\/p>\n

$ cd learn-openfaas\/legodb\n$ source legodb\/venv\/bin\/activate\n\n(venv)$ pip install rq\n(venv)$ pip freeze > legodb\/requirements.txt\n<\/code><\/pre>\n

I have one terminal window open to monitor the Redis server logs.<\/p>\n

ubuntu@faasd:~$ sudo journalctl -f -t openfaas:redis\n<\/code><\/pre>\n

Create a worker<\/h3>\n

We will need to start a worker that will accept tasks to be processed.<\/p>\n

# Need to figure out how to connect to the Redis server (and not just localhost)\n(venv)$ rq worker --help\n...\n-u, --url TEXT                  URL describing Redis connection details.\n\n# Ok lets spin up a worker\n(venv)$ rq worker -u 'redis:\/\/192.168.64.4:9988\/0' johnny5\n\n20:49:06 Worker rq:worker:c0b23f5bf6e14800bbcb83b5a87775ca: started, version 1.7.0\n20:49:06 Subscribing to channel rq:pubsub:c0b23f5bf6e14800bbcb83b5a87775ca\n20:49:06 *** Listening on johnny5...\n20:49:06 Cleaning registries for queue: johnny5\n<\/code><\/pre>\n

Create a task and test it works<\/h3>\n

Add a new file named tasks.py<\/code> in the same directory where handler.py lives. To test that Redis and RQ works, I will be using the example from Flask Mega Tutorial<\/a>.<\/p>\n

# tasks.py\nimport time\n\ndef example_task(seconds):\n    print('Starting task')\n    for i in range(seconds):\n        print(i)\n        time.sleep(1)\n    print('Task completed')\n<\/code><\/pre>\n

I modified my indev.py<\/code> file and ran it<\/p>\n

# indev.py\nfrom redis import Redis\nimport rq\n\nif __name__ == "__main__":\n    # Test RQ and Redis is working\n    queue = rq.Queue('johnny5', connection=Redis.from_url('redis:\/\/192.168.64.4:9988\/0'))\n    job = queue.enqueue('legodb.tasks.example_task', 42)\n    print(job.get_id())\n<\/code><\/pre>\n
(venv)$ python indev.py\nb147c143-53b1-469c-ba90-d264a1b8935f\n# ^^ the job.get_id()\n<\/code><\/pre>\n

The output from the worker<\/p>\n

20:57:35 johnny5: legodb.tasks.example_task(42) (b147c143-53b1-469c-ba90-d264a1b8935f)\nStarting task\n0\n1\n2\n...\n41\nTask completed\n20:58:17 johnny5: Job OK (b147c143-53b1-469c-ba90-d264a1b8935f)\n20:58:17 Result is kept for 500 seconds\n<\/code><\/pre>\n

\"\"<\/p>\n

Nice one!<\/strong> We have a worker running locally that can process tasks.<\/p>\n

Is this really using the faasd Redis server?<\/h3>\n

I noticed that monitoring the openfaas:redis logs had nothing about the worker or tasks and thus I was wondering if this is actually working the way I think it was. So I decided to do some testing.<\/p>\n

# Stop faasd\nubuntu@faasd:~$ sudo systemctl stop faasd\n<\/code><\/pre>\n

Not long after stopping faasd, the RQ worker logged the following.<\/p>\n

...\n21:06:52 Worker rq:worker:c0b23f5bf6e14800bbcb83b5a87775ca: found an unhandled exception, quitting...\n...\nredis.exceptions.ConnectionError: Connection closed by server.\nError 61 connecting to 192.168.64.4:9988. Connection refused.\n<\/code><\/pre>\n

Ok so the worker is indeed using Redis from our faasd instance. It also did stop running.<\/p>\n

Started it all up again and did another test run.<\/p>\n

ubuntu@faasd:~$ sudo systemctl start faasd\n\n(venv)$ rq worker -u 'redis:\/\/192.168.64.4:9988\/0' johnny5\n...\n21:16:37 *** Listening on johnny5...\n21:17:24 johnny5: legodb.tasks.example_task(42) (d65a042d-b188-4f70-878e-c132cfb34b6c)\nStarting task\n...\n<\/code><\/pre>\n

What happens when the task does not exist? I changed the name being requested to "legodb.tasks.example_task_fail" and ran it.<\/p>\n

(venv)$ python indev.py\n8a093e7a-a6d6-4746-98d1-9bdec7cce074\n# ^^ Interestingly we did get a job id\n\n# Worker output\n21:18:11 johnny5: legodb.tasks.example_task_fail(42) (8a093e7a-a6d6-4746-98d1-9bdec7cce074)\n... throws a big exception\nAttributeError: module 'legodb.tasks' has no attribute 'example_task_fail'\n<\/code><\/pre>\n

Ok at least the worker didn’t just quit.<\/p>\n

What happens when there is no worker with the specified name? I changed the name being requested to "johnny5_fail" and ran it.<\/p>\n

(venv)$ python indev.py\n3a50f84f-47db-400e-8b6a-41ab5d8c2bd5\n<\/code><\/pre>\n

Ok this is interesting. So there is no worker with that specified name but we did schedule the job to be run. My guess is the task is waiting in Redis until a worker with that name shows up for work.<\/p>\n

Let’s clock that worker bee in.<\/p>\n

(venv)$ rq worker -u 'redis:\/\/192.168.64.4:9988\/0' johnny5_fail\n...\n21:25:09 johnny5_fail: legodb.tasks.example_task(42) (3a50f84f-47db-400e-8b6a-41ab5d8c2bd5)\nStarting task\n0\n1\n...\n<\/code><\/pre>\n

Nice! Ok so you can schedule tasks even if no worker is running to pick up the tasks.<\/p>\n

Next actions<\/h2>\n

Tomorrow I will start hooking this up to my OpenFaaS function and also see how we can start workers on the faasd instance reliably.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"

Photo by Eden Constantino on Unsplash […]<\/p>\n

Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":324,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[37],"tags":[36,23,40],"yoast_head":"\n100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs<\/title>\n<meta name=\"description\" content=\"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs\" \/>\n<meta property=\"og:description\" content=\"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\" \/>\n<meta property=\"og:site_name\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-27T21:43:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-04-11T20:24:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/eden-constantino-OXmym9cuaEY-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1508\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:site\" content=\"@andrejacobs81\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Jacobs\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\"},\"author\":{\"name\":\"Andr\u00e9 Jacobs\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"headline\":\"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue\",\"datePublished\":\"2021-03-27T21:43:24+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\"},\"wordCount\":577,\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"keywords\":[\"OpenFaaS\",\"Python\",\"Redis\"],\"articleSection\":[\"100 Days Challenge\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\",\"url\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\",\"name\":\"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/#website\"},\"datePublished\":\"2021-03-27T21:43:24+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"description\":\"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.\",\"breadcrumb\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/andrejacobs.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/andrejacobs.org\/#website\",\"url\":\"https:\/\/andrejacobs.org\/\",\"name\":\"Andr\u00e9 Jacobs\",\"description\":\"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health\",\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/andrejacobs.org\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\",\"name\":\"Andr\u00e9 Jacobs\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"contentUrl\":\"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg\",\"width\":450,\"height\":450,\"caption\":\"Andr\u00e9 Jacobs\"},\"logo\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/\"},\"sameAs\":[\"https:\/\/andrejacobs.org\",\"https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw\"],\"url\":\"https:\/\/andrejacobs.org\/author\/andre\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs","description":"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/","og_locale":"en_GB","og_type":"article","og_title":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs","og_description":"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.","og_url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/","og_site_name":"Andr\u00e9 Jacobs","article_published_time":"2021-03-27T21:43:24+00:00","article_modified_time":"2022-04-11T20:24:23+00:00","og_image":[{"width":1920,"height":1508,"url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/eden-constantino-OXmym9cuaEY-unsplash.jpg","type":"image\/jpeg"}],"author":"Andr\u00e9 Jacobs","twitter_card":"summary_large_image","twitter_creator":"@andrejacobs81","twitter_site":"@andrejacobs81","twitter_misc":{"Written by":"Andr\u00e9 Jacobs","Estimated reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#article","isPartOf":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/"},"author":{"name":"Andr\u00e9 Jacobs","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"headline":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue","datePublished":"2021-03-27T21:43:24+00:00","dateModified":"2022-04-11T20:24:23+00:00","mainEntityOfPage":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/"},"wordCount":577,"publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"keywords":["OpenFaaS","Python","Redis"],"articleSection":["100 Days Challenge"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/","url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/","name":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue - Andr\u00e9 Jacobs","isPartOf":{"@id":"https:\/\/andrejacobs.org\/#website"},"datePublished":"2021-03-27T21:43:24+00:00","dateModified":"2022-04-11T20:24:23+00:00","description":"Day 19 of 100 complete. Today I will show you how to install Redis on your faasd instance and setup a task queue using RQ.","breadcrumb":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-19-installing-redis-on-faasd-and-using-python-rq-as-a-task-queue\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/andrejacobs.org\/"},{"@type":"ListItem","position":2,"name":"100 Days of Learning: Day 19 \u2013 Installing Redis on faasd and using Python RQ as a task queue"}]},{"@type":"WebSite","@id":"https:\/\/andrejacobs.org\/#website","url":"https:\/\/andrejacobs.org\/","name":"Andr\u00e9 Jacobs","description":"iOS Development, Electronics, Robotics, Artificial Intelligence, Business and Health","publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/andrejacobs.org\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68","name":"Andr\u00e9 Jacobs","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/","url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","contentUrl":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2019\/03\/andre_jacobs.jpg","width":450,"height":450,"caption":"Andr\u00e9 Jacobs"},"logo":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/image\/"},"sameAs":["https:\/\/andrejacobs.org","https:\/\/www.youtube.com\/channel\/UCzqXvnd_UJ3sAzQkQBD-IVw"],"url":"https:\/\/andrejacobs.org\/author\/andre\/"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/eden-constantino-OXmym9cuaEY-unsplash.jpg","_links":{"self":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/322"}],"collection":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/comments?post=322"}],"version-history":[{"count":2,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/322\/revisions"}],"predecessor-version":[{"id":325,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/322\/revisions\/325"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media\/324"}],"wp:attachment":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media?parent=322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/categories?post=322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/tags?post=322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}