<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tino Joel Muchenje</title>
    <description>The latest articles on DEV Community by Tino Joel Muchenje (@tino_muc).</description>
    <link>https://dev.to/tino_muc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F393666%2Fc84a3ef8-7b29-4b57-a1dc-1dfe4f1d836c.jpg</url>
      <title>DEV Community: Tino Joel Muchenje</title>
      <link>https://dev.to/tino_muc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tino_muc"/>
    <language>en</language>
    <item>
      <title>OpenAI Drops o3 Pricing by 80% — and Launches o3-pro for Tougher Problems</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Wed, 11 Jun 2025 07:57:52 +0000</pubDate>
      <link>https://dev.to/tino_muc/openai-drops-o3-pricing-by-80-and-launches-o3-pro-for-tougher-problems-1a5l</link>
      <guid>https://dev.to/tino_muc/openai-drops-o3-pricing-by-80-and-launches-o3-pro-for-tougher-problems-1a5l</guid>
      <description>&lt;p&gt;Just got an email from OpenAI, and it's a big one for developers, especially those building AI apps at scale.&lt;/p&gt;

&lt;p&gt;💸 o3 Is Now 80% Cheaper!&lt;br&gt;
OpenAI has dropped the price of the o3 model to:&lt;/p&gt;

&lt;p&gt;$2 / 1M input tokens&lt;/p&gt;

&lt;p&gt;$8 / 1M output tokens&lt;/p&gt;

&lt;p&gt;This isn’t a stripped-down version — it’s the same o3 model, just cheaper thanks to inference stack optimizations.&lt;/p&gt;

&lt;p&gt;👨‍💻 Why You Should Try o3 Now&lt;br&gt;
OpenAI recommends using o3 for:&lt;/p&gt;

&lt;p&gt;Coding tasks (same price per token as GPT-4.1, cheaper than GPT-4o)&lt;/p&gt;

&lt;p&gt;Agentic tool calling&lt;/p&gt;

&lt;p&gt;Function calling&lt;/p&gt;

&lt;p&gt;Instruction following&lt;/p&gt;

&lt;p&gt;If you're building apps with tool use, structured tasks, or agents — o3 is now way more cost-effective.&lt;/p&gt;

&lt;p&gt;🔍 Introducing: o3-pro&lt;br&gt;
For devs dealing with more complex reasoning or production use cases, OpenAI just launched o3-pro — a version of o3 that uses more compute to give deeper, more reliable responses.&lt;/p&gt;

&lt;p&gt;o3-pro Pricing:&lt;br&gt;
$20 / 1M input tokens&lt;/p&gt;

&lt;p&gt;$80 / 1M output tokens&lt;br&gt;
💰 That’s 87% cheaper than the old o1-pro model.&lt;/p&gt;

&lt;p&gt;Supported Features:&lt;br&gt;
Image inputs&lt;/p&gt;

&lt;p&gt;Function calling&lt;/p&gt;

&lt;p&gt;Structured Outputs&lt;/p&gt;

&lt;p&gt;Background mode for long-running requests&lt;/p&gt;

&lt;p&gt;🧠 o3-pro is better suited for difficult problems that need extra computation time and accuracy.&lt;/p&gt;

&lt;p&gt;📌 TL;DR for Devs&lt;br&gt;
Use o3 for general-purpose and coding tasks → super cheap now.&lt;/p&gt;

&lt;p&gt;Use o3-pro when you need reliability, depth, and complex logic.&lt;/p&gt;

&lt;p&gt;Test o3-pro-2025-06-10 in the Responses API or Playground.&lt;/p&gt;

&lt;p&gt;Long requests? Try the new background mode to avoid timeouts.&lt;/p&gt;

&lt;p&gt;🧪 These pricing changes make it way more feasible to build powerful AI experiences without blowing your budget.&lt;/p&gt;

&lt;p&gt;Let the tinkering begin. 🚀&lt;/p&gt;

&lt;p&gt;Have you tried the new o3 or o3-pro yet? Share your results or thoughts below!&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenAI #LLM #API #DevTools #AI #GPT #MachineLearning #Coding #FunctionCalling #DeveloperExperience
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Have more visibility in your APIs!</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Tue, 13 May 2025 06:24:40 +0000</pubDate>
      <link>https://dev.to/tino_muc/have-more-visibility-in-your-apis-30e0</link>
      <guid>https://dev.to/tino_muc/have-more-visibility-in-your-apis-30e0</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6" class="crayons-story__hidden-navigation-link"&gt;Building a Comprehensive Observability Stack for a .NET API with Core Banking Integration&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/tino_muc" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F393666%2Fc84a3ef8-7b29-4b57-a1dc-1dfe4f1d836c.jpg" alt="tino_muc profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/tino_muc" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Tino Joel Muchenje
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Tino Joel Muchenje
                
              
              &lt;div id="story-author-preview-content-2463365" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/tino_muc" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F393666%2Fc84a3ef8-7b29-4b57-a1dc-1dfe4f1d836c.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Tino Joel Muchenje&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 8 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6" id="article-link-2463365"&gt;
          Building a Comprehensive Observability Stack for a .NET API with Core Banking Integration
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backenddevelopment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backenddevelopment&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/banking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;banking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/api"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;api&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>programming</category>
      <category>backenddevelopment</category>
      <category>banking</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Comprehensive Observability Stack for a .NET API with Core Banking Integration</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Thu, 08 May 2025 19:36:39 +0000</pubDate>
      <link>https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6</link>
      <guid>https://dev.to/tino_muc/building-a-comprehensive-observability-stack-for-a-net-api-with-core-banking-integration-mp6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, I'll walk you through how I implemented a complete observability solution for a .NET 8 minimal API that integrates with a core banking system. I'll cover the architecture decisions, implementation process, challenges faced, and the final result that provides comprehensive monitoring capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;My .NET API needed to reliably interface with a core banking system through SOAP services while providing comprehensive monitoring capabilities. The initial codebase had limited observability features, making it difficult to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track performance issues&lt;/li&gt;
&lt;li&gt;Monitor service health&lt;/li&gt;
&lt;li&gt;Trace requests across system boundaries&lt;/li&gt;
&lt;li&gt;Identify and diagnose errors quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution Architecture
&lt;/h2&gt;

