{"id":3652419,"date":"2023-02-02T08:00:12","date_gmt":"2023-02-02T13:00:12","guid":{"rendered":"https:\/\/spin.atomicobject.com\/?p=3652419"},"modified":"2023-02-01T12:47:40","modified_gmt":"2023-02-01T17:47:40","slug":"compiling-python-openssl","status":"publish","type":"post","link":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/","title":{"rendered":"How to Compile Python with a Statically Linked OpenSSL on macOS"},"content":{"rendered":"<p>I&#8217;ve recently worked on software that requires a bundled installation of Python. The application itself is not written in Python, but it needs to run Python programs. And, we can&#8217;t rely on the destination already having the correct version of Python installed. The application runs on macOS and on Linux, but this post deals with macOS specifically.<\/p>\n<h2>Problem: How to Compile Python with a Statically Linked OpenSSL on macOS<\/h2>\n<p>To get the specific version of Python needed for the application (3.9.x), I knew I would have to compile it myself. Compiling Python from source is <a href=\"https:\/\/devguide.python.org\/getting-started\/setup-building\/\">well documented<\/a>. The <a href=\"https:\/\/devguide.python.org\/getting-started\/setup-building\/#macos\">macOS-specific instructions<\/a> eventually get running <code>configure<\/code> as follows:<\/p>\n<pre><code class=\"lang-bash\">\r\nCFLAGS=\"-I$(brew --prefix gdbm)\/include -I$(brew --prefix xz)\/include\" \\\r\n  LDFLAGS=\"-L$(brew --prefix gdbm)\/lib -L$(brew --prefix xz)\/lib\" \\\r\n  PKG_CONFIG_PATH=\"$(brew --prefix tcl-tk)\/lib\/pkgconfig\" \\\r\n  .\/configure --with-pydebug \\\r\n          --with-openssl=$(brew --prefix openssl@1.1) \\\r\n          --with-tcltk-libs=\"$(pkg-config --libs tcl tk)\" \\\r\n          --with-tcltk-includes=\"$(pkg-config --cflags tcl tk)\"\r\n<\/code><\/pre>\n<p>I didn&#8217;t want to install this Python on my local system but rather install it into a known directory. That way, I could zip it up and bundle it with the application I was packaging. To do that I specified a <code>--prefix=<\/code> argument:<\/p>\n<pre><code class=\"lang-bash\">\r\n...\r\n  .\/configure --prefix=\/Users\/patrick\/project\/python --with-pydebug \\\r\n  ...\r\n<\/code><\/pre>\n<p>After running <code>configure<\/code>, just make and install:<\/p>\n<pre><code class=\"lang-bash\">\r\nmake -s -j2\r\nmake install\r\n<\/code><\/pre>\n<p>Everything was looking good until we did some testing on other machines. It worked perfectly on some, but on others, it would fail during a step that was trying to use <code>pip<\/code> to install dependencies. The problem was that <code>pip<\/code> was trying to import the <code>ssl<\/code> module, and on some of the machines the version of OpenSSL I had installed (using <a href=\"https:\/\/formulae.brew.sh\/formula\/openssl@1.1\">Homebrew<\/a>) on my development machine, was not available.<\/p>\n<p>We didn&#8217;t want to create a dependency on the destination machine having a specific version of a Homebrew-installed OpenSSL available. So I set off looking for the instructions for how to statically link OpenSSL with our compiled Python.<\/p>\n<p>It turns out that this is not something officially supported by Python. (Someone <a href=\"https:\/\/github.com\/python\/cpython\/pull\/17153\">tried to get a PR accepted<\/a>, but it was eventually closed without being merged.)<\/p>\n<p>But while it&#8217;s not officially supported, there are a few ways to do it.<\/p>\n<h2>Compile OpenSSL<\/h2>\n<p>The first step is to compile the version of OpenSSL you want to link to. I wanted OpenSSL 1.1.1, so I cloned the <a href=\"https:\/\/github.com\/openssl\/openssl\">repo<\/a> and checked out the latest 1.1.1 tag (<code>OpenSSL_1_1_1s<\/code> at the time of writing), and ran the following<\/p>\n<pre><code class=\"lang-bash\">\r\n&gt; .\/config shared no-ssl2 no-ssl3 no-comp \\\r\n  --prefix=\/Users\/patrick\/project\/openssl \\\r\n  --openssldir=\/Users\/patrick\/project\/openssl\r\n\r\n&gt; make\r\n&gt; make install\r\n<\/code><\/pre>\n<h2>Modules\/Setup.local<\/h2>\n<p>With OpenSSL built, it&#8217;s now time to re-compile Python but statically linked to OpenSSL this time.<\/p>\n<p>The Python build system looks for a <code>Modules\/Setup.local<\/code> file to allow for some customization of the build. I came across a few references to it while searching. However, I was unable to find much documentation about how you&#8217;re supposed to use it.<\/p>\n<p>However, combining information found in a <a href=\"https:\/\/bugs.python.org\/msg389715\">message on the Python bug tracker<\/a>, and <a href=\"https:\/\/stackoverflow.com\/questions\/55928393\/compile-python-3-6-statically-with-openssl\">a StackOverflow answer<\/a>, I was able to piece together the following contents for my <code>Modules\/Setup.local<\/code> file (this is back in the Python source code directory, trying to compile version 3.9.x in my case).<\/p>\n<pre><code class=\"lang-text\">\r\nOPENSSL=\/Users\/patrick\/project\/openssl\r\n_ssl _ssl.c \\\r\n    -I$(OPENSSL)\/include -L$(OPENSSL)\/lib \\\r\n    $(OPENSSL)\/lib\/libssl.a \\\r\n    $(OPENSSL)\/lib\/libcrypto.a\r\n_hashlib _hashopenssl.c \\\r\n    -I$(OPENSSL)\/include -L$(OPENSSL)\/lib \\\r\n    $(OPENSSL)\/lib\/libcrypto.a\r\n<\/code><\/pre>\n<p>Now, you need to update the <code>configure<\/code> command to point to the compiled OpenSSL from the previous setup, instead of the Homebrew installed one:<\/p>\n<pre><code class=\"lang-bash\">\r\n&gt; CFLAGS=\"-I$(brew --prefix gdbm)\/include -I$(brew --prefix xz)\/include\" \\\r\n  LDFLAGS=\"-L$(brew --prefix gdbm)\/lib -L$(brew --prefix xz)\/lib\" \\\r\n  PKG_CONFIG_PATH=\"$(brew --prefix tcl-tk)\/lib\/pkgconfig\" \\\r\n  .\/configure --prefix=\/Users\/patrick\/project\/python \\\r\n          --with-pydebug \\\r\n          --with-openssl=\/Users\/patrick\/project\/openssl \\\r\n          --with-tcltk-libs=\"$(pkg-config --libs tcl tk)\" \\\r\n          --with-tcltk-includes=\"$(pkg-config --cflags tcl tk)\"\r\n&gt; make\r\n&gt; make install\r\n<\/code><\/pre>\n<p>At this point, I could just zip up the <code>\/Users\/patrick\/project\/python<\/code> directory and have a working version of Python that does not require a separate installation of OpenSSL.<\/p>\n<h2>PY_UNSUPPORTED_OPENSSL_BUILD<\/h2>\n<p>Starting in Python 3.10, there&#8217;s an &#8220;unsupported&#8221; way of specifying that you want to statically link OpenSSL . You set <code>PY_UNSUPPORTED_OPENSSL_BUILD<\/code> to <code>static<\/code>. (There&#8217;s no documentation for this, and my searches turned up almost nothing about it, but <a href=\"https:\/\/github.com\/python\/cpython\/commit\/bacefbf41461ab703b8d561f0e3d766427eab367\">here&#8217;s the commit<\/a>.)<\/p>\n<p>I needed version 3.9.x for the application I was working on, so I haven&#8217;t had a chance to actually try this out.<\/p>\n<h2>Hand Edit setup.py<\/h2>\n<p>If neither if the two options above work, it could be because you&#8217;re trying to compile an older version of Python. I believe the <code>Modules\/Setup.local<\/code> technique should work on older Pythons (before 3.9). However, since I haven&#8217;t actually tried, I thought I&#8217;d include another option I came across \u2014 hand editing the <code>setup.py<\/code> file.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/mzpqnxow\/bccc91be512a04dc6aeaa1375492672e\">This gist<\/a> is a patch for updating the <code>setup.py<\/code> for Python 3.8. If you apply those changes and then do the configure\/make\/install steps, you should end up with a Python build that&#8217;s statically linked to OpenSSL.<\/p>\n<h2>Caveat<\/h2>\n<p>We ran into some issues trying to run Python (built as described above) on a Mac running Monterey if Python was built on Ventura. However, if Python was built using Monterey, it seems to run just fine on both Monterey and on Ventura.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve recently worked on software that requires a bundled installation of Python. The application itself is not written in Python, but it needs to run Python programs. And, we can&#8217;t rely on the destination already having the correct version of Python installed. The application runs on macOS and on Linux, but this post deals with [&hellip;]<\/p>\n","protected":false},"author":407,"featured_media":3652872,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1858],"tags":[1332,2519],"series":[],"class_list":["post-3652419","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python-platforms-languages","tag-python","tag-openssl"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Compile Python with a Statically Linked OpenSSL on macOS<\/title>\n<meta name=\"description\" content=\"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Compile Python with a Statically Linked OpenSSL on macOS\" \/>\n<meta property=\"og:description\" content=\"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/\" \/>\n<meta property=\"og:site_name\" content=\"Atomic Spin\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/atomicobject\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-02T13:00:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Patrick Bacon\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@atomicobject\" \/>\n<meta name=\"twitter:site\" content=\"@atomicobject\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Patrick Bacon\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/\"},\"author\":{\"name\":\"Patrick Bacon\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/person\\\/b1ae70970124ba464ef398b4f93b4a65\"},\"headline\":\"How to Compile Python with a Statically Linked OpenSSL on macOS\",\"datePublished\":\"2023-02-02T13:00:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/\"},\"wordCount\":715,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/atomicobject.com\\\/\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg\",\"keywords\":[\"python\",\"openssl\"],\"articleSection\":[\"Python\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/\",\"name\":\"Compile Python with a Statically Linked OpenSSL on macOS\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg\",\"datePublished\":\"2023-02-02T13:00:12+00:00\",\"description\":\"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/compiling-python-openssl\\\/#primaryimage\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg\",\"width\":2560,\"height\":1707,\"caption\":\"Java Applications and macOS Automatic Proxy Configuration\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#website\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/\",\"name\":\"Atomic Spin\",\"description\":\"Atomic Object\u2019s blog on everything we find fascinating.\",\"publisher\":{\"@id\":\"https:\\\/\\\/atomicobject.com\\\/\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/spin.atomicobject.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#organization\",\"name\":\"Atomic Object\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/AO-Logo-Emblem-Color.png\",\"contentUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/AO-Logo-Emblem-Color.png\",\"width\":258,\"height\":244,\"caption\":\"Atomic Object\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/atomicobject\",\"https:\\\/\\\/x.com\\\/atomicobject\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/person\\\/b1ae70970124ba464ef398b4f93b4a65\",\"name\":\"Patrick Bacon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg\",\"caption\":\"Patrick Bacon\"},\"description\":\"Software Consultant and Developer. Loves making software, learning new technologies, and being an Atom.\",\"sameAs\":[\"http:\\\/\\\/www.linkedin.com\\\/in\\\/patrickbacon\\\/en\"],\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/author\\\/bacon\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Compile Python with a Statically Linked OpenSSL on macOS","description":"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.","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:\/\/spin.atomicobject.com\/compiling-python-openssl\/","og_locale":"en_US","og_type":"article","og_title":"Compile Python with a Statically Linked OpenSSL on macOS","og_description":"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.","og_url":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/","og_site_name":"Atomic Spin","article_publisher":"https:\/\/www.facebook.com\/atomicobject","article_published_time":"2023-02-02T13:00:12+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg","type":"image\/jpeg"}],"author":"Patrick Bacon","twitter_card":"summary_large_image","twitter_creator":"@atomicobject","twitter_site":"@atomicobject","twitter_misc":{"Written by":"Patrick Bacon","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#article","isPartOf":{"@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/"},"author":{"name":"Patrick Bacon","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/person\/b1ae70970124ba464ef398b4f93b4a65"},"headline":"How to Compile Python with a Statically Linked OpenSSL on macOS","datePublished":"2023-02-02T13:00:12+00:00","mainEntityOfPage":{"@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/"},"wordCount":715,"commentCount":4,"publisher":{"@id":"https:\/\/atomicobject.com\/"},"image":{"@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#primaryimage"},"thumbnailUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg","keywords":["python","openssl"],"articleSection":["Python"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/","url":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/","name":"Compile Python with a Statically Linked OpenSSL on macOS","isPartOf":{"@id":"https:\/\/spin.atomicobject.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#primaryimage"},"image":{"@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#primaryimage"},"thumbnailUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg","datePublished":"2023-02-02T13:00:12+00:00","description":"Statically linking OpenSSL to Python is not officially supported, but there are a couple of ways it can be done.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/spin.atomicobject.com\/compiling-python-openssl\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/spin.atomicobject.com\/compiling-python-openssl\/#primaryimage","url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg","contentUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/python-OpenSSL-JillDeVriesPhotography-Sept2019-50-scaled.jpg","width":2560,"height":1707,"caption":"Java Applications and macOS Automatic Proxy Configuration"},{"@type":"WebSite","@id":"https:\/\/spin.atomicobject.com\/#website","url":"https:\/\/spin.atomicobject.com\/","name":"Atomic Spin","description":"Atomic Object\u2019s blog on everything we find fascinating.","publisher":{"@id":"https:\/\/atomicobject.com\/"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/spin.atomicobject.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/spin.atomicobject.com\/#organization","name":"Atomic Object","url":"https:\/\/spin.atomicobject.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/logo\/image\/","url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/AO-Logo-Emblem-Color.png","contentUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/AO-Logo-Emblem-Color.png","width":258,"height":244,"caption":"Atomic Object"},"image":{"@id":"https:\/\/spin.atomicobject.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/atomicobject","https:\/\/x.com\/atomicobject"]},{"@type":"Person","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/person\/b1ae70970124ba464ef398b4f93b4a65","name":"Patrick Bacon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f41c671e4a227c4fa2a71be81c92fb792a243799d14fa702fbabd0e00a4ed8af?s=96&d=blank&r=pg","caption":"Patrick Bacon"},"description":"Software Consultant and Developer. Loves making software, learning new technologies, and being an Atom.","sameAs":["http:\/\/www.linkedin.com\/in\/patrickbacon\/en"],"url":"https:\/\/spin.atomicobject.com\/author\/bacon\/"}]}},"_links":{"self":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts\/3652419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/users\/407"}],"replies":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/comments?post=3652419"}],"version-history":[{"count":0,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts\/3652419\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/media\/3652872"}],"wp:attachment":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/media?parent=3652419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/categories?post=3652419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/tags?post=3652419"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/series?post=3652419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}