{"id":266,"date":"2021-03-19T22:38:03","date_gmt":"2021-03-19T22:38:03","guid":{"rendered":"https:\/\/andrejacobs.org\/?p=266"},"modified":"2022-04-11T20:24:23","modified_gmt":"2022-04-11T20:24:23","slug":"100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas","status":"publish","type":"post","link":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/","title":{"rendered":"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS"},"content":{"rendered":"\n

Photo by benjamin lehman<\/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

Adding MariaDB connector as a dependency<\/h2>\n

Continuing on from yesterday where I had a mocked API in place, the next phase is to add storage for the lego database.<\/p>\n

I will be using SQLAlchemy<\/a> as the ORM layer and this will connect to the MariaDB instance I have setup in AWS RDS. In other to connect to MariaDB I will need to use mysql-connector<\/s> MariaDB connector<\/a><\/p>\n

Develop and test locally<\/h2>\n

Instead of doing trial and error development, I want to develop and test the Python code locally on my machine first and once I know it works it can be transferred to the OpenFaaS code.<\/p>\n

$ cd legodb\/legodb\n$ ls\nhandler.py        requirements.txt\n\n# Install and activate a virtual environment\n$ python3 -m venv .\/venv\n$ source venv\/bin\/activate\n(venv)$\n\n(venv)$ python3 -m pip install --upgrade pip\n<\/code><\/pre>\n

Installing mariadb-connector-c and mariadb (connector)<\/h3>\n
(venv)$ brew install mariadb-connector-c\n(venv)$ pip install mariadb\n\nCollecting mariadb\n  Using cached mariadb-1.0.6.tar.gz (67 kB)\nUsing legacy 'setup.py install' for mariadb, since package 'wheel' is not installed.\nInstalling collected packages: mariadb\n    Running setup.py install for mariadb ... done\nSuccessfully installed mariadb-1.0.6\n<\/code><\/pre>\n

The MariaDB connector for Python requires the MariaDB connector for C to be installed first. This is going to be a learning curve later to see how I get the faas-cli + template + faasd to install these dependencies (including C ones on basically an Ubuntu image)<\/p>\n

Make a test connection<\/h3>\n

First I am testing to see if the connector is working and that I can connect to AWS database.<\/p>\n

(venv)$ python\n>>> import mariadb\n>>> connection = mariadb.connect(user="admin", \\\npassword="DA_PASSWORD", \\\nhost="xyzabc.rds.amazonaws.com", \\\nport=3306,database="openfaasdb")\n>>> cursor = connection.cursor()\n>>> cursor.execute("SELECT Description FROM openfaasdb.legosets")\n>>> for description in cursor:\n...     print(description)\n...\n('Pirates of Barracuda Bay',)\n('Medieval Blacksmith',)\n>>> exit() # This is a bit like the "how do you quit vim?"\n<\/code><\/pre>\n

Nice! Ok next test is to add it to the handler.py and see if we can get the dependencies to install correctly on faasd.<\/p>\n

Configure function and dependencies<\/h2>\n
# Update the requirments.txt to include the packages we have installed locally\n(venv)$ pip freeze > requirements.txt\n(venv)$ cat requirements.txt\nmariadb==1.0.6\n<\/code><\/pre>\n

I am 100% sure that running faas-cli up will explode because we need a way to also specify that mariadb-connector-c be installed. If faas-cli doesn’t explode then faasd surely will.<\/p>\n

$ faas-cli up -f legodb.yml\n...\n#22 [stage-1 14\/18] COPY function\/requirements.txt\t.\n#22 sha256:333b1ca8a3738bc696305e1b571339f0dd690a63f9211340f23111e9be70c1ed\n#22 DONE 0.2s\n\n#23 [stage-1 15\/18] RUN pip install --user -r requirements.txt\n#23 sha256:bc0ee19013bf0423e61eb77d7d2f6e9ae7fc90b25b9557e7d451250819bb3c0d\n#23 1.848 Collecting mariadb==1.0.6\n#23 2.017   Downloading mariadb-1.0.6.tar.gz (67 kB)\n#23 2.286     ERROR: Command errored out with exit status 1:\n...\n#23 2.286     OSError: mariadb_config not found.\n#23 2.286\n#23 2.286     Please make sure, that MariaDB Connector\/C is installed on your system.\n#\n<\/code><\/pre>\n

Ok that confirms at least that during faas-cli build it will explode.<\/p>\n

Down the rabbit hole<\/h3>\n

My suspicion earlier was spot on that it was going to be a learning curve to figure out how to get other non-python dependencies working.<\/p>\n

I read a number of docs and tutorials and even came across a github issue for OpenFaaS that described you can pass values to the template’s Dockerfile from you yaml file. But sometimes you will read a lot of things and the brain has not yet made all the required connections.<\/p>\n

Below I will describe the process I went through to figure this out.<\/p>\n

# 1st attempt, I edited template.yml\nbuild_options:\n  - name: dev\n    packages:\n      ... \n      - mariadb-connector-c\n# Failed in the same way about not being able to find mariadb_config\n\n# 2nd attempt, I edited legodb.yml\nfunctions:\n  legodb:\n    ...\n    build_args:\n      # ADDITIONAL_PACKAGE is used in the Dockerfile\n      ADDITIONAL_PACKAGE: mariadb-connector-c\n# Failed in the same way\n\n# 3rd attempt, I found a StackOverflow post about that you might also need mariadb-dev\n    ADDITIONAL_PACKAGE: mariadb-dev mariadb-connector-c\n# Ok we are getting somewhere, the error is now about not being able to find gcc\n\n# 4th attempt\n    ADDITIONAL_PACKAGE: gcc mariadb-dev mariadb-connector-c\n# Now the error is about gcc not being able to find limits.h header file\n<\/code><\/pre>\n

Clearly I need help here. So I joined the OpenFaaS Slack<\/a> and asked for help on this. Also I called it quits at this stage for the night.<\/p>\n

Next day I got a reply from Richard Gee<\/a> saying that the build_options would be a better place for this and pointed me to the docs<\/a>.<\/p>\n

Ironically my 1st attempt was on the right path, but the missing bit was that I assumed that the packages from the template.yml was being used during faas-cli build<\/code>. Turns out you have to pass --build-option dev<\/code> to install the listed packages.<\/p>\n

# template.yml\nlanguage: python3-http\nfprocess: python index.py\nbuild_options:\n  - name: dev\n    packages: \n      # ... Added the following 2 packages\n      - mariadb-dev\n      - mariadb-connector-c\n\n$ faas-cli up --build-option dev -f legodb.yml\n# This worked!\n<\/code><\/pre>\n

Getting the list of Lego sets from MariaDB<\/h2>\n

First we need to start using secrets and environment variables to pass the database details to the OpenFaaS function.<\/p>\n

version: 1.0\nprovider:\n  name: openfaas\n  gateway: http:\/\/192.168.64.4:9999\nfunctions:\n  legodb:\n    lang: python3-http\n    handler: .\/legodb\n    image: andrejacobs42\/legodb:latest\n    environment:\n      database-name: openfaasdb\n      database-port: 3306\n    secrets:\n      - database-host\n      - database-user\n      - database-password\n<\/code><\/pre>\n

Supply the secrets to the faasd instance.<\/p>\n

# Copy the hostname and then create secret\n$ pbpaste | faas-cli secret create database-host\nCreating secret: database-host\nCreated: 200 OK\n\n# Copy the username and then create secret\n$ pbpaste | faas-cli secret create database-user\n\n# Copy the password and then create secret\n$ pbpaste | faas-cli secret create database-password\n<\/code><\/pre>\n

I will be using MariaDB directly to query the database.<\/p>\n

import os\nimport json\nimport mariadb\n\n# GET \/legosets : Returns the list of lego sets\n# POST \/legoset : Add a new lego set to the database\n\ndef handle(event, context):\n    response = {'statusCode': 400}\n\n    if event.method == 'GET':\n        if event.path == '\/legosets':\n            legosets = get_list_of_legosets()\n            response = {'statusCode': 200, \n                'body': legosets,\n                'headers': {'Content-Type': 'application\/json'}\n                }\n    elif event.method == 'POST':\n        if event.path == '\/legoset':\n            response = add_new_legoset(event.body)\n   \n    return response\n\ndef load_secret(name):\n    filepath = os.path.join('\/var\/openfaas\/secrets\/', name)\n    with open(filepath) as f:\n        secret = f.read()\n    return secret\n\ndef database_connection():\n    host = load_secret('database-host')\n    user = load_secret('database-user')\n    password = load_secret('database-password')\n    database_name = os.environ.get('database-name')\n    database_port = int(os.environ.get('database-port', '3306'))\n\n    try:\n        connection = mariadb.connect(\n            user=user,\n            password=password,\n            host=host,\n            port=database_port,\n            database=database_name\n        )\n        return connection\n    except mariadb.Error as error:\n        print(f"Error: {error}")\n        return None\n\ndef get_list_of_legosets():\n    try:\n        connection = database_connection()\n        cursor = connection.cursor()\n        cursor.execute("SELECT LegoID, Description FROM legosets")\n        result = []\n        for legoID, description in cursor:\n            result.append({ "legoID": legoID, "description": description})\n        return {"sets": result}\n    except mariadb.Error as error:\n        print(f"Error{error}")\n        return {"error": f"{error}"}\n\ndef add_new_legoset(body):\n    response = None\n    try:\n        inputJSON = json.loads(body.decode('utf8').replace("'", '"'))\n        response = {\n            'statusCode': 200,\n            'body': {'received': inputJSON},\n            'headers': {'Content-Type': 'application\/json'}\n        }\n    except ValueError:\n        response = {\n            'statusCode': 400,\n            'body': {'reason': 'Invalid JSON'},\n            'headers': {'Content-Type': 'application\/json'}\n         }\n    return response\n<\/code><\/pre>\n

Build and test<\/p>\n

$ faas-cli up --build-option dev -f legodb.yml\n$ curl -s http:\/\/192.168.64.4:9999\/function\/legodb\/legosets | jq\n{\n  "sets": [\n    {\n      "description": "Pirates of Barracuda Bay",\n      "legoID": 21322\n    },\n    {\n      "description": "Medieval Blacksmith",\n      "legoID": 21325\n    }\n  ]\n}\n<\/code><\/pre>\n

\"\"<\/p>\n

Next actions<\/h3>\n

Tomorrow I will start exploring the use of SQLAlchemy<\/a>.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"

Photo by benjamin lehman on Unsplash […]<\/p>\n

Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":269,"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":[39,36,23],"yoast_head":"\n100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs<\/title>\n<meta name=\"description\" content=\"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.\" \/>\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-10-11-connecting-to-mariadb-from-python-and-openfaas\/\" \/>\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 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs\" \/>\n<meta property=\"og:description\" content=\"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\" \/>\n<meta property=\"og:site_name\" content=\"Andr\u00e9 Jacobs\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-19T22:38:03+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\/benjamin-lehman-GNyjCePVRs8-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1280\" \/>\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=\"6 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-10-11-connecting-to-mariadb-from-python-and-openfaas\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\"},\"author\":{\"name\":\"Andr\u00e9 Jacobs\",\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"headline\":\"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS\",\"datePublished\":\"2021-03-19T22:38:03+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\"},\"wordCount\":522,\"publisher\":{\"@id\":\"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68\"},\"keywords\":[\"MariaDB\",\"OpenFaaS\",\"Python\"],\"articleSection\":[\"100 Days Challenge\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\",\"url\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\",\"name\":\"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs\",\"isPartOf\":{\"@id\":\"https:\/\/andrejacobs.org\/#website\"},\"datePublished\":\"2021-03-19T22:38:03+00:00\",\"dateModified\":\"2022-04-11T20:24:23+00:00\",\"description\":\"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.\",\"breadcrumb\":{\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/andrejacobs.org\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS\"}]},{\"@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 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs","description":"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.","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-10-11-connecting-to-mariadb-from-python-and-openfaas\/","og_locale":"en_GB","og_type":"article","og_title":"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs","og_description":"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.","og_url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/","og_site_name":"Andr\u00e9 Jacobs","article_published_time":"2021-03-19T22:38:03+00:00","article_modified_time":"2022-04-11T20:24:23+00:00","og_image":[{"width":1920,"height":1280,"url":"https:\/\/andrejacobs.org\/wp-content\/uploads\/2021\/03\/benjamin-lehman-GNyjCePVRs8-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":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/#article","isPartOf":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/"},"author":{"name":"Andr\u00e9 Jacobs","@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"headline":"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS","datePublished":"2021-03-19T22:38:03+00:00","dateModified":"2022-04-11T20:24:23+00:00","mainEntityOfPage":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/"},"wordCount":522,"publisher":{"@id":"https:\/\/andrejacobs.org\/#\/schema\/person\/3d38360883015e883c80c2fb875c5a68"},"keywords":["MariaDB","OpenFaaS","Python"],"articleSection":["100 Days Challenge"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/","url":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/","name":"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS - Andr\u00e9 Jacobs","isPartOf":{"@id":"https:\/\/andrejacobs.org\/#website"},"datePublished":"2021-03-19T22:38:03+00:00","dateModified":"2022-04-11T20:24:23+00:00","description":"Day 10 and 11 of 100 complete. Today I managed to connect to MariaDB from Python and the OpenFaaS function.","breadcrumb":{"@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/andrejacobs.org\/100-days-challenge\/100-days-of-learning-day-10-11-connecting-to-mariadb-from-python-and-openfaas\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/andrejacobs.org\/"},{"@type":"ListItem","position":2,"name":"100 Days of Learning: Day 10 & 11 \u2013 Connecting to MariaDB from Python and OpenFaaS"}]},{"@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\/benjamin-lehman-GNyjCePVRs8-unsplash.jpg","_links":{"self":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/266"}],"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=266"}],"version-history":[{"count":4,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/266\/revisions"}],"predecessor-version":[{"id":272,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/posts\/266\/revisions\/272"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media\/269"}],"wp:attachment":[{"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/media?parent=266"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/categories?post=266"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andrejacobs.org\/wp-json\/wp\/v2\/tags?post=266"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}