&lt;p&gt;I implemented a complete observability stack consisting of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Structured Logging&lt;/strong&gt; with Serilog&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Tracing&lt;/strong&gt; with OpenTelemetry and Jaeger&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics Collection&lt;/strong&gt; with Prometheus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visualization&lt;/strong&gt; with Grafana&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health Checks&lt;/strong&gt; for the API and its dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────┐     ┌───────────────┐     ┌─────────────┐
│ .NET API          │────►│ Prometheus    │────►│ Grafana     │
│ - Metrics endpoint│     │ (Metrics DB)  │     │ (Dashboards)│
│ - Health checks   │     └───────────────┘     └─────────────┘
│ - OpenTelemetry   │     
│ - Serilog         │     ┌───────────────┐     
└───────┬───────────┘────►│ Jaeger       │     
        │                 │ (Tracing)    │     
        │                 └───────────────┘     
        │                 
        │                 ┌───────────────┐     
        └────────────────►│ Seq          │     
                          │ (Logs)       │     
                          └───────────────┘     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementation Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setting Up Structured Logging
&lt;/h3&gt;

&lt;p&gt;I implemented Serilog for structured logging with multiple sinks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSerilog&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="n"&gt;configuration&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFrom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enrich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromLogContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enrich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithMachineName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enrich&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithCorrelationId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteTo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteTo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Seq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:5342"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteTo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"logs/log-.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rollingInterval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;RollingInterval&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Day&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Adding OpenTelemetry for Distributed Tracing
&lt;/h3&gt;

&lt;p&gt;I integrated OpenTelemetry with Jaeger for distributed tracing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOpenTelemetry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTracing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tracing&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tracing&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAspNetCoreInstrumentation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHttpClientInstrumentation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BankingService"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOtlpExporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Endpoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:4317"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration sends trace data to Jaeger, where I can visualize complete request flows and identify performance bottlenecks across service boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Configuring Metrics Collection
&lt;/h3&gt;

&lt;p&gt;For metrics, I initially tried OpenTelemetry.Exporter.Prometheus.AspNetCore but switched to prometheus-net due to stability issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMetricsRegistry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MetricsRegistry&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Prometheus metrics endpoint&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMetricServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Implementing Health Checks
&lt;/h3&gt;

&lt;p&gt;I added comprehensive health checks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHealthChecks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HealthCheckResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Healthy&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddCheck&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BankingServiceHealthCheck&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"BankingService"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"services"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Docker Compose for Observability Infrastructure
&lt;/h3&gt;

&lt;p&gt;I created a dedicated docker-compose file for the observability stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prom/prometheus&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./prometheus:/etc/prometheus&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9090:9090"&lt;/span&gt;

  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana/grafana&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./grafana/provisioning:/etc/grafana/provisioning&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./grafana/dashboards:/var/lib/grafana/dashboards&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3001:3000"&lt;/span&gt;

  &lt;span class="na"&gt;jaeger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jaegertracing/all-in-one&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;16686:16686"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4317:4317"&lt;/span&gt;

  &lt;span class="na"&gt;seq&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;datalust/seq&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5341:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5342:5341"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges Encountered
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Prometheus Integration Issues
&lt;/h3&gt;

&lt;p&gt;The OpenTelemetry.Exporter.Prometheus.AspNetCore package lacked a stable release. I switched to prometheus-net, which required refactoring my metrics collection approach but provided better stability.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Docker Networking Problems
&lt;/h3&gt;

&lt;p&gt;Initially, Prometheus couldn't scrape my API metrics. The issue was in the Prometheus configuration, which needed to use &lt;code&gt;host.docker.internal:5071&lt;/code&gt; to access the API running on the host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;banking-integration'&lt;/span&gt;
    &lt;span class="na"&gt;scrape_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
    &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;host.docker.internal:5071'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Port Conflicts
&lt;/h3&gt;

&lt;p&gt;I encountered port conflicts with Grafana's default port (3000). The solution was simple - changing it to 3001 in my docker-compose configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Result
&lt;/h2&gt;

&lt;p&gt;My observability solution provides comprehensive monitoring capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Structured logs&lt;/strong&gt; viewable in Seq with full context and correlation IDs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed traces&lt;/strong&gt; visualized in Jaeger showing complete request flows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom metrics dashboards&lt;/strong&gt; in Grafana displaying:

&lt;ul&gt;
&lt;li&gt;API health status&lt;/li&gt;
&lt;li&gt;HTTP request rates and status codes&lt;/li&gt;
&lt;li&gt;Request durations&lt;/li&gt;
&lt;li&gt;Banking service performance metrics&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;li&gt;Resource usage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1135fckmw1typhdpppbd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1135fckmw1typhdpppbd.png" alt="Image description" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fys20h8lx9usoxb5szkk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fys20h8lx9usoxb5szkk2.png" alt="Image description" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfnsdj98r34lx6pbherv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjfnsdj98r34lx6pbherv.png" alt="Image description" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with health checks&lt;/strong&gt; - They're the foundation of observability and help define what "healthy" means for your service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Plan for correlations&lt;/strong&gt; - Ensure correlation IDs flow through logs, traces, and metrics for effective troubleshooting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Jaeger is invaluable for complex systems&lt;/strong&gt; - Distributed tracing with Jaeger provides insights that logs and metrics alone cannot offer, especially for understanding request flows across service boundaries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Docker Compose for local development&lt;/strong&gt; - Makes it easy to spin up complex observability infrastructure locally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom metrics matter&lt;/strong&gt; - Generic metrics are helpful, but domain-specific metrics provide the most valuable insights.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Implementing a comprehensive observability solution for my .NET API has significantly improved my ability to monitor, diagnose, and optimize the core banking integration service. The combination of structured logging, distributed tracing with Jaeger, and metrics collection provides a complete picture of system behavior.&lt;/p&gt;

&lt;p&gt;The most significant benefit is the reduced time to identify and resolve issues - what previously might have taken hours of debugging can now be spotted in minutes through my Grafana dashboards or trace analysis in Jaeger.&lt;/p&gt;

&lt;p&gt;What observability tools are you using in your .NET projects? I'd love to hear about your experiences in the comments!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>backenddevelopment</category>
      <category>banking</category>
      <category>api</category>
    </item>
    <item>
      <title>Automating Docker Deployments to Azure with GitHub Actions: A Step-by-Step Guide</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Thu, 12 Sep 2024 12:41:51 +0000</pubDate>
      <link>https://dev.to/tino_muc/automating-docker-deployments-to-azure-with-github-actions-a-step-by-step-guide-12i4</link>
      <guid>https://dev.to/tino_muc/automating-docker-deployments-to-azure-with-github-actions-a-step-by-step-guide-12i4</guid>
      <description>&lt;h1&gt;
  
  
  Automating Docker Deployments to Azure with GitHub Actions: A Step-by-Step Guide
&lt;/h1&gt;

