{"id":1001,"date":"2018-02-10T13:00:07","date_gmt":"2018-02-10T13:00:07","guid":{"rendered":"http:\/\/chewett.co.uk\/blog\/?p=1001"},"modified":"2020-09-26T22:07:51","modified_gmt":"2020-09-26T21:07:51","slug":"raspberry-pi-cluster-node-04-configuration-files-configparser","status":"publish","type":"post","link":"https:\/\/chewett.co.uk\/blog\/1001\/raspberry-pi-cluster-node-04-configuration-files-configparser\/","title":{"rendered":"Raspberry Pi Cluster Node \u2013 04 Configuration Files with ConfigParser"},"content":{"rendered":"\n<p>This post builds on the&nbsp;<a href=\"http:\/\/chewett.co.uk\/blog\/901\/raspberry-pi-cluster-node-03-basic-node-communication-two-nodes\/\">third step to create a Raspberry Pi Cluster Node<\/a>&nbsp;to store our configuration settings in a config file. Here we move all the configuration settings in our script into a useful .cfg file using the python ConfigParser.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Why use Configuration Files?<\/h2>\n\n\n\n<p>When developing a system there will always be variables you will want to tweak based on the machine its running on. These are typically simple settings such as the machine name, connection settings or passwords.<\/p>\n\n\n\n<p>Ideally these settings are not hardcoded into our code but are outside the codebase. One major reason for doing this is because you do not want to hardcode passwords into your codebase. So developers typically save these important settings in configuration files. The scripts then read these configuration files to find the details they need.<\/p>\n\n\n\n<p>In our previous script we hardcoded the IP address and socket port number used. This means that if we wanted to change the IP or port we would need to modify the code. This doesn&#8217;t make the script very flexible.<\/p>\n\n\n\n<p>In this tutorial I am going to remove the hard-coded IP address and port number and use a configuration file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the ConfigParser Module<\/h2>\n\n\n\n<p>Python has the <code>ConfigParser<\/code> module that reads a file and loads the settings. This module loads files in the ini&nbsp;format. These are basic text files with specific formatting that allows a program to read in settings.<\/p>\n\n\n\n<p>An example file format, as taken from the python docs,&nbsp;is shown below:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><span class=\"s2\">[mysqld]<\/span>\n<span class=\"s2\">user = mysql<\/span>\n<span class=\"s2\">pid-file = \/var\/run\/mysqld\/mysqld.pid<\/span>\n<span class=\"s2\">skip-external-locking<\/span>\n<span class=\"s2\">old_passwords = 1<\/span>\n<span class=\"s2\">skip-bdb<\/span>\n<span class=\"s2\">skip-innodb<\/span><\/pre>\n\n\n\n<p>The file is split up into sections, denoted by the square brackets. Each section then has a series of variables which may be set to a value with the equals sign.<\/p>\n\n\n\n<p>We are going to use this format with the ConfigParser python module.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Changing out code to use ConfigParser<\/h2>\n\n\n\n<p>First I am going to create the config parser configuration file. For this I have chosen to have two sections, one for the master and one for the slaves. The example file is below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[master]\nsocket_port = 12345\nsocket_bind_ip =\n\n<\/pre>\n\n\n<p>[slave]<\/p>\n\n\n\n<p>\nsocket_port = 12345\nmaster_ip = 127.0.0.1\n<\/p>\n\n\n\n<p>Now I have the file, the first thing I need to do is load up the config file in my scripts. This is performed by importing ConfigParser and creating a new instance of the config as follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">import ConfigParser\n\nconfig = ConfigParser.ConfigParser()\nconfig.read('rpicluster.cfg')<\/pre><\/pre>\n\n\n\n<p>I place the import statement with all the other import statements at the top of the file. Then I create an instance of the ConfigParser and tell it to read my config file.&nbsp; This reads in the file and all configuration options.<\/p>\n\n\n\n<p>Now it has loaded my config file up I can get out specific parts of the configuration<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">master_ip = config.get(\"slave\", \"master_ip\")\nsocket_port = config.getint(\"slave\", \"socket_port\")<\/pre><\/pre>\n\n\n\n<p>In the above code I have used two different methods of the config variable defined above. Both of these functions take two parameters, the section name of the config and the config name. The most basic one is <code>get<\/code>&nbsp;which gets the config value as a string.<\/p>\n\n\n\n<p>Similar to <code>get<\/code>, <code>getint<\/code>&nbsp;gets the value of the config but also converts it to an integer. I have used <code>getint<\/code>&nbsp;for the port of the socket as this is required to be an integer. In addition to this there is also <code>getfloat<\/code> and <code>getboolean<\/code> which converts the value to a float and boolean respectively.<\/p>\n\n\n\n<p>For the future I am going to store more values in the configuration settings. This means I can get away from hardcoding variables in my script and make it more flexible.<\/p>\n\n\n\n<p>The full code is\u00a0<a href=\"https:\/\/github.com\/chewett\/RaspberryPiCluster\/releases\/tag\/v4.0\" target=\"_blank\" rel=\"noreferrer noopener\">available on Github<\/a>, any comments or questions can be raised there as issues or posted below.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post builds on the&nbsp;third step to create a Raspberry Pi Cluster Node&nbsp;to store our configuration settings in a config file. Here we move all the configuration settings in our script into a useful .cfg file using the python ConfigParser.<\/p>\n","protected":false},"author":1,"featured_media":1003,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[122],"tags":[39,184,37,101],"class_list":["post-1001","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-cluster","tag-linux","tag-python","tag-raspberry-pi","tag-raspberry-pi-cluster"],"wppr_data":{"cwp_meta_box_check":"No"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/02\/rpi_cluster_04_config_parser.jpg?fit=800%2C800&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p2toWX-g9","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1054,"url":"https:\/\/chewett.co.uk\/blog\/1054\/raspberry-pi-tutorial-website-online-now\/","url_meta":{"origin":1001,"position":0},"title":"Raspberry Pi Tutorial Website online now!","author":"Chewett","date":"March 10, 2018","format":false,"excerpt":"This post talks about the new page on my website with linking to all my Raspberry Pi Cluster tutorials. Raspberry Pi Cluster Tutorial Webpage Now I have a couple Raspberry Pi Cluster tutorials I decided to link to all of them on my website. This will form the basis of\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2780,"url":"https:\/\/chewett.co.uk\/blog\/2780\/raspberry-pi-cluster-node-18-raspberry-pi-temperature-monitoring\/","url_meta":{"origin":1001,"position":1},"title":"Raspberry Pi Cluster Node \u2013 18 Raspberry Pi Temperature Monitoring","author":"Chewett","date":"February 20, 2021","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by starting to log temperature with the RaspberryPiVcgencmd Python module. Installing RaspberryPiVcgencmd RaspberryPiVcgencmd is a small python module aimed to control vcgencmd and allow programmatic access to it. This can be installed with the following command. python3 -m pip\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":2002,"url":"https:\/\/chewett.co.uk\/blog\/2002\/raspberry-pi-cluster-node-12-automatic-start-with-rc-local\/","url_meta":{"origin":1001,"position":2},"title":"Raspberry Pi Cluster Node \u2013 12 Automatic Start with rc.local","author":"Chewett","date":"March 6, 2019","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series by creating a script which automatically starts the slave and master with rc.local. What is the rc.local file? The rc.local file is used on many Linux operating systems to schedule operations to run after services are started on\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/rpi_cluster_12_automatic_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/rpi_cluster_12_automatic_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/rpi_cluster_12_automatic_start.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/02\/rpi_cluster_12_automatic_start.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2680,"url":"https:\/\/chewett.co.uk\/blog\/2680\/raspberry-pi-cluster-node-16-python-3-codebase-refactor\/","url_meta":{"origin":1001,"position":3},"title":"Raspberry Pi Cluster Node \u2013 16 Python 3 Codebase Refactor","author":"Chewett","date":"October 24, 2020","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by improving the codebase for Python 3. Moving to Python 3 Python 2 was marked end of life on January 1st, 2020 and therefore applications should ideally be no longer using Python 2. There will still be a lot\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/10\/raspi_cluster_16_python3refactor_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/10\/raspi_cluster_16_python3refactor_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/10\/raspi_cluster_16_python3refactor_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/10\/raspi_cluster_16_python3refactor_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2020\/10\/raspi_cluster_16_python3refactor_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":2952,"url":"https:\/\/chewett.co.uk\/blog\/2952\/running-a-python-script-on-boot-with-systemd\/","url_meta":{"origin":1001,"position":4},"title":"Running a Python Script on Boot with Systemd","author":"Chewett","date":"August 7, 2021","format":false,"excerpt":"This short blog post details how you can run a python script on boot using systemd. Using Systemd to manage the python script Systemd is a daemon that is used to control various aspects of services and initialization scripts that run on and after boot. It is used by a\u2026","rel":"","context":"In &quot;Informational&quot;","block_context":{"text":"Informational","link":"https:\/\/chewett.co.uk\/blog\/category\/informational\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/07\/systemd_bootup_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":1839,"url":"https:\/\/chewett.co.uk\/blog\/1839\/raspberry-pi-cluster-node-08-slave-helper-functions\/","url_meta":{"origin":1001,"position":5},"title":"Raspberry Pi Cluster Node &#8211; 08 Slave Helper Functions","author":"Chewett","date":"December 19, 2018","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by adding a number of slave helper functions.\u00a0 This update will begin the process of fully automating the slaves. Preparing the Slaves for Automation Before the slaves are ready to be fully automated there are a number of commands\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_08_slave_functions.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1001","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=1001"}],"version-history":[{"count":5,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1001\/revisions"}],"predecessor-version":[{"id":2653,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1001\/revisions\/2653"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media\/1003"}],"wp:attachment":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=1001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=1001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=1001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}