PageSourceSearch

https://andypi.co.uk/

html andypi.co.uk collected 2026-09-24 18:13:34 UTC 66,300 bytes, 827 lines download raw bytes

1<!DOCTYPE html>
2
3<html lang="en-GB">
4
5	<head>
6		
7		<meta charset="UTF-8">
8		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" >
9						 
10		<title>AndyPi &#8211; Python &amp; Programming</title>
11<meta name='robots' content='max-image-preview:large' />
12<link rel="alternate" type="application/rss+xml" title="AndyPi &raquo; Feed" href="https://andypi.co.uk/feed/" />
13<link rel="alternate" type="application/rss+xml" title="AndyPi &raquo; Comments Feed" href="https://andypi.co.uk/comments/feed/" />
14<style id="wp-img-auto-sizes-contain-inline-css">
15img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px}
16/*# sourceURL=wp-img-auto-sizes-contain-inline-css */
17</style>
18<style id="wp-emoji-styles-inline-css">
19
20	img.wp-smiley, img.emoji {
21		display: inline !important;
22		border: none !important;
23		box-shadow: none !important;
24		height: 1em !important;
25		width: 1em !important;
26		margin: 0 0.07em !important;
27		vertical-align: -0.1em !important;
28		background: none !important;
29		padding: 0 !important;
30	}
31/*# sourceURL=wp-emoji-styles-inline-css */
32</style>
33<style id="wp-block-library-inline-css">
34:root{--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color);--wp-editor-canvas-background:#ddd;--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,160.5;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-element-button{cursor:pointer}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}:root{--wp--preset--font-size--normal:16px;
34--wp--preset--font-size--huge:42px}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}:root .has-text-align-center{text-align:center}:root .has-text-align-left{text-align:left}:root .has-text-align-right{text-align:right}.has-fit-text{white-space:nowrap!important}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{word-wrap:normal!important;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style*=border-color]){border-style:solid}html :where([style*=border-top-color]){border-top-style:solid}html :where([style*=border-right-color]){border-right-style:solid}html :where([style*=border-bottom-color]){border-bottom-style:solid}html :where([style*=border-left-color]){border-left-style:solid}html :where([style*=border-width]){border-style:solid}html :where([style*=border-top-width]){border-top-style:solid}html :where([style*=border-right-width]){border-right-style:solid}html :where([style*=border-bottom-width]){border-bottom-style:solid}html :where([style*=border-left-width]){border-left-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}}
35
36/*# sourceURL=/wp-includes/css/dist/block-library/common.min.css */
37</style>
38<style id="classic-theme-styles-inline-css">
39/*! This file is auto-generated */
40.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none}
41/*# sourceURL=/wp-includes/css/classic-themes.min.css */
42</style>
43
44<style id="global-styles-inline-css">
45:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #222;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #fff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--color--accent: #13C4A5;--wp--preset--color--dark-gray: #444;--wp--preset--color--medium-gray: #666;--wp--preset--color--light-gray: #888;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgb(252,185,0) 0%,rgb(255,105,0) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgb(255,105,0) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);
45--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 16px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 24px;--wp--preset--font-size--x-large: 42px;--wp--preset--font-size--regular: 18px;--wp--preset--font-size--larger: 32px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgb(255, 255, 255), 6px 6px rgb(0, 0, 0);--wp--preset--shadow--crisp: 6px 6px 0px rgb(0, 0, 0);}:where(body) { margin: 0; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #32373c;border-width: 0;color: #fff;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;letter-spacing: inherit;line-height: inherit;padding-top: calc(0.667em + 2px);padding-right: calc(1.333em + 2px);padding-bottom: calc(0.667em + 2px);padding-left: calc(1.333em + 2px);text-decoration: none;text-transform: inherit;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-accent-color{color: var(--wp--preset--color--accent) !important;}.has-dark-gray-color{color: var(--wp--preset--color--dark-gray) !important;}.has-medium-gray-color{color: var(--wp--preset--color--medium-gray) !important;}.has-light-gray-color{color: var(--wp--preset--color--light-gray) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-accent-background-color{background-color: var(--wp--preset--color--accent) !important;}.has-dark-gray-background-color{background-color: var(--wp--preset--color--dark-gray) !important;}.has-medium-gray-background-color{background-color: var(--wp--preset--color--medium-gray) !important;}.has-light-gray-background-color{background-color: var(--wp--preset--color--light-gray) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-accent-border-color{border-color: var(--wp--preset--color--accent) !important;}.has-dark-gray-border-color{border-color: var(--wp--preset--color--dark-gray) !important;}.has-medium-gray-border-color{border-color: var(--wp--preset--color--medium-gray) !important;}.has-light-gray-border-color{border-color: var(--wp--preset--color--light-gray) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}
45.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}.has-regular-font-size{font-size: var(--wp--preset--font-size--regular) !important;}.has-larger-font-size{font-size: var(--wp--preset--font-size--larger) !important;}
46/*# sourceURL=global-styles-inline-css */
47</style>
48
49<link rel='stylesheet' id='tablepress-default-css' href='https://andypi.co.uk/wp-content/plugins/tablepress/css/build/default.css?ver=3.3.3' media='all' />
50<link rel='stylesheet' id='baskerville_googleFonts-css' href='//fonts.googleapis.com/css?family=Roboto+Slab:400,700|Roboto:400,400italic,700,700italic,300|Pacifico:400&#038;ver=1' media='all' />
51<link rel='stylesheet' id='baskerville_style-css' href='https://andypi.co.uk/wp-content/themes/baskerville/style.css?ver=1.0' media='all' />
52<script data-wp-strategy="defer" defer id="stop-user-enumeration-js" src="https://andypi.co.uk/wp-content/plugins/stop-user-enumeration/frontend/js/frontend.js?ver=1.7.7"></script>
vendor: 1 bytes, line 52
52
53<script id="jquery-core-js" src="https://andypi.co.uk/wp-includes/js/jquery/jquery.min.js?ver=3.7.1"></script>
vendor: 1 bytes, line 53
53
54<script id="jquery-migrate-js" src="https://andypi.co.uk/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1"></script>
vendor: 1 bytes, line 54
54
55<script id="baskerville_imagesloaded-js" src="https://andypi.co.uk/wp-content/themes/baskerville/js/imagesloaded.pkgd.js?ver=1"></script>
vendor: 1 bytes, line 55
55
56<script id="baskerville_flexslider-js" src="https://andypi.co.uk/wp-content/themes/baskerville/js/flexslider.min.js?ver=1"></script>
56
57<link rel="https://api.w.org/" href="https://andypi.co.uk/wp-json/" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://andypi.co.uk/xmlrpc.php?rsd" />
58<meta name="generator" content="WordPress 7.0.6" />
59<style id="custom-background-css">
60body.custom-background { background-color: #f1f1f1; }
61</style>
62<link rel="icon" href="https://andypi.co.uk/wp-content/uploads/2023/12/cropped-small-sq-32x32.png" sizes="32x32" />
63<link rel="icon" href="https://andypi.co.uk/wp-content/uploads/2023/12/cropped-small-sq-192x192.png" sizes="192x192" />
64<link rel="apple-touch-icon" href="https://andypi.co.uk/wp-content/uploads/2023/12/cropped-small-sq-180x180.png" />
65<meta name="msapplication-TileImage" content="https://andypi.co.uk/wp-content/uploads/2023/12/cropped-small-sq-270x270.png" />
66<script src="https://cdn.counter.dev/script.js" data-id="4f79969f-7643-492c-80c7-a85e5877c194" data-utcoffset="0"></script>
66	
67
68	</head>
69
70	
71	<body class="home blog custom-background wp-theme-baskerville no-featured-image">
72
73		
74			
75		<div class="header section small-padding bg-dark bg-image" style="background-image: url( https://andypi.co.uk/wp-content/uploads/2018/03/andypi_logo_web_bannerjpg.jpg );">
76		
77			<div class="cover"></div>
78			
79			<div class="header-search-block bg-graphite hidden">
80			
81				<form method="get" class="searchform" action="https://andypi.co.uk/">
82	<input type="search" value="" placeholder="Search Form" name="s" class="s" /> 
83	<input type="submit" class="searchsubmit" value="Search">
84</form>			
85			</div><!-- .header-search-block -->
86					
87			<div class="header-inner section-inner">
88			
89								
90					<div class="blog-logo">
91					
92				        <a class="logo" href='https://andypi.co.uk/' title='AndyPi &mdash; Python &amp; Programming' rel='home'>
93				        	<img src='https://andypi.co.uk/wp-content/uploads/2018/03/transparent.png' alt='AndyPi'>
94				        </a>
95			        
96					</div>
97			
98											
99			</div><!-- .header-inner -->
100						
101		</div><!-- .header -->
102		
103		<div class="navigation section no-padding bg-dark">
104		
105			<div class="navigation-inner section-inner">
106			
107				<div class="nav-toggle fleft hidden">
108					
109					<div class="bar"></div>
110					<div class="bar"></div>
111					<div class="bar"></div>
112					
113					<div class="clear"></div>
114					
115				</div>
116						
117				<ul class="main-menu">
118				
119					<li id="menu-item-18614" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-18614"><a href="https://andypi.co.uk" aria-current="page">Home</a></li>
120<li id="menu-item-17570" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-17570"><a href="https://andypi.co.uk/subscribe/">Subscribe</a></li>
121<li id="menu-item-18210" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children has-children menu-item-18210"><a href="https://andypi.co.uk/category/portfolio/">Pro Portfolio</a>
122<ul class="sub-menu">
123	<li id="menu-item-18834" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-18834"><a href="https://verticalvideoconverter.com/">Vertical Video Converter</a></li>
124	<li id="menu-item-18227" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-18227"><a href="https://github.com/andy-pi">Github Page</a></li>
125	<li id="menu-item-18333" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18333"><a href="https://andypi.co.uk/2013/12/05/magpi-article/">MagPi Article!</a></li>
126	<li id="menu-item-18420" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18420"><a href="https://andypi.co.uk/2021/04/10/countly-wordpress-plugin/">Countly WordPress plugin</a></li>
127	<li id="menu-item-18335" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18335"><a href="https://andypi.co.uk/2020/01/15/cloudflare-stream-video-analytics-wordpress-plugin/">Cloudflare Stream Power Tools WordPress Plugin</a></li>
128	<li id="menu-item-18208" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18208"><a href="https://andypi.co.uk/2017/05/02/countly-two-factor-authentication-plugin/">Countly Two Factor Authentication Plugin</a></li>
129	<li id="menu-item-18207" class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18207"><a href="https://andypi.co.uk/2017/11/01/automating-global-https-deployment-using-flys-api-and-ansible/">Automating Global HTTPS Deployment using Fly’s API and Ansible</a></li>
130</ul>
131</li>
132<li id="menu-item-17476" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-has-children has-children menu-item-17476"><a href="https://andypi.co.uk" aria-current="page">Categories</a>
133<ul class="sub-menu">
134	<li id="menu-item-17477" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17477"><a href="https://andypi.co.uk/category/raspberrypi/">Raspberry Pi</a></li>
135	<li id="menu-item-17554" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17554"><a href="https://andypi.co.uk/category/arduino/">Arduino</a></li>
136	<li id="menu-item-17555" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17555"><a href="https://andypi.co.uk/category/cloud/">Cloud</a></li>
137	<li id="menu-item-17478" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17478"><a href="https://andypi.co.uk/category/displays/">Displays &amp; Lights</a></li>
138	<li id="menu-item-17553" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17553"><a href="https://andypi.co.uk/category/web-apps/">Web Apps</a></li>
139	<li id="menu-item-18755" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18755"><a href="https://andypi.co.uk/category/devops/">DevOps</a></li>
140	<li id="menu-item-17552" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17552"><a href="https://andypi.co.uk/category/python/">Python</a></li>
141	<li id="menu-item-17960" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17960"><a href="https://andypi.co.uk/category/python-beginner-to-pro-in-5steps/">Python: beginner to pro in 5 steps</a></li>
142	<li id="menu-item-17556" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17556"><a href="https://andypi.co.uk/category/php/">PHP</a></li>
143	<li id="menu-item-18756" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18756"><a href="https://andypi.co.uk/category/wordpress/">WordPress</a></li>
144	<li id="menu-item-17585" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17585"><a href="https://andypi.co.uk/category/javascript/">JavaScript</a></li>
145	<li id="menu-item-17962" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17962"><a href="https://andypi.co.uk/category/random/">Random</a></li>
146</ul>
147</li>
148<li id="menu-item-17566" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-17566"><a href="https://andypi.co.uk/about/">About</a></li>
149<li id="menu-item-17474" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-17474"><a href="http://zhongwen.andypi.co.uk">中文</a></li>
150											
151				 </ul><!-- .main-menu -->
152				 
153				 <a class="search-toggle fright" href="#"></a>
154				 
155				 <div class="clear"></div>
156				 
157			</div><!-- .navigation-inner -->
158			
159		</div><!-- .navigation -->
160		
161		<div class="mobile-navigation section bg-graphite no-padding hidden">
162					
163			<ul class="mobile-menu">
164			
165				<li class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-18614"><a href="https://andypi.co.uk" aria-current="page">Home</a></li>
166<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-17570"><a href="https://andypi.co.uk/subscribe/">Subscribe</a></li>
167<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children has-children menu-item-18210"><a href="https://andypi.co.uk/category/portfolio/">Pro Portfolio</a>
168<ul class="sub-menu">
169	<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-18834"><a href="https://verticalvideoconverter.com/">Vertical Video Converter</a></li>
170	<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-18227"><a href="https://github.com/andy-pi">Github Page</a></li>
171	<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18333"><a href="https://andypi.co.uk/2013/12/05/magpi-article/">
171MagPi Article!</a></li>
172	<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18420"><a href="https://andypi.co.uk/2021/04/10/countly-wordpress-plugin/">Countly WordPress plugin</a></li>
173	<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18335"><a href="https://andypi.co.uk/2020/01/15/cloudflare-stream-video-analytics-wordpress-plugin/">Cloudflare Stream Power Tools WordPress Plugin</a></li>
174	<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18208"><a href="https://andypi.co.uk/2017/05/02/countly-two-factor-authentication-plugin/">Countly Two Factor Authentication Plugin</a></li>
175	<li class="menu-item menu-item-type-post_type menu-item-object-post menu-item-18207"><a href="https://andypi.co.uk/2017/11/01/automating-global-https-deployment-using-flys-api-and-ansible/">Automating Global HTTPS Deployment using Fly’s API and Ansible</a></li>
176</ul>
177</li>
178<li class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-has-children has-children menu-item-17476"><a href="https://andypi.co.uk" aria-current="page">Categories</a>
179<ul class="sub-menu">
180	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17477"><a href="https://andypi.co.uk/category/raspberrypi/">Raspberry Pi</a></li>
181	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17554"><a href="https://andypi.co.uk/category/arduino/">Arduino</a></li>
182	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17555"><a href="https://andypi.co.uk/category/cloud/">Cloud</a></li>
183	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17478"><a href="https://andypi.co.uk/category/displays/">Displays &amp; Lights</a></li>
184	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17553"><a href="https://andypi.co.uk/category/web-apps/">Web Apps</a></li>
185	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18755"><a href="https://andypi.co.uk/category/devops/">DevOps</a></li>
186	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17552"><a href="https://andypi.co.uk/category/python/">Python</a></li>
187	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17960"><a href="https://andypi.co.uk/category/python-beginner-to-pro-in-5steps/">Python: beginner to pro in 5 steps</a></li>
188	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17556"><a href="https://andypi.co.uk/category/php/">PHP</a></li>
189	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-18756"><a href="https://andypi.co.uk/category/wordpress/">WordPress</a></li>
190	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17585"><a href="https://andypi.co.uk/category/javascript/">JavaScript</a></li>
191	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-17962"><a href="https://andypi.co.uk/category/random/">Random</a></li>
192</ul>
193</li>
194<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-17566"><a href="https://andypi.co.uk/about/">About</a></li>
195<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-17474"><a href="http://zhongwen.andypi.co.uk">中文</a></li>
196										
197			 </ul><!-- .main-menu -->
198		
199		</div><!-- .mobile-navigation -->
200		
201<div class="wrapper section medium-padding">
202
203	
204	<div class="content section-inner">
205																		                    
206				
207			<div class="posts">
208					
209		    			    	
210		    		<div class="post-container">
211		    	
212						<div id="post-19181" class="post-19181 post type-post status-publish format-standard hentry category-python">
213			    	
214				    		<div class="post-header">
215
216			
217		<h2 class="post-title"><a href="https://andypi.co.uk/2026/08/17/how-to-switch-simple-saleforce-python-package-to-use-oauth-soap-api-login-retiring-june-2027/" rel="bookmark" title="How to switch simple-saleforce python package to use OAuth (SOAP API login retiring June 2027)">How to switch simple-saleforce python package to use OAuth (SOAP API login retiring June 2027)</a></h2>
218
219	    
220        
221</div><!-- .post-header -->
222
223									                                    	    
224<div class="post-excerpt">
225
226	<p>Salesforce OAuth Setup for `simple-salesforce` Salesforce is retiring the SOAP API login o
226peration on June 1, 2027, ending username-password authentication for all SOAP, REST, and Bulk API integrations. This post explains how to switch from using SOAP username / password&#8230; <a class="more-link" href="https://andypi.co.uk/2026/08/17/how-to-switch-simple-saleforce-python-package-to-use-oauth-soap-api-login-retiring-june-2027/">Continue Reading &rarr;</a></p>
227
228</div><!-- .post-excerpt -->
229
230
231		<div class="post-meta">
232		
233			<a class="post-date" href="https://andypi.co.uk/2026/08/17/how-to-switch-simple-saleforce-python-package-to-use-oauth-soap-api-login-retiring-june-2027/" title="How to switch simple-saleforce python package to use OAuth (SOAP API login retiring June 2027)">2026/08/17</a>
234			
235						
236			<div class="clear"></div>
237		
238		</div><!-- .post-meta -->
239		
240	            
241<div class="clear"></div>				    				    		
242			    		</div><!-- .post -->
243		    		
244		    		</div>
245		    			        		            
246		        		    	
247		    		<div class="post-container">
248		    	
249						<div id="post-18814" class="post-18814 post type-post status-publish format-standard has-post-thumbnail hentry category-devops category-django-deployment category-python">
250			    	
251				    		<div class="post-header">
252
253			
254		<h2 class="post-title"><a href="https://andypi.co.uk/2026/05/02/deployment-of-a-django-app-on-caddy-server-using-ansible-docker/" rel="bookmark" title="Deployment of a Django app on Caddy server using Ansible &#038; Docker">Deployment of a Django app on Caddy server using Ansible &#038; Docker</a></h2>
255
256	    
257        
258</div><!-- .post-header -->
259
260
261	<div class="featured-media">
262	
263		<a href="https://andypi.co.uk/2026/05/02/deployment-of-a-django-app-on-caddy-server-using-ansible-docker/" rel="bookmark" title="Deployment of a Django app on Caddy server using Ansible &#038; Docker">
264		
265			<img width="600" height="342" src="https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-600x342.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" fetchpriority="high" srcset="https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-600x342.jpg 600w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-300x171.jpg 300w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-1024x583.jpg 1024w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-768x437.jpg 768w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-1536x874.jpg 1536w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663-945x538.jpg 945w, https://andypi.co.uk/wp-content/uploads/2024/08/c9ba8d8c-0d23-46f8-8be8-c578c987b663.jpg 1662w" sizes="(max-width: 600px) 100vw, 600px" />			
266		</a>
267				
268	</div><!-- .featured-media -->
269		
270									                                    	    
271<div class="post-excerpt">
272
273	<p>A tutorial showing how to reliably and repeatably deploy a Django app in production using Docker and Ansible. Caddy server instead of Nginx and Gunicorn instead of uWSGI which require less configuration &#8211; see the conclusion for why I made these changes.</p>
274
275</div><!-- .post-excerpt -->
276
277
278		<div class="post-meta">
279		
280			<a class="post-date" href="https://andypi.co.uk/2026/05/02/deployment-of-a-django-app-on-caddy-server-using-ansible-docker/" title="Deployment of a Django app on Caddy server using Ansible &#038; Docker">2026/05/02</a>
281			
282			<a href="https://andypi.co.uk/2026/05/02/deployment-of-a-django-app-on-caddy-server-using-ansible-docker/#respond" class="post-comments" >0</a>			
283			<div class="clear"></div>
284		
285		</div><!-- .post-meta -->
286		
287	            
288<div class="clear"></div>				    				    		
289			    		</div><!-- .post -->
290		    		
291		    		</div>
292		    			        		            
293		        		    	
294		    		<div class="post-container">
295		    	
296						<div id="post-19118" class="post-19118 post type-post status-publish format-standard has-post-thumbnail hentry category-ai category-random">
297			    	
298				    		<div class="post-header">
299
300			
301		<h2 class="post-title"><a href="https://andypi.co.uk/2026/03/13/amiga-500-rgb2hdmi-mod-plus-debugging-dead-motherboard-with-chatgpt/" rel="bookmark" title="Amiga 500 RGB2HDMI mod plus debugging dead motherboard with ChatGPT">Amiga 500 RGB2HDMI mod plus debugging dead motherboard with ChatGPT<
301/a></h2>
302
303	    
304        
305</div><!-- .post-header -->
306
307
308	<div class="featured-media">
309	
310		<a href="https://andypi.co.uk/2026/03/13/amiga-500-rgb2hdmi-mod-plus-debugging-dead-motherboard-with-chatgpt/" rel="bookmark" title="Amiga 500 RGB2HDMI mod plus debugging dead motherboard with ChatGPT">
311		
312			<img width="600" height="338" src="https://andypi.co.uk/wp-content/uploads/2026/03/breakout-600x338.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="breakout" decoding="async" srcset="https://andypi.co.uk/wp-content/uploads/2026/03/breakout-600x338.jpg 600w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-300x169.jpg 300w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-1024x576.jpg 1024w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-768x432.jpg 768w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-1536x864.jpg 1536w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-2048x1152.jpg 2048w, https://andypi.co.uk/wp-content/uploads/2026/03/breakout-945x532.jpg 945w" sizes="(max-width: 600px) 100vw, 600px" />			
313		</a>
314				
315	</div><!-- .featured-media -->
316		
317									                                    	    
318<div class="post-excerpt">
319
320	<p>My Mrs has an Amiga 500 that she is desperate to play and reclaim her childhood, but the CRT monitor broke. We don&#8217;t have room for a CRT so I decided to mod it to output the AV to HDMI&#8230; <a class="more-link" href="https://andypi.co.uk/2026/03/13/amiga-500-rgb2hdmi-mod-plus-debugging-dead-motherboard-with-chatgpt/">Continue Reading &rarr;</a></p>
321
322</div><!-- .post-excerpt -->
323
324
325		<div class="post-meta">
326		
327			<a class="post-date" href="https://andypi.co.uk/2026/03/13/amiga-500-rgb2hdmi-mod-plus-debugging-dead-motherboard-with-chatgpt/" title="Amiga 500 RGB2HDMI mod plus debugging dead motherboard with ChatGPT">2026/03/13</a>
328			
329			<a href="https://andypi.co.uk/2026/03/13/amiga-500-rgb2hdmi-mod-plus-debugging-dead-motherboard-with-chatgpt/#respond" class="post-comments" >0</a>			
330			<div class="clear"></div>
331		
332		</div><!-- .post-meta -->
333		
334	            
335<div class="clear"></div>				    				    		
336			    		</div><!-- .post -->
337		    		
338		    		</div>
339		    			        		            
340		        		    	
341		    		<div class="post-container">
342		    	
343						<div id="post-19101" class="post-19101 post type-post status-publish format-standard has-post-thumbnail hentry category-ruby">
344			    	
345				    		<div class="post-header">
346
347			
348		<h2 class="post-title"><a href="https://andypi.co.uk/2026/01/12/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-3-basic-rails-app/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (3 – Basic Rails App)">How I started learning Ruby on Rails from scratch as a Python dev (3 – Basic Rails App)</a></h2>
349
350	    
351        
352</div><!-- .post-header -->
353
354
355	<div class="featured-media">
356	
357		<a href="https://andypi.co.uk/2026/01/12/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-3-basic-rails-app/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (3 – Basic Rails App)">
358		
359			<img width="600" height="325" src="https://andypi.co.uk/wp-content/uploads/2026/01/rails-600x325.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" srcset="https://andypi.co.uk/wp-content/uploads/2026/01/rails-600x325.png 600w, https://andypi.co.uk/wp-content/uploads/2026/01/rails-300x162.png 300w, https://andypi.co.uk/wp-content/uploads/2026/01/rails-768x415.png 768w, https://andypi.co.uk/wp-content/uploads/2026/01/rails.png 808w" sizes="(max-width: 600px) 100vw, 600px" />			
360		</a>
361				
362	</div><!-- .featured-media -->
363		
364									                                    	    
365<div class="post-excerpt">
366
367	<p>There&#8217;s a couple of very helpful guides to creating a basic Ruby on Rails app: There&#8217;s a text based tutorial: https://guides.rubyonrails.org/getting_started.html#introduction I followed this video tutorial (quite fast so needed to pause at some points as I was coding alongside&#8230; <a class="more-link" href="https://andypi.co.uk/2026/01/12/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-3-basic-rails-app/">Continue Reading &rarr;</a></p>
368
369</div><!-- .post-excerpt -->
370
371
372		<div class="post-meta">
373		
374			<a class="post-date" href="https://andypi.co.uk/2026/01/12/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-3-basic-rails-app/" title="How I started learning Ruby on Rails from scratch as a Python dev (3 – Basic Rails App)">2026/01/12</a>
375			
376			<a href="https://andypi.co.uk/2026/01/12/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-3-basic-rails-app/#respond" class="post-comments" >0</a>			
377			<div class="clear"></div>
378		
379		</div><!-- .post-meta -->
380		
381	            
382<div class="clear"></div>				    				    		
383			    		</div><!-- .post -->
384		    		
385		    		</div>
386		    			        		            
387		        		    	
388		    		<div class="post-container">
389		    	
390						<div id="post-19091" class="post-19091 post type-post status-publish format-standard has-post-thumbnail hentry category-ruby">
391			    	
392				    		<div class="post-header">
393
394			
395		<h2 class="post-title"><a href="https://andypi.co.uk/2025/12/24/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-2-syntax/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (2 &#8211; Syntax)">How I started learning Ruby on Rails from scratch as a Python dev (2 &#8211; Syntax)</a></h2>
396
397	    
398        
399</div><!-- .post-header -->
400
401
402	<div class="featured-media">
403	
404		<a href="https://andypi.co.uk/2025/12/24/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-2-syntax/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (2 &#8211; Syntax)">
405		
406			<img width="600" height="300" src="https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-600x300.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-600x300.png 600w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-300x150.png 300w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-768x384.png 768w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-945x473.png 945w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1.png 1024w" sizes="auto, (max-width: 600px) 100v
406w, 600px" />			
407		</a>
408				
409	</div><!-- .featured-media -->
410		
411									                                    	    
412<div class="post-excerpt">
413
414	<p>In order to get a familiar with Ruby syntax before diving into a real project, I did a couple of things to practice. The first was to use the Try Ruby online playground &#8211; this took me a bit more&#8230; <a class="more-link" href="https://andypi.co.uk/2025/12/24/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-2-syntax/">Continue Reading &rarr;</a></p>
415
416</div><!-- .post-excerpt -->
417
418
419		<div class="post-meta">
420		
421			<a class="post-date" href="https://andypi.co.uk/2025/12/24/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-2-syntax/" title="How I started learning Ruby on Rails from scratch as a Python dev (2 &#8211; Syntax)">2025/12/24</a>
422			
423			<a href="https://andypi.co.uk/2025/12/24/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-2-syntax/#respond" class="post-comments" >0</a>			
424			<div class="clear"></div>
425		
426		</div><!-- .post-meta -->
427		
428	            
429<div class="clear"></div>				    				    		
430			    		</div><!-- .post -->
431		    		
432		    		</div>
433		    			        		            
434		        		    	
435		    		<div class="post-container">
436		    	
437						<div id="post-19083" class="post-19083 post type-post status-publish format-standard has-post-thumbnail hentry category-ruby">
438			    	
439				    		<div class="post-header">
440
441			
442		<h2 class="post-title"><a href="https://andypi.co.uk/2025/12/13/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-1-project-setup/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (1 &#8211; Project Setup)">How I started learning Ruby on Rails from scratch as a Python dev (1 &#8211; Project Setup)</a></h2>
443
444	    
445        
446</div><!-- .post-header -->
447
448
449	<div class="featured-media">
450	
451		<a href="https://andypi.co.uk/2025/12/13/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-1-project-setup/" rel="bookmark" title="How I started learning Ruby on Rails from scratch as a Python dev (1 &#8211; Project Setup)">
452		
453			<img width="600" height="300" src="https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-600x300.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-600x300.png 600w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-300x150.png 300w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-768x384.png 768w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1-945x473.png 945w, https://andypi.co.uk/wp-content/uploads/2025/12/ruby-lang-ar21-1024x512-1.png 1024w" sizes="auto, (max-width: 600px) 100vw, 600px" />			
454		</a>
455				
456	</div><!-- .featured-media -->
457		
458									                                    	    
459<div class="post-excerpt">
460
461	<p>I&#8217;ve got the opportunity to do some work on a Ruby on Rails web app coming up soon. I&#8217;m documenting my journey here of getting up to speed with Ruby coming from Python on MacOS. This post is going to&#8230; <a class="more-link" href="https://andypi.co.uk/2025/12/13/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-1-project-setup/">Continue Reading &rarr;</a></p>
462
463</div><!-- .post-excerpt -->
464
465
466		<div class="post-meta">
467		
468			<a class="post-date" href="https://andypi.co.uk/2025/12/13/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-1-project-setup/" title="How I started learning Ruby on Rails from scratch as a Python dev (1 &#8211; Project Setup)">2025/12/13</a>
469			
470			<a href="https://andypi.co.uk/2025/12/13/how-i-started-learning-ruby-on-rails-from-scratch-as-a-python-dev-1-project-setup/#respond" class="post-comments" >0</a>			
471			<div class="clear"></div>
472		
473		</div><!-- .post-meta -->
474		
475	            
476<div class="clear"></div>				    				    		
477			    		</div><!-- .post -->
478		    		
479		    		</div>
480		    			        		            
481		        		    	
482		    		<div class="post-container">
483		    	
484						<div id="post-19067" class="post-19067 post type-post status-publish format-standard has-post-thumbnail hentry category-python">
485			    	
486				    		<div class="post-header">
487
488			
489		<h2 class="post-title"><a href="https://andypi.co.uk/2025/08/17/how-to-create-a-private-python-package-on-github/" rel="bookmark" title="How to create a private python package on Github">
489How to create a private python package on Github</a></h2>
490
491	    
492        
493</div><!-- .post-header -->
494
495
496	<div class="featured-media">
497	
498		<a href="https://andypi.co.uk/2025/08/17/how-to-create-a-private-python-package-on-github/" rel="bookmark" title="How to create a private python package on Github">
499		
500			<img width="500" height="500" src="https://andypi.co.uk/wp-content/uploads/2025/08/packages.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/08/packages.jpg 500w, https://andypi.co.uk/wp-content/uploads/2025/08/packages-300x300.jpg 300w, https://andypi.co.uk/wp-content/uploads/2025/08/packages-150x150.jpg 150w" sizes="auto, (max-width: 500px) 100vw, 500px" />			
501		</a>
502				
503	</div><!-- .featured-media -->
504		
505									                                    	    
506<div class="post-excerpt">
507
508	<p>Sometimes the need arises to share code across different python projects. This can be achieved by extracting that code into a separate project and making it into a python package. This can be uploaded to the PyPi python package repository,&#8230; <a class="more-link" href="https://andypi.co.uk/2025/08/17/how-to-create-a-private-python-package-on-github/">Continue Reading &rarr;</a></p>
509
510</div><!-- .post-excerpt -->
511
512
513		<div class="post-meta">
514		
515			<a class="post-date" href="https://andypi.co.uk/2025/08/17/how-to-create-a-private-python-package-on-github/" title="How to create a private python package on Github">2025/08/17</a>
516			
517			<a href="https://andypi.co.uk/2025/08/17/how-to-create-a-private-python-package-on-github/#respond" class="post-comments" >0</a>			
518			<div class="clear"></div>
519		
520		</div><!-- .post-meta -->
521		
522	            
523<div class="clear"></div>				    				    		
524			    		</div><!-- .post -->
525		    		
526		    		</div>
527		    			        		            
528		        		    	
529		    		<div class="post-container">
530		    	
531						<div id="post-18947" class="post-18947 post type-post status-publish format-image has-post-thumbnail hentry category-cryptocurreny post_format-post-format-image">
532			    	
533				    		
534
535	<div class="featured-media">
536	
537			
538		<a href="https://andypi.co.uk/2025/07/07/full-guide-to-creating-your-own-cryptocurrency-token-on-the-solana-blockchain/" rel="bookmark" title="Full guide to creating your own cryptocurrency token on the Solana blockchain">
539		
540			<img width="600" height="199" src="https://andypi.co.uk/wp-content/uploads/2025/07/11-duplicate-600x199.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/07/11-duplicate-600x199.png 600w, https://andypi.co.uk/wp-content/uploads/2025/07/11-duplicate-300x100.png 300w, https://andypi.co.uk/wp-content/uploads/2025/07/11-duplicate.png 666w" sizes="auto, (max-width: 600px) 100vw, 600px" />			
541		</a>
542				
543	</div><!-- .featured-media -->
544		
545
546<div class="post-excerpt">
547
548	<p>The AndyPi (Meme) Coin! Full guide to creating your own cryptocurrency token on the Solana blockchain This guide is based on the excellent video by Network Chuck (https://youtu.be/L4ASwqLZVV0?t=397). I&#8217;ve documented actually minting a real token with real money, and clarified&#8230; <a class="more-link" href="https://andypi.co.uk/2025/07/07/full-guide-to-creating-your-own-cryptocurrency-token-on-the-solana-blockchain/">Continue Reading &rarr;</a></p>
549		
550</div><!-- .post-excerpt -->
551									                                    	    
552
553		<div class="post-meta">
554		
555			<a class="post-date" href="https://andypi.co.uk/2025/07/07/full-guide-to-creating-your-own-cryptocurrency-token-on-the-solana-blockchain/" title="Full guide to creating your own cryptocurrency token on the Solana blockchain">2025/07/07</a>
556			
557						
558			<div class="clear"></div>
559		
560		</div><!-- .post-meta -->
561		
562	            
563<div class="clear"></div>				    				    		
564			    		</div><!-- .post -->
565		    		
566		    		</div>
567		    			        		            
568		        		    	
569		    		<div class="post-container">
570		    	
571						<div id="post-18930" class="post-18930 post type-post status-publish format-standard has-post-thumbnail hentry category-devops category-python category-web-apps">
572			    	
573				    		<div class="post-header">
574
575			
576		<h2 class="post-title"><a href="https://andypi.co.uk/2025/06/27/why-i-switched-to-using-caddy-uvicorn-for-python-web-projects-instead-of-nginx-uwsgi/" rel="bookmark" title="Why I switched to using Caddy + Uvicorn for python web projects instead of Nginx + uWSGI">Why I switched to using Caddy + Uvicorn for python web projects instead of Nginx + uWSGI</a></h2>
577
578	    
579        
580</div><!-- .post-header -->
581
582
583	<div class="featured-media">
584	
585		<a href="https://andypi.co.uk/2025/06/27/why-i-switched-to-using-caddy-uvicorn-for-python-web-projects-instead-of-nginx-uwsgi/" rel="bookmark" title="Why I switched to using Caddy + Uvicorn for python web projects instead of Nginx + uWSGI">
586		
587			<img width="600" height="193" src="https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-600x193.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-600x193.jpg 600w, https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-300x97.jpg 300w, https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-1024x329.jpg 1024w, https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-768x247.jpg 768w, https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354-945x304.jpg 945w, https://andypi.co.uk/wp-content/uploads/2025/06/caddy-e1751053507354.jpg 1200w" sizes="auto, (max-width: 600px) 100v
587w, 600px" />			
588		</a>
589				
590	</div><!-- .featured-media -->
591		
592									                                    	    
593<div class="post-excerpt">
594
595	<p>For each python app I build, the server deployment always seems to be the most difficult part! As well as Python we need some kind of python server (uWSGI) and a web server AND getting the SSL certs&#8230;. I guess&#8230; <a class="more-link" href="https://andypi.co.uk/2025/06/27/why-i-switched-to-using-caddy-uvicorn-for-python-web-projects-instead-of-nginx-uwsgi/">Continue Reading &rarr;</a></p>
596
597</div><!-- .post-excerpt -->
598
599
600		<div class="post-meta">
601		
602			<a class="post-date" href="https://andypi.co.uk/2025/06/27/why-i-switched-to-using-caddy-uvicorn-for-python-web-projects-instead-of-nginx-uwsgi/" title="Why I switched to using Caddy + Uvicorn for python web projects instead of Nginx + uWSGI">2025/06/27</a>
603			
604			<a href="https://andypi.co.uk/2025/06/27/why-i-switched-to-using-caddy-uvicorn-for-python-web-projects-instead-of-nginx-uwsgi/#respond" class="post-comments" >0</a>			
605			<div class="clear"></div>
606		
607		</div><!-- .post-meta -->
608		
609	            
610<div class="clear"></div>				    				    		
611			    		</div><!-- .post -->
612		    		
613		    		</div>
614		    			        		            
615		        		    	
616		    		<div class="post-container">
617		    	
618						<div id="post-18903" class="post-18903 post type-post status-publish format-standard has-post-thumbnail hentry category-random">
619			    	
620				    		<div class="post-header">
621
622			
623		<h2 class="post-title"><a href="https://andypi.co.uk/2025/03/21/automating-a-daily-email-using-google-sheets-and-apps-script/" rel="bookmark" title="Automating a daily email using Google Sheets and Apps Script">Automating a daily email using Google Sheets and Apps Script</a></h2>
624
625	    
626        
627</div><!-- .post-header -->
628
629
630	<div class="featured-media">
631	
632		<a href="https://andypi.co.uk/2025/03/21/automating-a-daily-email-using-google-sheets-and-apps-script/" rel="bookmark" title="Automating a daily email using Google Sheets and Apps Script">
633		
634			<img width="600" height="338" src="https://andypi.co.uk/wp-content/uploads/2025/03/google_apps_script-600x338.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://andypi.co.uk/wp-content/uploads/2025/03/google_apps_script-600x338.jpg 600w, https://andypi.co.uk/wp-content/uploads/2025/03/google_apps_script-300x169.jpg 300w, https://andypi.co.uk/wp-content/uploads/2025/03/google_apps_script.jpg 760w" sizes="auto, (max-width: 600px) 100vw, 600px" />			
635		</a>
636				
637	</div><!-- .featured-media -->
638		
639									                                    	    
640<div class="post-excerpt">
641
642	<p>1. Automate the boring stuff&#8230; A client needed to send short email every day with pre-prepared content to a list of people in google contacts who have a specific label. At the moment, they are doing this by creating and&#8230; <a class="more-link" href="https://andypi.co.uk/2025/03/21/automating-a-daily-email-using-google-sheets-and-apps-script/">Continue Reading &rarr;</a></p>
643
644</div><!-- .post-excerpt -->
645
646
647		<div class="post-meta">
648		
649			<a class="post-date" href="https://andypi.co.uk/2025/03/21/automating-a-daily-email-using-google-sheets-and-apps-script/" title="Automating a daily email using Google Sheets and Apps Script">2025/03/21</a>
650			
651			<a href="https://andypi.co.uk/2025/03/21/automating-a-daily-email-using-google-sheets-and-apps-script/#respond" class="post-comments" >0</a>			
652			<div class="clear"></div>
653		
654		</div><!-- .post-meta -->
655		
656	            
657<div class="clear"></div>				    				    		
658			    		</div><!-- .post -->
659		    		
660		    		</div>
661		    			        		            
662		        	        	                    
663						
664		</div><!-- .posts -->
665			
666	</div><!-- .content -->
667	
668			
669		<div class="archive-nav section-inner">
670					
671			<a href="https://andypi.co.uk/page/2/" class="post-nav-older fleft">&laquo; Older posts</a>						
672						
673			<div class="clear"></div>
674			
675		</div><!-- .post-nav archive-nav -->
676	
677				
678	<div class="clear"></div>
679
680</div><!-- .wrapper -->
681	              	        
682<div class="footer section medium-padding bg-graphite">
683
684		
685		<div class="section-inner row">
686		
687						
688				<div class="column column-1 one-third">
689				
690					<div class="widgets">
691			
692						<div class="widget widget_categories"><div class="widget-content"><h3 class="widget-title">Categories</h3>
693			<ul>
694					<li class="cat-item cat-item-28"><a href="https://andypi.co.uk/category/3d-printing/">3D Printing</a>
695</li>
696	<li class="cat-item cat-item-44"><a href="https://andypi.co.uk/category/ai/">AI</a>
697</li>
698	<li class="cat-item cat-item-41"><a href="https://andypi.co.uk/category/analytics/">Analytics</a>
699</li>
700	<li class="cat-item cat-item-2"><a href="https://andypi.co.uk/category/arduino/">Arduino</a>
701</li>
702	<li class="cat-item cat-item-3"><a href="https://andypi.co.uk/category/cloud/">Cloud</a>
703</li>
704	<li class="cat-item cat-item-29"><a href="https://andypi.co.uk/category/cryptocurreny/">Cryptocurrency</a>
705</li>
706	<li class="cat-item cat-item-45"><a href="https://andypi.co.uk/category/devops/">DevOps</a>
707</li>
708	<li class="cat-item cat-item-4"><a href="https://andypi.co.uk/category/displays/">Displays &amp; Lights</a>
709</li>
710	<li class="cat-item cat-item-47"><a href="https://andypi.co.uk/category/django-deployment/">Django Deployment</a>
711</li>
712	<li class="cat-item cat-item-49"><a href="https://andypi.co.uk/category/golang/">Golang</a>
713</li>
714	<li class="cat-item cat-item-5"><a href="https://andypi.co.uk/category/javascript/">JavaScript</a>
715</li>
716	<li class="cat-item cat-item-48"><a href="https://andypi.co.uk/category/networking/">Networking</a>
717</li>
718	<li class="cat-item cat-item-6"><a href="https://andypi.co.uk/category/php/">PHP</a>
719</li>
720	<li class="cat-item cat-item-32"><a href="https://andypi.co.uk/category/portfolio/">Portfolio</a>
721</li>
722	<li class="cat-item cat-item-8"><a href="https://andypi.co.uk/category/python/">Python</a>
723</li>
724	<li class="cat-item cat-item-31"><a href="https://andypi.co.uk/category/python-for-mechanical-engineers/">Python for Mechanical Engineers</a>
725</li>
726	<li class="cat-item cat-item-30"><a href="https://andypi.co.uk/category/python-beginner-to-pro-in-5steps/">Python: beginner to pro in 5 steps</a>
727</li>
728	<li class="cat-item cat-item-27"><a href="https://andypi.co.uk/category/random/">Random</a>
729</li>
730	<li class="cat-item cat-item-9"><a href="https://andypi.co.uk/category/raspberrypi/">Raspberry Pi</a>
731</li>
732	<li class="cat-item cat-item-52"><a href="https://andypi.co.uk/category/ruby/">Ruby</a>
733</li>
734	<li class="cat-item cat-item-42"><a href="https://andypi.co.uk/category/sysadmin/">SysAdmin</a>
735</li>
736	<li class="cat-item cat-item-1"><a href="https://andypi.co.uk/category/uncategorised/">Uncategorised</a>
737</li>
738	<li class="cat-item cat-item-43"><a href="https://andypi.co.uk/category/web/">Web</a>
739</li>
740	<li class="cat-item cat-item-10"><a href="https://andypi.co.uk/category/web-apps/">Web Apps</a>
741</li>
742	<li class="cat-item cat-item-46"><a href="https://andypi.co.uk/category/wordpress/">WordPress</a>
743</li>
744			</ul>
745
746			</div><div class="clear"></div></div>											
747					</div>
748					
749				</div><!-- .column-1 -->
750				
751							
752						
753				<div class="column column-2 one-third">
754				
755					<div class="widgets">
756			
757						<div class="widget widget_text"><div class="widget-content"><h3 class="widget-title">Follow AndyPi</h3>			<div class="textwidget"><iframe src="https://ghbtns.com/github-btn.html?user=andy-pi&type=follow&count=true&size=large" frameborder="0" scrolling="0" width="220px" height="30px"></iframe>
758<br><br>
759
760<a href="https://twitter.com/Andypitech"><img src="https://andypi.co.uk/wp-content/uploads/2017/04/followandypitechbuttonblack.png" height="20" width="120"></a></div>
761		</div><div class="clear"></div></div>											
762					</div><!-- .widgets -->
763					
764				</div><!-- .column-2 -->
765				
766											
767						
768				<div class="column column-3 one-third">
769			
770					<div class="widgets">
771			
772						<div class="widget widget_text"><div class="widget-content"><h3 class="widget-title">Privacy Policy</h3>			<div class="textwidget"><p>
772This site uses cookies and by using the site you are consenting to this. Find out why we use cookies and how to opt out by reading our <a href="https://andypi.co.uk/privacy-policy/">Privacy Policy</a>.</p>
773</div>
774		</div><div class="clear"></div></div>											
775					</div><!-- .widgets -->
776					
777				</div>
778				
779			<!-- .footer-c -->
780			
781			<div class="clear"></div>
782		
783		</div><!-- .section-inner -->
784
785	
786</div><!-- .footer -->
787
788<div class="credits section bg-dark small-padding">
789
790	<div class="credits-inner section-inner">
791
792		<p class="credits-left fleft">
793		
794			&copy; 2026 <a href="https://andypi.co.uk" title="AndyPi">AndyPi</a><span> &mdash; Powered by <a href="http://www.wordpress.org">WordPress</a></span>
795		
796		</p>
797		
798		<p class="credits-right fright">
799			
800			<span>Theme by <a href="https://www.andersnoren.se">Anders Noren</a> &mdash; </span><a class="tothetop" title="To the top" href="#">Up &uarr;</a>
801			
802		</p>
803		
804		<div class="clear"></div>
805	
806	</div><!-- .credits-inner -->
807	
808</div><!-- .credits -->
809
810<script type="speculationrules">
811{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/baskerville/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
812</script>
vendor: 1 bytes, line 812
812
813<script id="imagesloaded-js" src="https://andypi.co.uk/wp-includes/js/imagesloaded.min.js?ver=5.0.0"></script>
vendor: 1 bytes, line 813
813
814<script id="masonry-js" src="https://andypi.co.uk/wp-includes/js/masonry.min.js?ver=4.2.2"></script>
vendor: 1 bytes, line 814
814
815<script id="baskerville_global-js" src="https://andypi.co.uk/wp-content/themes/baskerville/js/global.js?ver=7.0.6"></script>
vendor: 1 bytes, line 815
815
816<script id="wp-emoji-settings" type="application/json">
817{"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://andypi.co.uk/wp-includes/js/wp-emoji-release.min.js?ver=7.0.6"}}
818</script>
vendor: 1 bytes, line 818
818
819<script type="module">
820/*! This file is auto-generated */
821var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,r){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!r(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,r){let a;const s=(a="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),o=(s.textBaseline="top",s.font="600 32px Arial",{});return e.forEach(e=>{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(o),u.toString(),c.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"});const a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=e=>{i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))});
822//# sourceURL=https://andypi.co.uk/wp-includes/js/wp-emoji-loader.min.js
823</script>
823
824
825<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a403c3875acfe080',t:'MTc5MDI3MzYxMw=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
825<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"1c051d73aabb4e0c8fcbd130a989cbfc","r":1,"spa":2}' crossorigin="anonymous"></script>
825
826</body>
827</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.