&lt;p&gt;In this article, we'll walk through how to automate your container deployment process using &lt;strong&gt;Azure Container Registry (ACR)&lt;/strong&gt; and &lt;strong&gt;Azure Container Instances (ACI)&lt;/strong&gt;, all triggered from &lt;strong&gt;GitHub Actions&lt;/strong&gt;. You’ll learn how to set up your resources, link them with GitHub, and automate deployments in a way that can fit right into your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;Imagine you’ve just finished building a cool app or service, and now you need to deploy it somewhere. You don’t want to manually build Docker images, push them to a registry, and then manually deploy them every time you make a change. Automating this process saves time and reduces the risk of mistakes!&lt;/p&gt;

&lt;h3&gt;
  
  
  What We'll Cover:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Setting Up Azure Resources&lt;/li&gt;
&lt;li&gt;Creating an Azure Service Principal&lt;/li&gt;
&lt;li&gt;GitHub Secrets and Workflows&lt;/li&gt;
&lt;li&gt;How the Automation Works&lt;/li&gt;
&lt;li&gt;Running It Yourself&lt;/li&gt;
&lt;li&gt;Helpful Tips and Troubleshooting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you get started, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;Azure account&lt;/strong&gt; with an active subscription.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;GitHub account&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Azure CLI&lt;/strong&gt; and &lt;strong&gt;Docker&lt;/strong&gt; installed locally.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools we'll be using:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure CLI&lt;/strong&gt;: This is your command-line interface for managing Azure resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;: You’ll need this to build your application images.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt;: This will automate your deployment pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Terms to know
&lt;/h3&gt;

&lt;p&gt;ACR - Azure container registry&lt;/p&gt;

&lt;h2&gt;
  
  
  ACI - Azure container instances
&lt;/h2&gt;

&lt;h2&gt;
  
  
  2. Setting Up Azure Resources
&lt;/h2&gt;

&lt;p&gt;First, we need to create a resource group and a container registry in Azure to store our Docker images.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Resource Group&lt;/strong&gt;:
Think of a resource group as a folder where you organize your Azure resources.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az group create &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;your-resource-group&amp;gt; &lt;span class="nt"&gt;--location&lt;/span&gt; &amp;lt;location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Azure Container Registry (ACR)&lt;/strong&gt;:
This is where your Docker images will be stored.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az acr create &lt;span class="nt"&gt;--resource-group&lt;/span&gt; &amp;lt;your-resource-group&amp;gt; &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;your-registry-name&amp;gt; &lt;span class="nt"&gt;--sku&lt;/span&gt; Basic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Creating an Azure Service Principal
&lt;/h2&gt;

&lt;p&gt;To allow GitHub Actions to access Azure resources, we’ll create something called a &lt;strong&gt;Service Principal&lt;/strong&gt;. It’s like giving GitHub a key to open the door to your Azure account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run this command to create the service principal:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   az ad sp create-for-rbac &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"GitHubAction"&lt;/span&gt; &lt;span class="nt"&gt;--role&lt;/span&gt; contributor &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--scopes&lt;/span&gt; /subscriptions/&amp;lt;subscription-id&amp;gt;/resourceGroups/&amp;lt;your-resource-group&amp;gt;/providers/Microsoft.ContainerRegistry/registries/&amp;lt;your-registry-name&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--sdk-auth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Save the &lt;strong&gt;JSON output&lt;/strong&gt; from this command. We’ll use it later in GitHub as a secret to authenticate.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. GitHub Secrets and Workflows
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Add Secrets to GitHub
&lt;/h3&gt;

&lt;p&gt;In your GitHub repository:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; Secrets and variables &amp;gt; Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the following secrets:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AZURE_CREDENTIALS&lt;/code&gt;: Paste the JSON output from the Service Principal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;REGISTRY_LOGIN_SERVER&lt;/code&gt;: Your Azure Container Registry URL (e.g., &lt;code&gt;&amp;lt;your-registry-name&amp;gt;.azurecr.io&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;REGISTRY_USERNAME&lt;/code&gt;: The client ID from the service principal JSON.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;REGISTRY_PASSWORD&lt;/code&gt;: The client secret from the service principal JSON.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4.2 Create GitHub Workflows
&lt;/h3&gt;

&lt;p&gt;Workflows are the steps that tell GitHub Actions what to do. We’ll create two workflows: one to build and push your Docker image to ACR, and another to deploy the image to ACI.&lt;/p&gt;

&lt;h4&gt;
  
  
  ACR Build and Push Workflow:
&lt;/h4&gt;

&lt;p&gt;This workflow will build your Docker image and push it to ACR every time you push code to the &lt;code&gt;main&lt;/code&gt; branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Push to ACR&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Login&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Azure'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure/login@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;creds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AZURE_CREDENTIALS }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;push&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;image'&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;docker build . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/app:latest&lt;/span&gt;
          &lt;span class="s"&gt;docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/app:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ACI Deployment Workflow:
&lt;/h4&gt;

&lt;p&gt;This workflow will deploy your container to Azure when you trigger it manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to ACI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Login&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Azure'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure/login@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;creds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AZURE_CREDENTIALS }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Azure&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Container&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Instances'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;azure/aci-deploy@v1'&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;resource-group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-resource-group&amp;gt;&lt;/span&gt;
          &lt;span class="na"&gt;dns-name-label&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myappdeployment&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.REGISTRY_LOGIN_SERVER }}/app:latest&lt;/span&gt;
          &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;eastus'&lt;/span&gt;
          &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. How the Automation Works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ACR Build and Push Workflow&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Triggered when you push code to the &lt;code&gt;main&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Logs into Azure, builds the Docker image, and pushes it to the registry.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;ACI Deployment Workflow&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manually triggered.&lt;/li&gt;
&lt;li&gt;Logs into Azure and deploys the Docker image from ACR to ACI.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Running It Yourself
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Push your code&lt;/strong&gt; to the &lt;code&gt;main&lt;/code&gt; branch, and the &lt;strong&gt;build and push workflow&lt;/strong&gt; will trigger automatically.&lt;/li&gt;
&lt;li&gt;To deploy, go to the &lt;strong&gt;GitHub Actions tab&lt;/strong&gt; and manually trigger the &lt;strong&gt;ACI deployment workflow&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. Helpful Tips and Troubleshooting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep Secrets Safe&lt;/strong&gt;: Make sure your GitHub secrets are correctly set up. If something isn’t working, it’s often an issue with secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Double-Check Logs&lt;/strong&gt;: If the deployment fails, check the logs in the &lt;strong&gt;Azure portal&lt;/strong&gt; or in the &lt;strong&gt;GitHub Actions logs&lt;/strong&gt; for more detailed error messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage Docker Images&lt;/strong&gt;: Over time, you may want to delete old Docker images from ACR to save space.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With just a few steps, you can automate your Docker deployments to Azure, saving time and avoiding manual mistakes. By using GitHub Actions and Azure services together, you’re taking a big step toward a more efficient and reliable workflow!&lt;/p&gt;




&lt;p&gt;Feel free to share any questions or tips in the comments below!&lt;/p&gt;

</description>
      <category>azure</category>
      <category>ai</category>
      <category>automation</category>
      <category>github</category>
    </item>
    <item>
      <title>Getting Started with AI for Developers: Part 1 - Demystifying the Basics</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Mon, 09 Sep 2024 07:25:13 +0000</pubDate>
      <link>https://dev.to/tino_muc/getting-started-with-ai-for-developers-part-1-demystifying-the-basics-9li</link>
      <guid>https://dev.to/tino_muc/getting-started-with-ai-for-developers-part-1-demystifying-the-basics-9li</guid>
      <description>&lt;h2&gt;
  
  
  Hello, Developers!
&lt;/h2&gt;

&lt;p&gt;AI is no longer just a dream. It's here and changing how we build software. It can make apps better and more useful. But how do you start using AI in your projects?&lt;/p&gt;

&lt;p&gt;This series aims to equip you with the fundamental knowledge to embark on your AI development journey. In this first part, we'll delve into core concepts and provide a hands-on example using Langchain and OpenAI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demystifying AI Jargon:
&lt;/h3&gt;

&lt;p&gt;Before diving in, let's clear the air with some key terms:&lt;/p&gt;

&lt;p&gt;LLM (Large Language Model): These advanced AI models are trained on massive datasets of text and code, enabling them to generate human-quality text, translate languages, write different kinds of creative content, and answer your questions in an informative way. Thats OpenAi, Gemni, Claude, Llama etc &lt;br&gt;
   &lt;br&gt;
Langchain: This innovative library simplifies the process of interacting with various AI services through a unified API. It acts as a bridge between your code and powerful AI platforms like OpenAI.&lt;/p&gt;
&lt;h3&gt;
  
  
  Different Types of AI Models:
&lt;/h3&gt;

&lt;p&gt;There are numerous types of AI models, each specializing in a specific task. Some common categories include:&lt;/p&gt;

&lt;p&gt;Classification models: Used to categorize data points, such as spam detection or image recognition.&lt;br&gt;
Generative models: Create new data, like generating realistic images or composing music.&lt;br&gt;
Regression models: Predict continuous values based on input data, used in forecasting or trend analysis.&lt;br&gt;
Understanding the different model types helps you choose the right tool for the job.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hands-on Example: Chatting with OpenAI using Langchain
&lt;/h3&gt;

&lt;p&gt;Now, let's get our hands dirty! This code snippet demonstrates how to interact with OpenAI's chatbot functionality using Langchain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { ChatOpenAI } from "@langchain/openai";

async function main() {
  const chatModel = new ChatOpenAI({}); // Create a ChatOpenAI instance

  const response = await chatModel.invoke("What is Hello World?"); // Ask a question
  console.log(response); // Print the response
}

main().catch(console.error);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer to &lt;a href="https://github.com/Tinomuchenje/ai-dev-journey.git" rel="noopener noreferrer"&gt;https://github.com/Tinomuchenje/ai-dev-journey.git&lt;/a&gt; for running setup example.&lt;/p&gt;

&lt;h4&gt;
  
  
  Explanation
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;1. This code first imports the necessary module, ChatOpenAI, from the @langchain/openai package&lt;/li&gt;
&lt;li&gt;Then, it creates an instance of ChatOpenAI. The invoke method allows us to send a question ("What is Hello World?") to the OpenAI chatbot and capture its response. &lt;/li&gt;
&lt;li&gt;Finally, the response is logged to the console.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Make sure you have Langchain and its dependencies installed before running this code. You can find instructions on the Langchain website: &lt;a href="https://js.langchain.com/v0.2/docs/introduction/" rel="noopener noreferrer"&gt;https://js.langchain.com/v0.2/docs/introduction/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, you'll need an OpenAI API key to use the service. Refer to OpenAI's documentation for acquiring one.&lt;/p&gt;

&lt;p&gt;This is just a taste of what's possible with Langchain and AI. In the upcoming parts of this series, we'll explore more complex applications, delve into different AI models, and equip you with the skills to build your own AI-powered projects.&lt;/p&gt;

&lt;p&gt;Stay tuned for Part 2!&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Resources:
&lt;/h2&gt;

&lt;p&gt;Langchain Documentation: &lt;a href="https://js.langchain.com/v0.2/docs/introduction/" rel="noopener noreferrer"&gt;https://js.langchain.com/v0.2/docs/introduction/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article serves as a springboard for your AI development journey. Feel free to tinker with the code and experiment with different functionalities. With dedication and a thirst for exploration, you'll be building your own AI marvels in no time!&lt;/p&gt;

&lt;p&gt;Happy coding&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Careful using forEach in Javascript</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Fri, 03 Nov 2023 08:20:56 +0000</pubDate>
      <link>https://dev.to/tino_muc/careful-using-foreach-in-javascript-50jd</link>
      <guid>https://dev.to/tino_muc/careful-using-foreach-in-javascript-50jd</guid>
      <description>&lt;p&gt;When dealing with asynchronous functions, using &lt;code&gt;Array.prototype.forEach()&lt;/code&gt; can lead to unexpected behavior. Let’s explore why and discuss alternative approaches.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Array.prototype.forEach() and Asynchronous Functions&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;forEach()&lt;/code&gt; method is commonly used for iterating through arrays. However, it has a limitation: it &lt;strong&gt;does not&lt;/strong&gt; work well with asynchronous functions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you use &lt;code&gt;forEach()&lt;/code&gt; with asynchronous operations (such as promises), it does not wait for the promises to resolve. As a result, the calculations inside the promises may be lost, leading to incorrect results or errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ratings = [5, 4, 5];
let sum = 0;

const sumFunction = async (a, b) =&amp;gt; a + b;

ratings.forEach(async (rating) =&amp;gt; {
  sum = await sumFunction(sum, rating);
});

console.log(sum);
// Naively expected output: 14
// Actual output: 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the sumFunction is asynchronous, but the &lt;code&gt;forEach()&lt;/code&gt; loop does not wait for the promises to complete. Hence, the actual output is 0, even though you would naively expected it to be 14.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Alternative Approach: Using &lt;code&gt;for...of:&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of f&lt;code&gt;orEach()&lt;/code&gt;, consider using a &lt;code&gt;for...of&lt;/code&gt; loop. This loop does await each asynchronous task in order, ensuring that promises are resolved before moving to the next iteration.&lt;br&gt;
Here’s how you can rewrite your example using &lt;code&gt;for...of:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ratings = [5, 4, 5];
let sum = 0;

const sumFunction = async (a, b) =&amp;gt; a + b;

for (const rating of ratings) {
  sum = await sumFunction(sum, rating);
}

console.log(sum); // Expected output: 14

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;While &lt;code&gt;for...of&lt;/code&gt; is a better choice for handling asynchronous tasks, it’s essential to understand the behavior of different iteration methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be aware of conventions and project-specific guidelines. Discuss with your team to find the solution that best suits your project’s needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember, using the right iteration method can significantly impact the correctness and performance of your code. &lt;/p&gt;

&lt;p&gt;Happy coding! 🚀🔍👩‍💻&lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to use Ruby on Rails ActiveRecord joins</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Tue, 04 Jul 2023 14:11:14 +0000</pubDate>
      <link>https://dev.to/tino_muc/how-to-use-ruby-on-rails-activerecord-joins-edg</link>
      <guid>https://dev.to/tino_muc/how-to-use-ruby-on-rails-activerecord-joins-edg</guid>
      <description>&lt;p&gt;In this article, I will show you how to use the ActiveRecord joins method to query data from two or more tables in Ruby on Rails. I will use a simple example of a SsoProfile model that belongs to a User model and has some attributes related to a single sign-on provider.&lt;/p&gt;

&lt;p&gt;What is a join?&lt;br&gt;
A join is a way of combining two or more tables based on a common attribute. For example, in this case, the SsoProfile table and the User table have a common attribute called user_id, which is the foreign key that references the User table. A join allows you to access the data from both tables in one query, by matching the rows that have the same user_id value.&lt;/p&gt;

&lt;p&gt;How to use joins in Rails?&lt;br&gt;
Rails provides a built-in method called joins that takes an argument of the name of the association or a hash of associations. For example, if you have a SsoProfile model that belongs to a User model, you can use joins like this:&lt;/p&gt;

&lt;h1&gt;
  
  
  Find all SsoProfiles by joining the users table
&lt;/h1&gt;

&lt;p&gt;sso_profiles = SsoProfile.joins(:user)&lt;/p&gt;

&lt;h1&gt;
  
  
  Find a SsoProfile by joining the users table and using the email attribute
&lt;/h1&gt;

&lt;p&gt;sso_profile = SsoProfile.joins(:user).find_by(users: {email: "&lt;a href="mailto:alice@gmail.com"&gt;alice@gmail.com&lt;/a&gt;"})&lt;/p&gt;

&lt;p&gt;The joins method will return an ActiveRecord::Relation object that you can chain with other methods like where, order, limit, etc.&lt;/p&gt;

&lt;p&gt;How to illustrate a join?&lt;br&gt;
To illustrate how a join works, let's look at an example of how the SsoProfile table and the User table would look:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SsoProfile table&lt;/th&gt;
&lt;th&gt;user_id&lt;/th&gt;
&lt;th&gt;sso_provider&lt;/th&gt;
&lt;th&gt;sso_provider_id&lt;/th&gt;
&lt;th&gt;sso_provider_data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;google&lt;/td&gt;
&lt;td&gt;1234567890&lt;/td&gt;
&lt;td&gt;{"name": "Alice", "email": "&lt;a href="mailto:alice@gmail.com"&gt;alice@gmail.com&lt;/a&gt;", "picture": "&lt;a href="https://example.com/alice.jpg%22" rel="noopener noreferrer"&gt;https://example.com/alice.jpg"&lt;/a&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;facebook&lt;/td&gt;
&lt;td&gt;9876543210&lt;/td&gt;
&lt;td&gt;{"name": "Bob", "email": "&lt;a href="mailto:bob@facebook.com"&gt;bob@facebook.com&lt;/a&gt;", "picture": "&lt;a href="https://example.com/bob.jpg%22" rel="noopener noreferrer"&gt;https://example.com/bob.jpg"&lt;/a&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;twitter&lt;/td&gt;
&lt;td&gt;4567891230&lt;/td&gt;
&lt;td&gt;{"name": "Charlie", "email": "&lt;a href="mailto:charlie@twitter.com"&gt;charlie@twitter.com&lt;/a&gt;", "picture": "&lt;a href="https://example.com/charlie.jpg%22" rel="noopener noreferrer"&gt;https://example.com/charlie.jpg"&lt;/a&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User table&lt;/th&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;email&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:alice@gmail.com"&gt;alice@gmail.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:bob@facebook.com"&gt;bob@facebook.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Bob&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:charlie@twitter.com"&gt;charlie@twitter.com&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Charlie&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A join will combine the two tables based on the user_id attribute, like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SsoProfile table JOIN User table on user_id = id&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;user_id    sso_provider    sso_provider_id    sso_provider_data    id    email    name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1          google          1234567890         {"name": "Alice", ...}     1    &lt;a href="mailto:alice@gmail.com"&gt;alice@gmail.com&lt;/a&gt;   Alice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2          facebook        9876543210         {"name": "Bob", ...}       2    &lt;a href="mailto:bob@facebook.com"&gt;bob@facebook.com&lt;/a&gt;   Bob&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3          twitter         4567891230         {"name": "Charlie", ...}   3    &lt;a href="mailto:charlie@twitter.com"&gt;charlie@twitter.com&lt;/a&gt;   Charlie&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can see that the join has matched the rows that have the same user_id value and created a new table with all the attributes from both tables. You can use this new table to query the data from both tables in one query, by using the table name and the attribute name.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title># Understanding .NET 6 Configuration Files</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Tue, 04 Jul 2023 14:07:39 +0000</pubDate>
      <link>https://dev.to/tino_muc/-understanding-net-6-configuration-files-39ld</link>
      <guid>https://dev.to/tino_muc/-understanding-net-6-configuration-files-39ld</guid>
      <description>&lt;p&gt;Configuring a .NET 6 application can be a complex task, especially when dealing with different environments, sensitive data, and file paths. This article will guide you through the key aspects of understanding and using the &lt;code&gt;appsettings.json&lt;/code&gt; file in a .NET 6 application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the &lt;code&gt;appsettings.json&lt;/code&gt; File
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;appsettings.json&lt;/code&gt; file is a critical part of a .NET application. It is primarily used for storing application settings, such as connection strings, logging settings, and other configuration data.&lt;/p&gt;

&lt;p&gt;Here's an example of what a typical &lt;code&gt;appsettings.json&lt;/code&gt; file could look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"LogLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Debug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"System"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Information"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Microsoft"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Error"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AllowedHosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ConnectionString"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Data Source=Database;Initial Catalog=AppDB;Integrated Security=True"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"NetworkPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;ServerName&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;SharedFolder"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling Sensitive Data in Configuration
&lt;/h2&gt;

&lt;p&gt;One of the key considerations when dealing with configuration files is the handling of sensitive data. It is never recommended to store sensitive data, like database connection strings, in the configuration file in plain text. Instead, consider using the Secret Manager tool or environment variables to store sensitive data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network Paths in Configuration
&lt;/h2&gt;

&lt;p&gt;When defining a network path in the &lt;code&gt;appsettings.json&lt;/code&gt; file, you can simply provide the network path as a string value. However, your application will need appropriate permissions to access the network path. If it's running under a user account that has access to the network path, it should be able to read the path without issues.&lt;/p&gt;

&lt;p&gt;Here's an example of how to define a network path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"NetworkPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s2"&gt;ServerName&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;SharedFolder"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In .NET, the double backslashes (&lt;code&gt;\\\\&lt;/code&gt;) will be interpreted as a single backslash (&lt;code&gt;\&lt;/code&gt;). This is because the backslash is an escape character in C#, which means it is used to introduce special character sequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Configuration Values
&lt;/h2&gt;

&lt;p&gt;To access these configuration values in your .NET 6 app, you can use the &lt;code&gt;IConfiguration&lt;/code&gt; interface. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Startup&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;_configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Startup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;networkPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_configuration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"NetworkPath"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="c1"&gt;// Use networkPath...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;appsettings.json&lt;/code&gt; file is a key component of .NET 6 applications, allowing developers to manage various configurations. By understanding how to properly structure this file, manage sensitive data, define network paths, and access configuration values in the code, you can create more secure and flexible .NET applications. Remember that the final configuration values will be a combination of various sources like environment variables, command line arguments, and user secrets. Always ensure that your application has the necessary permissions to access any paths defined in the configuration. &lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Learn about the difference between var, let, and const keywords in JavaScript and when to use them.</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Fri, 02 Jun 2023 10:21:01 +0000</pubDate>
      <link>https://dev.to/tino_muc/learn-about-the-difference-between-var-let-and-const-keywords-in-javascript-and-when-to-use-them-2638</link>
      <guid>https://dev.to/tino_muc/learn-about-the-difference-between-var-let-and-const-keywords-in-javascript-and-when-to-use-them-2638</guid>
      <description>&lt;h2&gt;
  
  
  var, let, and const: What's the Difference in JavaScript?
&lt;/h2&gt;

&lt;p&gt;JavaScript is a dynamic and flexible language that allows you to declare variables in different ways. You can use var, let, or const keywords to declare variables in JavaScript, but what's the difference between them and when should you use them?&lt;/p&gt;

&lt;p&gt;In this article, you will learn about the difference between var, let, and const keywords in JavaScript and some of their advantages and disadvantages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a variable?
&lt;/h2&gt;

&lt;p&gt;A variable is a container for storing information. You can use a variable to store a value, such as a number, a string, a boolean, an object, or a function. You can also use a variable to refer to a value that may change over time.&lt;/p&gt;

&lt;p&gt;To declare a variable in JavaScript, you need to use a keyword followed by a name for the variable. For example:&lt;/p&gt;

&lt;p&gt;var x = 10; // Declare a variable using var&lt;br&gt;
let y = 20; // Declare a variable using let&lt;br&gt;
const z = 30; // Declare a variable using const&lt;/p&gt;

&lt;p&gt;The name of the variable must follow some rules:&lt;/p&gt;

&lt;p&gt;•  It must begin with a letter, or $, or _.&lt;/p&gt;

&lt;p&gt;•  It cannot contain spaces or punctuation marks (except $ and _).&lt;/p&gt;

&lt;p&gt;•  It cannot be a reserved word in JavaScript, such as var, let, const, if, for, etc.&lt;/p&gt;

&lt;p&gt;•  It is case sensitive, meaning that x and X are different variables.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is the difference between var, let, and const?
&lt;/h2&gt;

&lt;p&gt;The main difference between var, let, and const is how they affect the scope and hoisting of the variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;br&gt;
The scope of a variable is the part of the code where the variable can be accessed or used. In JavaScript, there are two types of scopes: global scope and local scope.&lt;/p&gt;

&lt;p&gt;•  Global scope: A variable declared in the global scope can be accessed from anywhere in the code. A variable declared outside any function or block is in the global scope.&lt;/p&gt;

&lt;p&gt;•  Local scope: A variable declared in the local scope can only be accessed within the function or block where it is declared. A variable declared inside a function or block is in the local scope.&lt;/p&gt;

&lt;p&gt;The scope of a variable declared with var is either global or function-based. This means that if you declare a variable with var inside a function, it can only be accessed within that function. However, if you declare a variable with var inside a block (such as an if statement or a for loop), it can be accessed outside that block as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb3jljx1lebempdkyfiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb3jljx1lebempdkyfiq.png" alt="Image description" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function foo() {
var x = 10; // Declare x with var inside foo function
if (true) {
var y = 20; // Declare y with var inside if block
console.log(x); // 10 (x is accessible inside if block)
console.log(y); // 20 (y is accessible inside if block)
}
console.log(x); // 10 (x is accessible outside if block)
console.log(y); // 20 (y is accessible outside if block)
}

foo();

console.log(x); // ReferenceError: x is not defined (x is not accessible outside foo function)
console.log(y); // ReferenceError: y is not defined (y is not accessible outside foo function)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The scope of a variable declared with let or const is block-based. This means that if you declare a variable with let or const inside any block (such as a function, an if statement, or a for loop), it can only be accessed within that block.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function foo() {
let x = 10; // Declare x with let inside foo function
const z = 30; // Declare z with const inside foo function
if (true) {
let y = 20; // Declare y with let inside if block
console.log(x); // 10 (x is accessible inside if block)
console.log(y); // 20 (y is accessible inside if block)
console.log(z); // 30 (z is accessible inside if block)
}
console.log(x); // 10 (x is accessible outside if block)
console.log(y); // ReferenceError: y is not defined (y is not accessible outside if block)
console.log(z); // 30 (z is accessible outside if block)
}

foo();

console.log(x); // ReferenceError: x is not defined (x is not accessible outside foo function)
console.log(y); // ReferenceError: y is not defined (y is not accessible outside foo function)
console.log(z); // ReferenceError: z is not defined (z is not accessible outside foo function)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using block-based scope can prevent accidental leaks and conflicts of variables with the same name in different blocks.&lt;/p&gt;

&lt;p&gt;Hoisting&lt;br&gt;
Hoisting is a mechanism in JavaScript that moves the declarations of variables to the top of their scope before any code is executed. This means that you can use a variable before it is declared, but its initial value will be undefined.&lt;/p&gt;

&lt;p&gt;Hoisting applies differently to variables declared with var, let, and const.&lt;/p&gt;

&lt;p&gt;Variables declared with var are hoisted to the top of their scope, either global or function-based. This means that you can use them before they are declared, but their initial value will be undefined.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;console.log(x); // undefined (x is hoisted but not initialized)&lt;br&gt;
var x = 10;&lt;br&gt;
console.log(x); // 10&lt;/p&gt;

&lt;p&gt;Variables declared with let or const are also hoisted to the top of their scope, but they are not initialized until they are declared. This means that you cannot use them before they are declared, and you will get a reference error.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(x); // ReferenceError: Cannot access 'x' before initialization (x is hoisted but not initialized)
let x = 10;
console.log(x); // 10

console.log(y); // ReferenceError: Cannot access 'y' before initialization (y is hoisted but not initialized)
const y = 20;
console.log(y); // 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This behavior creates a temporal dead zone between the hoisting and the initialization of the variables declared with let or const. This can prevent errors and enforce good coding practices.&lt;/p&gt;

&lt;p&gt;When to use var, let, and const?&lt;br&gt;
As you have seen, there are some advantages and disadvantages of using var, let, and const to declare variables in JavaScript. So when should you use them?&lt;/p&gt;

&lt;p&gt;The general recommendation is to avoid using var unless you have a specific reason to do so. Using var can cause confusion and errors due to its function-based scope and hoisting behavior.&lt;/p&gt;

&lt;p&gt;Instead, you should use let or const to declare variables with block-based scope and temporal dead zone. This can prevent accidental leaks and conflicts of variables with different blocks.&lt;/p&gt;

&lt;p&gt;The main difference between let and const is that let allows you to change the value of a variable after it is declared, while const does not. You should use const when you want to declare a constant value that will not change, such as:&lt;/p&gt;

&lt;p&gt;•  A primitive value like a number or a string.&lt;/p&gt;

&lt;p&gt;•  A reference to an object or an array that will always point to the same object or array.&lt;/p&gt;

&lt;p&gt;•  A function expression or an arrow function.&lt;/p&gt;

&lt;p&gt;You should use let when you want to declare a variable that may change over time, such as:&lt;/p&gt;

&lt;p&gt;•  A counter or an iterator in a loop.&lt;/p&gt;

&lt;p&gt;•  A temporary value in an algorithm.&lt;/p&gt;

&lt;p&gt;•  A conditionally assigned value in an if-else statement.&lt;/p&gt;

&lt;p&gt;Here are some examples of using let and const:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Use const for primitive values that will not change
const PI = 3.14;
const NAME = "John";

// Use const for references to objects or arrays that will always point to the same object or array
const person = {name: "John", age: 25};
const numbers = [1, 2, 3];

// Use const for function expressions or arrow functions
const add = function(a,b) {
return a + b;
};

const multiply = (a,b) =&amp;gt; {
return a * b;
};

// Use let for counters or iterators in loops
for (let i = 0
i &amp;lt; 10; i++) {
console.log(i); // 0, 1, 2, ..., 9
}

// Use let for temporary values in algorithms
let a = 10;
let b = 20;
let temp = a; // Use temp to swap the values of a and b
a = b;
b = temp;

// Use let for conditionally assigned values in if-else statements
let greeting;
if (hour &amp;lt; 12) {
greeting = "Good morning";
} else {
greeting = "Good afternoon";
}

console.log(greeting); // Depends on the value of hour
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, you learned about the difference between &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, and &lt;code&gt;const&lt;/code&gt; keywords in JavaScript and when to use them. You learned that:&lt;/p&gt;

&lt;p&gt;•  &lt;code&gt;var&lt;/code&gt; declares a variable with function scope or global scope, and it is hoisted to the top of its scope with an initial value of &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;•  &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; declare variables with block scope, and they are hoisted to the top of their scope but not initialized until they are declared.&lt;/p&gt;

&lt;p&gt;•  You should avoid using &lt;code&gt;var&lt;/code&gt; unless you have a specific reason to do so, and use &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;const&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;•  You should use &lt;code&gt;const&lt;/code&gt; when you want to declare a constant value that will not change, and use &lt;code&gt;let&lt;/code&gt; when you want to declare a variable that may change over time.&lt;/p&gt;

&lt;p&gt;I hope this article helps you understand the difference between &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, and &lt;code&gt;const&lt;/code&gt; in JavaScript. If you have any questions or feedback, please leave a comment below. Thanks for reading!blush&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to find non-numeric values in SQL Server</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Mon, 29 May 2023 13:24:46 +0000</pubDate>
      <link>https://dev.to/tino_muc/how-to-find-non-numeric-values-in-sql-server-1jf7</link>
      <guid>https://dev.to/tino_muc/how-to-find-non-numeric-values-in-sql-server-1jf7</guid>
      <description>&lt;p&gt;Have you ever encountered an error like this when trying to convert a varchar column to a numeric column in SQL Server?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Error converting data type varchar to numeric&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This error occurs when the varchar column contains some values that are not valid for the numeric data type, such as alphabets, symbols, spaces, commas, etc.&lt;/p&gt;

&lt;p&gt;In this article, I will show you how to find these non-numeric values using some simple SQL queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding non-numeric values
&lt;/h2&gt;

&lt;p&gt;There are two main ways to find non-numeric values in a varchar column in SQL Server. One way is to use the ISNUMERIC() function, which returns 1 for numeric values and 0 for non-numeric values. Another way is to use the LIKE operator with a pattern that matches any character that is not a digit.&lt;/p&gt;

&lt;p&gt;For example, suppose we have a table called Payments with a column called Amount that contains some varchar values. Some of them are numeric, some of them are not. Here is a sample of the data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ABCDE#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.ABC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;To find the non-numeric values using the ISNUMERIC() function, we can use this query:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Select Amount&lt;br&gt;
from Payments&lt;br&gt;
where ISNUMERIC(Amount) &amp;lt;&amp;gt; 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will return the following rows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ABCDE#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.ABC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;To find the non-numeric values using the LIKE operator, we can use this query:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Select Amount&lt;br&gt;
from Payments&lt;br&gt;
where Amount like '%[^0-9]%'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will return the same rows as before:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ABCDE#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.ABC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, I have shown you how to find non-numeric values in a varchar column in SQL Server using some simple SQL queries. I hope this helps you understand the cause of the error &lt;em&gt;Error converting data type varchar to numeric&lt;/em&gt; and prepare your data for conversion.&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback, please let me know in the comments below.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>datascience</category>
      <category>development</category>
    </item>
    <item>
      <title>Parse vs TryParse in C#</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Wed, 24 May 2023 09:30:36 +0000</pubDate>
      <link>https://dev.to/tino_muc/parse-vs-tryparse-in-c-n8a</link>
      <guid>https://dev.to/tino_muc/parse-vs-tryparse-in-c-n8a</guid>
      <description>&lt;p&gt;We will explore the difference between the Parse and TryParse methods in C#, and when to use each one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int.Parse() will throw an exception&lt;br&gt;
int.TryParse() will return false (but not throw an exception)&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Parse and TryParse methods?
&lt;/h2&gt;

&lt;p&gt;The Parse and TryParse methods are used to convert a string representation of a number to a numeric type, such as int, long, double, decimal, etc. For example, if we have a string "123", we can use int.Parse or int.TryParse to convert it to an integer value 123.&lt;/p&gt;

&lt;p&gt;The Parse and TryParse methods are defined on each numeric type, such as System.Int32, System.Double, System.Decimal, etc. They have different overloads that accept different parameters, such as the number format, the culture information, and the style of the number.&lt;/p&gt;

&lt;p&gt;What is the difference between Parse and TryParse methods?&lt;br&gt;
The main difference between Parse and TryParse methods is how they handle invalid input. If the string cannot be converted to a number, the** Parse** method will throw an exception, while the &lt;strong&gt;TryParse&lt;/strong&gt; method will return false and not throw an exception.&lt;/p&gt;

&lt;p&gt;For example, parse the string "abc" as an integer, the int.Parse method will throw a FormatException, while the int TryParse method will return false and assign a default value of 0 to the output parameter.&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
string input = "abc";&lt;br&gt;
int result;&lt;/p&gt;

&lt;p&gt;// Using Parse method&lt;br&gt;
try&lt;br&gt;
{&lt;br&gt;
result = int.Parse(input); // This will throw an exception&lt;br&gt;
Console.WriteLine(result);&lt;br&gt;
}&lt;br&gt;
catch (FormatException e)&lt;br&gt;
{&lt;br&gt;
Console.WriteLine(e.Message); // This will print "Input string was not in a correct format."&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// Using TryParse method&lt;br&gt;
if (int.TryParse(input, out result)) // This will return false&lt;br&gt;
{&lt;br&gt;
Console.WriteLine(result); // This will not be executed&lt;br&gt;
}&lt;br&gt;
else&lt;br&gt;
{&lt;br&gt;
Console.WriteLine("String could not be parsed."); // This will print "String could not be parsed."&lt;br&gt;
}&lt;br&gt;
`&lt;br&gt;
The TryParse method does not use try/catch internally. It is implemented without exceptions so that it is faster and more efficient. In fact, it is likely that the Parse method calls the TryParse method internally and then throws an exception if it returns false.&lt;/p&gt;

&lt;p&gt;When to use Parse and TryParse methods?&lt;br&gt;
The general rule is to use Parse method if you are sure that the string will be valid and can be converted to a number. Otherwise, use TryParse method to avoid exceptions and handle invalid input gracefully.&lt;/p&gt;

&lt;p&gt;For example, if you are reading user input from a console or a text box, you should use TryParse method to validate the input and display an error message if it is not a valid number. On the other hand, if you are parsing a string that is hard-coded or comes from a reliable source, you can use Parse method and assume that it will succeed.&lt;/p&gt;

&lt;p&gt;However, you should always use exception handling when calling Parse method to catch any FormatException that may occur due to unexpected or invalid input. You can also use String.IsNullOrEmpty method to check for null or empty strings before attempting to parse them.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>backend</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Keep Configuration Secrets out of a Django Project</title>
      <dc:creator>Tino Joel Muchenje</dc:creator>
      <pubDate>Wed, 02 Jun 2021 21:58:55 +0000</pubDate>
      <link>https://dev.to/tino_muc/how-to-keep-configuration-secrets-out-of-a-django-project-k07</link>
      <guid>https://dev.to/tino_muc/how-to-keep-configuration-secrets-out-of-a-django-project-k07</guid>
      <description>&lt;p&gt;It is best practice to hide your configuration details and not include them in version control for the sake of security and independence of project instance. Getting straight to the point here is how to do it using python decouple library.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Quick Summary
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Install decouple pip install python-decouple or [&lt;a href="https://pypi.org/project/python-decouple/" rel="noopener noreferrer"&gt;https://pypi.org/project/python-decouple/&lt;/a&gt;].&lt;/li&gt;
&lt;li&gt;Create file named .env or .ini under the route of your project.&lt;/li&gt;
&lt;li&gt;Add ignore for .env if you are using git.&lt;/li&gt;
&lt;li&gt;Retrieve the settings by importing decouple into the settings.py file and replacing variables to hide with config.
5 . Test the application&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Detailed Steps
&lt;/h1&gt;

&lt;p&gt;This is how our initial exposed settings.py looks like before exclusion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3izb^ryglmyscret_key_here&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.postgresql_psycopg2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HELLO_DJANGO&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;TINO&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;thepasswordhere&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0000&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  1. Installing decouple
&lt;/h2&gt;

&lt;p&gt;run&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;pip install python-decouple&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 or if you prefer downloading [&lt;a href="https://pypi.org/project/python-decouple/" rel="noopener noreferrer"&gt;https://pypi.org/project/python-decouple/&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Create .env file
&lt;/h2&gt;

&lt;p&gt;Add variables to hide or exclude by copying values from settings.py making sure you do not include quotes("").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;izb&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;ryglmyscret_key_here&lt;/span&gt;
&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HELLO_DJANGO&lt;/span&gt;
&lt;span class="n"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TINO&lt;/span&gt;
&lt;span class="n"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thepasswordhere&lt;/span&gt;
&lt;span class="n"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;127.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Ignoring .env from version control(git)
&lt;/h2&gt;

&lt;p&gt;Go into your gitignore file and add .env as below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Environments
&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make sure our file with variables is not tracked by the source control.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Retrieve the settings or values on variables set in the .env file
&lt;/h2&gt;

&lt;p&gt;Import config from decouple as below and reference variables as strings&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;decouple&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DEBUG&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#NB casting here for boolean
&lt;/span&gt;&lt;span class="n"&gt;DATABASES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;default&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ENGINE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;django.db.backends.postgresql_psycopg2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DB_NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DB_USER&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;DB_HOST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;PORT&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please Note: On non string values we need to cast to the type e.g&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;DEBUG = ('DEBUG', cast=bool)&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 as DEBUG expects boolean True or False&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Test to see if your application still run the same
&lt;/h2&gt;

&lt;p&gt;Execute&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;py manage.py runserver&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 to make sure your application still run smoothly.&lt;/p&gt;

&lt;p&gt;I have tried to go straight to the point for easier implementation. My motivation to write this down was the struggle I had to find similar information which is helpful. Feel free to suggest different implementations or suggestions. &lt;/p&gt;

&lt;p&gt;Happy Coding!!! &lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>security</category>
      <category>deployment</category>
    </item>
  </channel>
</rss>
