<?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: Sophia Iroegbu</title>
    <description>The latest articles on DEV Community by Sophia Iroegbu (@sophyia).</description>
    <link>https://dev.to/sophyia</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%2F435453%2F483f8bd7-17aa-46ef-b297-52d30e6914dc.jpg</url>
      <title>DEV Community: Sophia Iroegbu</title>
      <link>https://dev.to/sophyia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sophyia"/>
    <language>en</language>
    <item>
      <title>How to Build a RAG Solution with Llama Index, ChromaDB, and Ollama</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Wed, 05 Nov 2025 07:21:00 +0000</pubDate>
      <link>https://dev.to/sophyia/how-to-build-a-rag-solution-with-llama-index-chromadb-and-ollama-20lb</link>
      <guid>https://dev.to/sophyia/how-to-build-a-rag-solution-with-llama-index-chromadb-and-ollama-20lb</guid>
      <description>&lt;p&gt;Have you ever wanted to read through a ton of documents super fast or ask questions based on a particular knowledge or domain? That’s where RAG shines. &lt;/p&gt;

&lt;p&gt;RAG stands for retrieval-augmented generation, and it lets you combine a knowledge base, such as a PDF or a web page, with a large language model (LLM), such as Gemini or GPT, to get accurate, fast answers. So instead of relying solely on ChatGPT, which does not know your documents and would likely hallucinate (give incorrect answers), you could build and use a RAG solution. &lt;/p&gt;

&lt;p&gt;In this tutorial guide, we’ll build a very simple document search tool with Python, LlamaIndex, ChromaDB, and Ollama. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow alongside this guide, you need to have the following installed on your laptop or PC. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have Python 3.10+, and&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ollama.com/download" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; installed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  These are the steps we will cover:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Downloading models on Ollama,&lt;/li&gt;
&lt;li&gt;Setting up a Llama index and Chroma database,&lt;/li&gt;
&lt;li&gt;Loading our documents to the Llama index, and&lt;/li&gt;
&lt;li&gt;Building a query engine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Download a Model on Ollama
&lt;/h2&gt;

&lt;p&gt;In case you are unfamiliar with Ollama. &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; is an open source that lets you download &lt;a href="https://ollama.com/models" rel="noopener noreferrer"&gt;local models&lt;/a&gt; and use them in your projects. You can download the software &lt;a href="https://ollama.com/download" rel="noopener noreferrer"&gt;here&lt;/a&gt; and follow the on-screen instructions to install it. &lt;/p&gt;

&lt;p&gt;On your terminal, run this command to download the Llama 3.1:8b model locally. You may choose to use any model of your preference; the following models are &lt;a href="https://ollama.com/search" rel="noopener noreferrer"&gt;available&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run llama3.1:8b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To confirm you have downloaded the model, run the same command, and you can send a message to the model. &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%2F3um8kwzbwshvxxfcsirg.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%2F3um8kwzbwshvxxfcsirg.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that’s done, create and activate your virtual environment, then install Chromadb, Llama Index, and Python-dotenv to build with them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;chromadb llama-index python-dotenv llama-index-readers-web 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Set up &lt;a href="https://developers.llamaindex.ai" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt; and &lt;a href="https://www.trychroma.com/" rel="noopener noreferrer"&gt;Chroma DB&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Firstly, set up your project with &lt;a href="https://developers.llamaindex.ai/python/framework/" rel="noopener noreferrer"&gt;Llama index&lt;/a&gt; and &lt;a href="https://www.trychroma.com/" rel="noopener noreferrer"&gt;ChromaDB&lt;/a&gt;, but before we get to that, what is Llama index, and how does ChromaDB factor into a RAG application? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://llamaindex.ai/llamaindex/" rel="noopener noreferrer"&gt;Llama index&lt;/a&gt; is an open-source RAG orchestrator; this is the brain behind RAG. It loads your documents (PDF, TXT, CSV files, or webpages), splits them into chunks (bits or pieces), and saves them in a vector database. A vector database is not like a regular (SQL or NoSQL) database, which stores image files as image files or text as text files; instead, it saves every piece of data as vector embeddings, a list of numbers that encodes a text. If a text like &lt;code&gt;"cat sitting on a mat"&lt;/code&gt; is saved, it saves like this &lt;code&gt;[0.12, -0.87, 0.44, …]&lt;/code&gt;. &lt;a href="https://www.trychroma.com/" rel="noopener noreferrer"&gt;ChromaDB&lt;/a&gt; is a type of vector database, and the vectors are what the LLM uses for retrieval in RAG. The whole beauty of RAG lies in the implementation of this search. &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%2Fqkz81szp4njpnclsybav.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%2Fqkz81szp4njpnclsybav.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you’ve understood this, let’s initialize the llama index and chroma vector database in our project. You would need to import the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;VectorStoreIndex&lt;/code&gt;This will be used to wrap the vector store and load and embed our documents.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Settings&lt;/code&gt; : This will be used to set our LLM and an embedding model.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ChromaVectorStore&lt;/code&gt; : This will be used to set up our chroma vector database.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HuggingFaceEmbedding&lt;/code&gt; : This will be used to set up an embedding model from &lt;a href="https://huggingface.co/models" rel="noopener noreferrer"&gt;Huggingface&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we need to define our LLM and an embedding model from Huggingface. We will use the  &lt;strong&gt;all-MiniLM-L6-v2&lt;/strong&gt; embedding model, which is perfect for this simple project.&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;llama_index.core&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;VectorStoreIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;llama_index.vector_stores.chroma&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChromaVectorStore&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;llama_index.embeddings.huggingface&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HuggingFaceEmbedding&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;

&lt;span class="n"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama3.1:8b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embed_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HuggingFaceEmbedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sentence-transformers/all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Next, let’s define our Chrome vector database. We will need to initialize a Chrome client, and we will use &lt;code&gt;PersistentClient&lt;/code&gt;, which is a client type that stores vectors and metadata (document text, source, etc.) on your laptop's local disk, similar to how SQLite works. &lt;/p&gt;

&lt;p&gt;Then, we will define a collection. Think of a collection like a set of tables inside the Chroma; it holds your vectors (the numbers) and metadata, allowing the LLM to query them during the retrieval process. &lt;/p&gt;

&lt;p&gt;After the collection is created, we will need to create a vector store that takes the collection as input.&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;chroma_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PersistentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./chroma_db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;chroma_collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chroma_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_or_create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rag_collection&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vector_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChromaVectorStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chroma_collection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chroma_collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Load Documents &amp;amp; Building an Index
&lt;/h2&gt;

&lt;p&gt;After setting up our LlamaIndex and ChromaDB, we need to feed our documents into LlamaIndex. It will load, split, and store the vectors of our documents in the Chroma vector database. &lt;/p&gt;

&lt;p&gt;This guide will send a webpage as a raw document, so you will need to install &lt;strong&gt;&lt;code&gt;llama-index-readers-web&lt;/code&gt;&lt;/strong&gt; crawl a webpage.&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;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;llama&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;readers&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;web&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you install it, import the library, crawl the web page, and send it as a document:&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;llama_index.readers.web&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoupWebReader&lt;/span&gt;

&lt;span class="n"&gt;url&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;https://en.wikipedia.org/wiki/Artificial_intelligence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoupWebReader&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;load_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will need to build an index; the beauty of LlamaIndex lies in this. The index is a super smart wrapper that wraps around the vector store (ChromaDB) and handles the RAG orchestration; chunking, vector embeddings, storing of vector embeddings, and retrieval of data.&lt;/p&gt;

&lt;p&gt;To build the index, you need to pass the documents and the vector store as arguments.&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VectorStoreIndex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vector_store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Ask Questions to Your Documents
&lt;/h2&gt;

&lt;p&gt;Next, let’s build the query engine that takes our questions and gives answers. When you ask a question, the embedding model converts it into a single vector. The vector is used to search against the document’s vector embeddings stored in the Chroma DB. The most similar vector embeddings text chunks are retrieved, and the LLM uses those chunks to generate your answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your question → one embedding vector → nearest document vectors → retrieved text chunks → LLM answer (English).&lt;/strong&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%2Flcxqsguu656m0w0nnpo7.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%2Flcxqsguu656m0w0nnpo7.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To build the &lt;strong&gt;query engine,&lt;/strong&gt; you would need to use the &lt;code&gt;as_query_engine()&lt;/code&gt; method in the Llama Index and send the query to it.&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;query_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_query_engine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query_engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize the document into five bullet points&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your output should look like this:&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%2F8pq94vu1t831ocbplfn7.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%2F8pq94vu1t831ocbplfn7.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-Up
&lt;/h2&gt;

&lt;p&gt;And that is how you can build a simple RAG tool that crawls a webpage and allows you to ask questions about the content of the webpage. Along the way, you saw how to load and index your documents, store vector embeddings in the chroma database, and how LLM answers questions based on your documents. &lt;/p&gt;

&lt;p&gt;With a few lines of Python, you can build a basic retrieval-augmented generation (RAG) solution, but it doesn’t stop here. You can extend this project to search for multiple web pages, load large documents, add a simple web UI using either &lt;a href="https://streamlit.io/" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; or &lt;a href="https://anvil.works/" rel="noopener noreferrer"&gt;Anvil&lt;/a&gt;, or even experiment with different models in Ollama. &lt;/p&gt;

&lt;p&gt;The real fun starts when you can integrate this into your project, so have fun building and extending this project! &lt;/p&gt;

&lt;p&gt;If you would love the video version of this guide, you can find it here: &lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/NoOYYV7_kSc"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Set Up Ollama: Install, Download Models, and Run LLMs Locally</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Mon, 22 Sep 2025 12:18:18 +0000</pubDate>
      <link>https://dev.to/sophyia/how-to-set-up-ollama-install-download-models-and-run-llms-locally-2542</link>
      <guid>https://dev.to/sophyia/how-to-set-up-ollama-install-download-models-and-run-llms-locally-2542</guid>
      <description>&lt;p&gt;Most people hear the term “AI model” and think of something that exists only in the cloud, accessed through an API key, and has a monthly fee. But not all large language models (LLMs) have to live on a cloud, a farm data center. Ollama lets you and me have LLMs on our computers. This gives us the flexibility to have the LLM regardless of internet connection, $0 in the bank, and our chats can be saved on our computers as well. &lt;/p&gt;

&lt;p&gt;In short, &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; is a local LLM runtime; it’s a lightweight environment that lets you download, run, and chat with LLMs locally; It’s like VSCode for LLMs. Although if you want to run an LLM on a container (like Docker), that is also an option. The goal of Ollama is to handle the heavy lifting of executing models and managing memory, so you can focus on using the model rather than wiring it from scratch. &lt;/p&gt;

&lt;p&gt;In this short guide, we will walk through the steps of installing ollama, downloading models, and building with the model in a simple Python project. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To follow alongside this guide, you will need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have a laptop or PC that has 16GB RAM minimum&lt;/li&gt;
&lt;li&gt;Windows 10+ or MacOS 12+&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Installing &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before installing Ollama, ensure you have met the prerequisites above for a smooth experience using Ollama.&lt;/p&gt;

&lt;p&gt;Head over to their website, download the software, and click on Download. You will be redirected to the download page, where you can select an OS and follow the on-screen instructions to install it on your computer.&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%2Fik6991nl8ged2r6mxfrw.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%2Fik6991nl8ged2r6mxfrw.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To confirm you have Ollama installed properly, you can run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the version of Ollama you have installed&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%2Fbxs2ht6h9wfjd0hufrzo.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%2Fbxs2ht6h9wfjd0hufrzo.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Downloading a Model&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Once you have the Ollama software installed, you will need to download a model. Ollama has an awesome list of open-source models to choose from; they also offer embedding models. Head over to their &lt;a href="https://ollama.com/search" rel="noopener noreferrer"&gt;model&lt;/a&gt; section and pick a model. For this guide, we will download the &lt;a href="https://ollama.com/library/deepseek-r1" rel="noopener noreferrer"&gt;&lt;code&gt;deepseek-r1&lt;/code&gt;&lt;/a&gt; model. &lt;/p&gt;

&lt;p&gt;Something to keep in mind when downloading a model is that each model has different versions that have different parameter sizes. A parameter is a representation of data the model was trained on or the data it has learned. Larger parameter sizes mean better response, especially if you want it for complex tasks.&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%2Fx58pkviu05zj3comopy2.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%2Fx58pkviu05zj3comopy2.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will download the lowest parameter size, so click on the size you want to download and copy the command from the page onto your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run deepseek-r1:1.5b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To confirm you have downloaded the model, run the command again, and it should let you send a message to the model. &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%2Fr7cguaaw1itj626wzf22.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%2Fr7cguaaw1itj626wzf22.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This lets you run the model you just downloaded locally, and with this, you can send messages to the model locally. &lt;/p&gt;

&lt;p&gt;This is cool, but it doesn’t stop here. Let’s see how this model works in a project like a simple chatbot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accessing Ollama Endpoint
&lt;/h2&gt;

&lt;p&gt;Ollama has an endpoint that lets you call the downloaded model and interact. This section will feature a simple project built in Python, which is optional, as the endpoint works in any project as long as you have the necessary software downloaded. &lt;/p&gt;

&lt;p&gt;You would need to download &lt;code&gt;requests&lt;/code&gt; library using pip to run the project, do this inside your virtual environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We would need import requests and JSON.&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;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you need to call the Ollama localhost endpoint and define the model name. This endpoint lets you send requests to models you downloaded and get a response.&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;OLLAMA_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434/api/generate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;MODEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deepseek-r1:1.5b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, define functions that would take user input and send it to the model via ollama. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ask_ollama&lt;/code&gt; func takes the user input as a prompt as an argument and sends it as a POST request to the model.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ask_ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;payload&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;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OLLAMA_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No response received from the model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;ConnectionError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: Cannot connect to Ollama. Make sure it&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s running (ollama serve)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exceptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;he&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;404&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;he&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: Model &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; not found. Try running: ollama pull &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;he&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSONDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: Invalid response from Ollama&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the &lt;code&gt;main&lt;/code&gt; func is the main function of the project, which takes the user's input and returns the response from the model. It also tells the user the model sending the request.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Chatbot using &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; via Ollama. Type &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; to quit.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bot:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;ask_ollama&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your output should look like this.&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%2Fzhvxljaqt2y81849jqyk.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%2Fzhvxljaqt2y81849jqyk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;And that is how you can interact with models you download. This lets you have open-source models you can use to experiment with building AI-powered solutions or agents. &lt;/p&gt;

&lt;p&gt;The downside of using a local model rather than a cloud-based model is that it may not always provide the desired results, as they are often trained on a small dataset or lack real-time data, i.e., outdated datasets. Regardless, this is a great way to save costs on interacting with GPT, Claude, etc, for a simple project.&lt;/p&gt;

&lt;p&gt;If you prefer the video version of this guide, you should check out the video below.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/K6lQ9RW5gEc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
    </item>
    <item>
      <title>🔥 Build a RAG Chatbot That Talks to Your Documents Using Python (Gemma + Qdrant + Docling)</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Wed, 06 Aug 2025 08:50:50 +0000</pubDate>
      <link>https://dev.to/sophyia/build-a-rag-chatbot-that-talks-to-your-documents-using-python-gemma-qdrant-docling-3o90</link>
      <guid>https://dev.to/sophyia/build-a-rag-chatbot-that-talks-to-your-documents-using-python-gemma-qdrant-docling-3o90</guid>
      <description>&lt;p&gt;Hey devs 👋&lt;/p&gt;

&lt;p&gt;I just released a full step-by-step video tutorial on how to build a document-chatting AI chatbot using Python and open-source tools.  No heavy setup, just clean and practical.&lt;/p&gt;

&lt;h3&gt;
  
  
  We’re using:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🧠 &lt;a href="https://pypi.org/project/google-genai/" rel="noopener noreferrer"&gt;Gemma&lt;/a&gt; (via Google's Generative AI SDK) for smart responses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📄 &lt;a href="https://github.com/docling-project/docling" rel="noopener noreferrer"&gt;Docling&lt;/a&gt; to parse documents like PDFs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📦 &lt;a href="https://qdrant.tech/" rel="noopener noreferrer"&gt;Qdrant&lt;/a&gt; for fast vector search and retrieval&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🐍 All powered by good old Python&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;strong&gt;Watch the full tutorial here:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://youtu.be/TaLg1yZbS_s?si=gzovkKrlWPZHWc9n" rel="noopener noreferrer"&gt;https://youtu.be/TaLg1yZbS_s?si=gzovkKrlWPZHWc9n&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  🚧 What You’ll Learn
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;How to extract embeddings and store them in Qdrant,&lt;/li&gt;
&lt;li&gt;Parsing docs with Docling and sending queries through Gemma, and&lt;/li&gt;
&lt;li&gt;Building a whole Retrieval-Augmented Generation (RAG) loop, start to finish.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would love to know what you think of the project or what you’d add next. You can also share what other project you would love me to build. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>rag</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Python in DevOps: Automation, Efficiency, and Scalability 🚀</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Sat, 18 Jan 2025 10:22:04 +0000</pubDate>
      <link>https://dev.to/sophyia/python-in-devops-automation-efficiency-and-scalability-2h10</link>
      <guid>https://dev.to/sophyia/python-in-devops-automation-efficiency-and-scalability-2h10</guid>
      <description>&lt;p&gt;Python has become a must-have tool in the DevOps engineer's toolkit. From automating tasks and managing cloud infrastructure to building CI/CD (Continuous Integration and Continuous Delivery) pipelines, Python helps simplify and scale processes. Whether you're new to DevOps or a seasoned professional, learning how Python fits into the DevOps workflow can transform the way you work.&lt;/p&gt;

&lt;p&gt;This article highlights key takeaways from a live stream about Python and DevOps on my YouTube channel with &lt;a href="https://x.com/HowDevelop" rel="noopener noreferrer"&gt;Shivay Lamba&lt;/a&gt;; you can check it out here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Jsz0ooDL8MU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Okay, let’s start learning about cloud and Python 🚀 &lt;/p&gt;

&lt;h2&gt;
  
  
  So, what Is DevOps? 🤔
&lt;/h2&gt;

&lt;p&gt;DevOps combines software development (Dev) and IT operations (Ops) to bridge the gap between building an app or product and deploying said product. It focuses on delivering software to users faster, more reliably, and with little to no stress. The practice revolves around automating repetitive tasks, scaling applications, and ensuring smooth operation at all times.&lt;/p&gt;

&lt;p&gt;By integrating development and operations, DevOps automates the entire product lifecycle—from building and testing to releasing and maintaining. Whether you're managing a small startup's app or a global-scale SaaS platform, DevOps ensures scalability, stability, and efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DevOps is so Important?
&lt;/h2&gt;

&lt;p&gt;In today’s cloud-driven world, the demand for accessible and scalable software keeps rising. Businesses rely on SaaS (Software as a Service) platforms to serve millions of users, which makes automated pipelines, containerized systems, and real-time monitoring super important. DevOps doesn't just make things work—it makes them work at scale!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is Python Perfect for DevOps?
&lt;/h2&gt;

&lt;p&gt;Python's versatility, ease of use, and rich ecosystem make it an ideal programming language for automating tasks, orchestrating processes, and solving challenges in DevOps.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does Python fit into this practice?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Simple and powerful scripting Python allows DevOps engineers to write short, effective scripts to automate processes, such as migrating data or monitoring servers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python is perfect for CI/CD pipelines because SDKs can dynamically replace YAML in building and managing pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Python is widely used in tools and services like AWS (via &lt;a href="https://boto3.amazonaws.com/v1/documentation/api/latest/index.html" rel="noopener noreferrer"&gt;Boto3&lt;/a&gt;), and Kubernetes and it integrates seamlessly with popular DevOps tools. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What does a DevOps workflow look like?
&lt;/h2&gt;

&lt;p&gt;A typical DevOps workflow starts with building software locally and ends with deploying it reliably for users. Here’s a breakdown:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From Development to Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers install dependencies, write APIs, build the software, and test it locally. The software is then hosted on self-managed servers or in the cloud, making it accessible worldwide. Manual tasks like provisioning servers and running tests are automated to speed up delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managing Complexity with Containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Developers now use tools like Docker to bundle applications into containers that can run consistently across environments. Kubernetes then orchestrates these containers, letting teams scale and manage them effortlessly. &lt;/p&gt;

&lt;h2&gt;
  
  
  Tools commonly used in DevOps
&lt;/h2&gt;

&lt;p&gt;DevOps relies on a set of tools for CI/CD (Continuous Integration and Continuous Delivery), infrastructure management, and monitoring. There are: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD Pipelines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.jenkins.io/" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt; and &lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; are go-to tools for automating tasks like testing and deployment. These pipelines ensure that the latest version of your software gets built, tested, and delivered efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Containerization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Containers package applications and their dependencies, ensuring consistency across environments. Using &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; makes it easy to "build once, run anywhere." &lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; manages multiple containers to keep complex apps running smoothly. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; and &lt;a href="https://pulumi.com/" rel="noopener noreferrer"&gt;Pulumi&lt;/a&gt; automate the provisioning of cloud resources. IaC ensures consistency and eliminates manual errors when setting up infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python for CI/CD Pipelines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CI/CD (Continuous Integration and Continuous Deployment) makes the journey from code changes to production so easy. Python shines in this space with its flexibility and power.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Python?
&lt;/h2&gt;

&lt;p&gt;While YAML has been a traditional choice for defining pipelines, Python SDKs like &lt;a href="https://dagger.io/" rel="noopener noreferrer"&gt;Dagger&lt;/a&gt; provide developers with programmatic control. Instead of static files, you can write functions to configure, test, and deploy applications dynamically.&lt;/p&gt;

&lt;p&gt;For example, when creating pipelines with Python, tools like Pulumi and Dagger allow developers to replace repetitive YAML configurations. By writing clear Python scripts, developers can build pipelines, pull builds, or deploy applications. This programmatic approach not only saves time but also reduces the risk of errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code (IaC) with Python&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;IaC changes how we set up infrastructure. Instead of manually setting up servers, you write code to describe the resources you need, and tools take care of the deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python and Terraform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Terraform's declarative configuration lets you define resources like VMs or load balancers, and Python scripts can enhance this by automating workflows, managing variables, and improving efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pulumi: Python-Powered IaC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pulumi extends the power of IaC by allowing you to define infrastructure in Python. Where Terraform uses custom syntax, Pulumi lets Python developers use familiar libraries to manage resources programmatically. For example, creating an AWS container registry (ECR) becomes as simple as writing a Python function. It’s efficient, flexible, and readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python in Cloud Automation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python simplifies cloud management through libraries like Boto3, which allows access to AWS services. Automating repetitive operations like provisioning VMs, managing networks, or migrating databases becomes lightning-fast.&lt;/p&gt;

&lt;p&gt;For example, if you need to handle database migration tasks, moving data between systems like DynamoDB and MongoDB can be challenging. However, a simple Python script can automate this process in minutes, saving you days of manual work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KitOps: Simplifying AI Workloads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kitops.ml/" rel="noopener noreferrer"&gt;KitOps&lt;/a&gt; is an innovative tool designed for MLOps (Machine Learning Operations). AI workloads usually need more complex infrastructure than traditional software, but KitOps makes this easier by offering pre-configured, modular solutions that simplify the deployment, scaling, and management of AI models and pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is KitOps?
&lt;/h2&gt;

&lt;p&gt;KitOps consolidates different components of a machine learning system—models, datasets, and code—into a single "model kit." This container-friendly solution supports lightweight deployment on platforms like Docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Using KitOps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;KitOps provides a single package by combining all AI components into one kit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;KitOps offers incredible flexibility, allowing you to deploy across any infrastructure, from Kubernetes to cloud containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;KitOps is fully compatible with Python, allowing you to write scripts to manage workflows programmatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With KitOps, you don’t just solve infrastructure challenges—you streamline them into an accessible format, making AI deployment as seamless as managing microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is DevOps something a backend engineer should know?
&lt;/h3&gt;

&lt;p&gt;Yes, absolutely. Backend engineers should understand DevOps practices and principles because they enhance their ability to build, maintain, and manage scalable projects. DevOps focuses on collaboration between development and operations, including deploying, testing, and monitoring, which is super important knowledge for any backend engineer. &lt;/p&gt;

&lt;p&gt;While backend engineering involves building APIs, managing databases, and handling business logic, understanding DevOps helps connect the process of writing code to deliver it as a production-ready service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trends in DevOps
&lt;/h2&gt;

&lt;p&gt;The DevOps ecosystem is constantly evolving, getting new tools, challenges, and opportunities, but here are two trends to take note of: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tools like &lt;a href="https://prometheus.io/docs/introduction/overview/" rel="noopener noreferrer"&gt;Prometheus&lt;/a&gt;, &lt;a href="https://grafana.com/" rel="noopener noreferrer"&gt;Grafana&lt;/a&gt;, and &lt;a href="https://www.elastic.co/elastic-stack/" rel="noopener noreferrer"&gt;ELK Stack&lt;/a&gt; are becoming popular as they offer insights into live systems. These tools help monitor metrics such as server usage, request latency, and CPU load to prevent downtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Machine Learning Operations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MLOps elevates DevOps principles to AI workloads. The new frontiers of DevOps are managing large model training jobs, handling GPUs, and automating ML pipelines. Python tools like &lt;a href="https://mlflow.org/" rel="noopener noreferrer"&gt;MLflow&lt;/a&gt; and &lt;a href="https://www.kubeflow.org/" rel="noopener noreferrer"&gt;Kubeflow&lt;/a&gt; make this possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;DevOps is more than deployment—it's about creating efficient systems that scale reliably. Python’s role in this journey is undeniable and unique. It automates tasks, simplifies infrastructure, and makes building pipelines a breeze.&lt;/p&gt;

&lt;p&gt;Whether you're a software engineer learning to deploy your code or an experienced DevOps engineer handling complex systems, Python will always be your reliable tool. DevOps isn't just the future of software development—it's today! And Python is making it easier than ever.&lt;/p&gt;

</description>
      <category>python</category>
      <category>devops</category>
      <category>cloud</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Create a Number-Guessing Game in Python</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Tue, 26 Nov 2024 12:59:21 +0000</pubDate>
      <link>https://dev.to/studio1hq/how-to-create-a-number-guessing-game-in-python-3kbd</link>
      <guid>https://dev.to/studio1hq/how-to-create-a-number-guessing-game-in-python-3kbd</guid>
      <description>&lt;p&gt;Hello there! 👋&lt;/p&gt;

&lt;p&gt;In this guide, you will learn how to build a number-guessing game using basic Python concepts, such as loops, if-else statements, handling inputs, and more. This is inspired by the &lt;a href="https://roadmap.sh/projects/number-guessing-game" rel="noopener noreferrer"&gt;Number guessing game project&lt;/a&gt; in the Roadmap projects section.&lt;/p&gt;

&lt;p&gt;Let’s get started! 😎&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the game’s function
&lt;/h2&gt;

&lt;p&gt;We would need to create a function to handle the generation of the random number for the user to guess using Python’s random module.&lt;/p&gt;

&lt;p&gt;Start by importing the module then create the function using &lt;code&gt;random.randint()&lt;/code&gt; within the module to generate a random number between 1 - 100, this is the number the player has to guess and it will be stored in a variable, &lt;code&gt;number_to_guess&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, set &lt;code&gt;guessed_correctly&lt;/code&gt; var to false to stop the game once the player guessed the right number and set an attempts_limit to make the game more difficult.&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;random&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;number_guessing_game&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attempts_limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;number_to_guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;guessed_correctly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
  &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, use a print statement to welcome your player with some messages and instructions on how to play the game. You can customize this to your preference.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NB: This should be within the function.&lt;/em&gt;&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome to Number guessing game&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I have selected a number from 1-100, can you guess it?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the guessing loop
&lt;/h2&gt;

&lt;p&gt;Next, we need to create the core of the game. This will manage the loop that continues until the player guesses the number correctly or reaches their guess limit.&lt;/p&gt;

&lt;p&gt;Start by using a while loop to increase the attempt count with each try. If the player doesn't guess correctly, they should be given another turn to guess as long as they haven't exceeded their limit.&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="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;attempts_limit&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;guessed_correctly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please add your guess: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, use an if-else statement to compare the player's guess with the random number and provide feedback. If the guess is lower than the correct number, print "too low." If it's too high, print "too high." If it matches the correct number, set &lt;code&gt;guessed_correctly&lt;/code&gt; to True, break the loop, and print a congratulations message.&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;number_to_guess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too low!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number_to_guess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;guessed_correctly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Congratulations, you guessed the number in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; attempts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's add an extra layer of error handling. Users can be unpredictable, and many might try to break your program. For example, if a player decides to use a letter or a decimal number to guess, the program will stop unexpectedly. That's why we need this extra layer.&lt;/p&gt;

&lt;p&gt;Using the try-except block, we can catch such an error. It should only accept whole numbers and should send an error message and stop if the player decides to use something else.&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="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;attempts_limit&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;guessed_correctly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please add your guess: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;number_to_guess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too low!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;number_to_guess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Too high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;guessed_correctly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Congratulations, you guessed the number in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; attempts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Oops! This is not a valid number, please a whole number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that's done, we move on to the final step. If the player runs out of guesses and hasn't guessed the correct number, display a message saying "Game over" and inform them that they are out of guesses.&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;guessed_correctly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are out of guesses, the correct guess was &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number_to_guess&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Game over, Thanks for playing!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing your game
&lt;/h2&gt;

&lt;p&gt;Now that’s all done! Let’s test our game and see if it works. Also, remember to call your function at the bottom of your program to run your program.&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="nf"&gt;number_guessing_game&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fytvfo0x8gpl5yf7kuua3.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%2Fytvfo0x8gpl5yf7kuua3.png" alt=" " width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;And there you have it! A simple yet fun game in Python that you can create as a beginner. I hope this helps you become more comfortable with key programming concepts like loops, conditionals, and random numbers. &lt;/p&gt;

&lt;p&gt;The source code can be found &lt;a href="https://github.com/Sophyia7/Python-Tutorials" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you prefer the video version of this guide, check it out:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/MrTWan2td28"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>F-Strings in Python: What They Are and How to Use Them</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Tue, 27 Aug 2024 17:29:57 +0000</pubDate>
      <link>https://dev.to/studio1hq/f-strings-in-python-what-they-are-and-how-to-use-them-4bk9</link>
      <guid>https://dev.to/studio1hq/f-strings-in-python-what-they-are-and-how-to-use-them-4bk9</guid>
      <description>&lt;p&gt;F-strings (Formatted strings) in Python are an easy way to add expressions in Strings. It was first introduced in &lt;a href="https://docs.python.org/3/whatsnew/3.6.html" rel="noopener noreferrer"&gt;Python 3.6&lt;/a&gt;, making string formatting much more readable and easy.&lt;/p&gt;

&lt;p&gt;In this guide, we will understand f-strings and why they are so much better than the standard formatting method, &lt;code&gt;str.format()&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are F-strings?
&lt;/h2&gt;

&lt;p&gt;F-string is a formatting technique introduced to Python that makes it so much easier to play around with expressions and strings; it is usually defined by the prefix, &lt;code&gt;f&lt;/code&gt;, and using the curly brackets, &lt;code&gt;{}&lt;/code&gt; to format your value or to interpolate.&lt;/p&gt;

&lt;p&gt;The usefulness of this type of string formatting lies in the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Readability:&lt;/strong&gt; F-strings lets you embed expressions directly within the string, which makes it easy to read and understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance:&lt;/strong&gt; F-strings are faster than your average string formatting, like &lt;code&gt;str.format()&lt;/code&gt; or &lt;code&gt;%&lt;/code&gt; because f-strings do not need any overhead of method calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy to Use:&lt;/strong&gt; With f-strings, you do not need to remember different formatting methods or symbols; you only need to prefix your string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; When using f-strings, expressions defined can include any valid Python expression inside the curly brackets an not just variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type safety:&lt;/strong&gt; F-strings automatically convert your expressions to strings, thereby reducing the chance of type conversion errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are a few reasons you should consider f-strings when dealing with formatting. Let's look at some code examples to show how this awesome formatting method works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is str.format() all about?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;str.format()&lt;/code&gt; is the OG formatting method. This method is still useful when you need to reuse your format technique more than once with different values or data types or if you are working on a project that uses Python versions earlier than 3.6. &lt;/p&gt;

&lt;p&gt;Aside from using it with older Python version projects, &lt;code&gt;str.format()&lt;/code&gt; is also useful when dealing with more advanced formatting options like padding, number formatting, alignment, etc, or when formatting dictionaries or objects, making dealing with structured data so easy.&lt;/p&gt;

&lt;p&gt;While this method is useful, it is also very slow because of many function calls when formatting values. &lt;code&gt;str.format()&lt;/code&gt; is just as useful as f-strings, depending on your use case. &lt;/p&gt;

&lt;p&gt;Let's look at a code example of how str.format() works:&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sophia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;

&lt;span class="c1"&gt;# Using str.format() to format the string
&lt;/span&gt;&lt;span class="n"&gt;formatted_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My name is {} and I am {} years old.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your response will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;My name is Sophia and I am 30 years old.

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Basic Syntax of F-string
&lt;/h3&gt;

&lt;p&gt;As stated earlier, f-strings are prefixed f before the string, and inside the string, you add the variable or the expression within curly brackets, &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's a basic syntax that shows how variables can be defined within the f-string.&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sophia&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nigeria&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, I am &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and I am &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greetings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your response will look 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;I am Sophia and I am from Nigeria
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Expressions within F-strings
&lt;/h3&gt;

&lt;p&gt;Now, let’s look at adding expressions inside f-strings. You can also add the expressions within curly brackets.&lt;/p&gt;

&lt;p&gt;Here’s a code example:&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The sum of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your response will look 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;The sum of 10 and 24 is 34
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formatting Numbers within F-strings
&lt;/h3&gt;

&lt;p&gt;Let’s take another look at how we can use f-strings. You can format numbers within the curly braces.&lt;/p&gt;

&lt;p&gt;Here's a code example:&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;500.287018&lt;/span&gt; 

&lt;span class="n"&gt;formatted_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in two decimal places is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;formatted_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your response will look 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;The 500.287018 in two decimal places is 500.29
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using F-strings in multiple lines
&lt;/h3&gt;

&lt;p&gt;Lastly, let’s see if the f-strings can be used in multiple lines using triple quotes.&lt;/p&gt;

&lt;p&gt;Here's a code example:&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mercedes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2009&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Name : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Year the car was made: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your response will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
Name : Mercedes
Year the car was made: 2009

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

&lt;/div&gt;



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

&lt;p&gt;Voila! Congrats you now understand what f-strings are and how this is a great formatting method for your projects.&lt;/p&gt;

&lt;p&gt;In this guide, I focused on formatting strings and numbers, but f-strings can be used to format all data types in Python. &lt;/p&gt;

&lt;p&gt;If you prefer the video version of this guide, check it out:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/k6ZEKNHQIuo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Secure Your Django App with Parameterized Queries</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Fri, 17 May 2024 13:47:38 +0000</pubDate>
      <link>https://dev.to/studio1hq/secure-your-django-app-with-parameterized-queries-212b</link>
      <guid>https://dev.to/studio1hq/secure-your-django-app-with-parameterized-queries-212b</guid>
      <description>&lt;p&gt;Building software goes beyond creating a functional application or solution. You also need to protect user data and privacy, which shows you care not only for the problem your application solves but also for your users. &lt;/p&gt;

&lt;p&gt;In this short guide, we will discuss parameterized queries and how they help improve the security of your django application. &lt;/p&gt;

&lt;p&gt;Let's learn! &lt;/p&gt;

&lt;h2&gt;
  
  
  What are Parameterized Quieres?
&lt;/h2&gt;

&lt;p&gt;Parameterized Quieres are security measures to prevent SQL injection attacks when taking user-generated data. They ensure that the data from the client side is validated and that SQL commands within the user data are separated. &lt;/p&gt;

&lt;p&gt;On the server side, when handling user-generated data, instead of embedding it within an SQL query, you use parameters so the database can tell the difference between code and data and prevent malicious input from being treated as part of the query. &lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Parameterized Queries Work in Django?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/" rel="noopener noreferrer"&gt;Django&lt;/a&gt; follows a Model-View-Controller (MVC) architectural pattern, which allows parameterized queries to be implemented using query parameters. &lt;/p&gt;

&lt;p&gt;Here is how these queries work:&lt;/p&gt;

&lt;h3&gt;
  
  
  Define the query:
&lt;/h3&gt;

&lt;p&gt;In Django, you can easily use the &lt;a href="https://www.geeksforgeeks.org/django-orm-inserting-updating-deleting-data/" rel="noopener noreferrer"&gt;Django Object-Relational Mapping&lt;/a&gt; (ORM) to define the structure of your SQL query. Instead of directly embedding user-generated input within the query, Django ORM lets you use placeholders or parameters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instead of doing this:&lt;/strong&gt;&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;# Directly embedding user input in the query
&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&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_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id = &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code snippet exposes the &lt;code&gt;user_id&lt;/code&gt; because the data is not validated and sanitized. An attacker could manipulate the &lt;code&gt;user_id&lt;/code&gt; input to inject malicious SQL code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do this instead:&lt;/strong&gt;&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;# Using parameterized query with Django ORM
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="c1"&gt;# Define the User model
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Retrieve user data using Django ORM with parameterized query
&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&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_id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code snippet, the Django ORM defines the User model, which represents the structure of the users' table in a database. The &lt;code&gt;get()&lt;/code&gt; method then retrieves a user based on the provided &lt;code&gt;user_id&lt;/code&gt;; the ORM automatically handles the parametrized queries to ensure the user input is properly sanitized and handled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Executing Queries:
&lt;/h3&gt;

&lt;p&gt;When executing queries in Django, Django ORM sends SQL queries to the database to get the results. Using Django ORM ensures safe communication with the database. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instead of using the user input in the query:&lt;/strong&gt;&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_books&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;# Directly using user input in the query
&lt;/span&gt;        &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search_results.html&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;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this snippet, you are directly using the &lt;code&gt;q&lt;/code&gt; parameter in the SQL query, which makes it vulnerable to SQL injections as the &lt;code&gt;q&lt;/code&gt; can be manipulated. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can do this instead:&lt;/strong&gt;&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_books&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;# Using parameterized query
&lt;/span&gt;        &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title__contains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search_results.html&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;books&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, you could use the &lt;code&gt;__contains&lt;/code&gt; lookup within the title field to sanitize the query and ensure the user input is treated as data, not SQL commands. &lt;/p&gt;

&lt;p&gt;Parameterized queries are a crucial security measure in web development, and Django provides built-in support to help developers write secure code and protect their applications from potential vulnerabilities.&lt;/p&gt;

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

&lt;p&gt;Using parameterized queries, Django automatically handles the much-needed security to prevent attacks when taking user inputs and prevents SQL injections. &lt;/p&gt;

&lt;p&gt;Please note that Django ORM automatically handles parameterized queries for you. You do not need to define them manually in your views file, but you would need to define them if you use raw SQL queries when interacting with a database.  &lt;/p&gt;

&lt;p&gt;Did I miss anything while explaining this concept? Let me know in the comments. &lt;/p&gt;

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

</description>
      <category>webdev</category>
      <category>django</category>
      <category>python</category>
      <category>security</category>
    </item>
    <item>
      <title>Cloud Computing Explained</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Fri, 05 Apr 2024 10:50:00 +0000</pubDate>
      <link>https://dev.to/studio1hq/cloud-computing-explained-5cd1</link>
      <guid>https://dev.to/studio1hq/cloud-computing-explained-5cd1</guid>
      <description>&lt;p&gt;Have you ever wondered what cloud computing is? Or why do companies need cloud engineers to ensure the public uses their applications?&lt;/p&gt;

&lt;p&gt;I was curious, too, and started taking the &lt;a href="https://learn.microsoft.com/en-us/collections/31gup6jr1ej0r/?wt.mc_id=studentamb_200507" rel="noopener noreferrer"&gt;Azure Learning path&lt;/a&gt; on the Microsoft Learn platform. Every week, I'll share my key takeaways from the week's learnings, hoping that it may inspire others to learn alongside me. &lt;/p&gt;

&lt;p&gt;Today, let's discuss cloud computing! &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Cloud Computing?
&lt;/h2&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%2Fxyvwsrakavo17yl4yvr9.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%2Fxyvwsrakavo17yl4yvr9.png" alt=" " width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud computing is all about delivering computing services such as compute power, storage, databases, networks, etc., over the internet for users to access and scale their applications without needing a local or physical infrastructure. &lt;/p&gt;

&lt;p&gt;By using cloud computing, users can save costs. Unlike maintaining a physical infrastructure, cloud computing allows users to pay solely for their use. This reduces the need for upfront investments and ongoing maintenance costs, making it an attractive option for users who need a resource allocation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared Responsibility Model
&lt;/h3&gt;

&lt;p&gt;In cloud computing, the shared responsibility model is a framework that divides the responsibilities between cloud service providers and consumers(users). It ensures both parties have set roles and expectations, creating a collaborative and efficient cloud computing environment.&lt;/p&gt;

&lt;p&gt;Under the shared responsibility model, the cloud provider manages the underlying infrastructure, including the physical data center, network, and host. It includes providing security measures, maintaining hardware and software, and ensuring the availability and performance of cloud services.&lt;/p&gt;

&lt;p&gt;On the other hand, the consumer(user) is responsible for managing the cloud services' data, database, and security controls. The consumer also ensures the compliance of applications with regulatory requirements.&lt;/p&gt;

&lt;p&gt;Then, we have what we call a service model, which is selected by the consumer and determines the level of control and responsibility of the cloud infrastructure. &lt;/p&gt;

&lt;p&gt;For instance, in a Platform as a Service (PaaS) model, the provider manages the operating system, network controls, and infrastructure, while the consumer focuses on deploying and managing applications.&lt;/p&gt;

&lt;p&gt;The shared responsibility model enables cloud providers to offer scalable and reliable services while allowing consumers to maintain control over their data and applications. It fosters a cost-efficient collaborative partnership where both parties work together to ensure the success and security of the cloud-based solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Models
&lt;/h2&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%2F4lyebajn1dj10fmxyaxg.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%2F4lyebajn1dj10fmxyaxg.png" alt=" " width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud models are tiers of how users consume and deploy cloud computing services based on their requirements, needs, level of control, etc. In cloud models, there are three tiers: Private, Public, and Hybrid. &lt;/p&gt;

&lt;h3&gt;
  
  
  Private Model
&lt;/h3&gt;

&lt;p&gt;Private models are primarily used by a single entity or organization. The internal IT team of the organization has control over the model and its usage. These models cost more because startups and funded companies often use them. Additionally, all services are purchased upfront, even if they are not immediately required, and the IT team assumes the role of a cloud provider. It's important to note that private models can provide enhanced security and customization, making them a suitable choice for organizations with specific data privacy and control requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public Model
&lt;/h3&gt;

&lt;p&gt;Public models are the cost-effective options for third-party cloud providers like &lt;a href="https://aws.amazon.com/what-is-aws/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us" rel="noopener noreferrer"&gt;Azure&lt;/a&gt;, and &lt;a href="https://cloud.google.com/" rel="noopener noreferrer"&gt;GCP&lt;/a&gt; offer. These models are ideal for hobbyists, students, and developers working on personal or small-scale projects. Unlike private models, users do not need to purchase all the cloud services provided by the cloud provider. Instead, they pay only for the resources they use, making public models a flexible and budget-friendly choice. It's important to note that while public models provide a lower-cost alternative, they may have specific limitations compared to Private models regarding features, customization, and control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid Model
&lt;/h3&gt;

&lt;p&gt;The hybrid cloud model seamlessly blends the features of private and public cloud models, addressing specific organizational needs and preferences. It combines the public cloud's scalability and cost-efficiency with the private cloud's security and control, offering a flexible and secure computing environment. By leveraging the advantages of both models, organizations can optimize their IT infrastructure, enhance security measures, and ensure compliance with regulatory requirements. &lt;/p&gt;

&lt;p&gt;Capital &amp;amp; Operational Expenditure &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%2Fcdgn8ome5ir5q3vmw3xa.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%2Fcdgn8ome5ir5q3vmw3xa.png" alt=" " width="529" height="612"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When comparing cloud models, there are two types of expenses or costs to consider:&lt;/p&gt;

&lt;h3&gt;
  
  
  Capital Expenditure (CapEx)
&lt;/h3&gt;

&lt;p&gt;This cloud cost model is a one-time payment to acquire the necessary resources and services. It includes purchasing software licenses for the private cloud, investing in hardware infrastructure, setting up servers and cooling systems to support the cloud environment, and leasing land for self-managed cloud installations. This upfront investment provides ownership and control over the cloud resources, allowing organizations to control the cloud to their specific needs and requirements.&lt;/p&gt;

&lt;p&gt;The CapEx is most suited for companies and organizations using many cloud resources and will scale their applications soon. Here are some advantages of choosing CapEx as a large company:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Companies that commit to the capital expenditure strategy save costs in the future by bulk purchasing resources.  This may lead to a lower total cost of ownership despite the huge upfront investment. &lt;/li&gt;
&lt;li&gt;Companies with total control and ownership over their hardware and infrastructure can easily customize it to fit their needs and preferences for smoother integration or maximize the compatibility of their cloud ecosystem. &lt;/li&gt;
&lt;li&gt;Companies choosing the capital expenditure approach can safely secure sensitive data in their data centers rather than third-party data centers. They control the encryption standards and the &lt;a href="https://www.investopedia.com/terms/a/audittrail.asp#:~:text=Key%20Takeaways%201%20An%20audit%20trail%20is%20a,suspected%20fraud%20or%20illegal%20financial%20activity.%20More%20items" rel="noopener noreferrer"&gt;auditable trails&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Companies with proprietary infrastructure can easily scale their applications and innovate them in a way their IT team sees fit. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operational Expenditure (OpEx)
&lt;/h3&gt;

&lt;p&gt;The OpEx cloud cost model involves the continuous spending on cloud resources over time. It operates similarly to a pay-as-you-go option, where users only pay for the resources they use. This cost model is commonly associated with cloud computing, allowing users to scale their resource consumption based on their actual usage.&lt;/p&gt;

&lt;p&gt;In the OpEx, there are some advantages of choosing this over the CapEx model, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Users do not need to pay an upfront fee,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users can pay for only the resources they use,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users do not need to pay or be concerned about infrastructure maintenance and&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users can choose when to stop paying for a resource or service.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;To conclude, cloud computing is an easy way to deploy your hobby projects or a small-scale project without considering maintenance costs or buying a data center. Thanks to the cloud providers, you can quickly deploy your to-do app or README generator app and make it accessible for anyone to try and give feedback.&lt;/p&gt;

&lt;p&gt;Did I miss any term? Or did I miss any key takeaway on cloud computing? Please share it in the comments.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>My Journey as a First-Time Speaker at DevFest</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Thu, 04 Apr 2024 10:13:24 +0000</pubDate>
      <link>https://dev.to/sophyia/my-journey-as-a-first-time-speaker-at-devfest-4nnp</link>
      <guid>https://dev.to/sophyia/my-journey-as-a-first-time-speaker-at-devfest-4nnp</guid>
      <description>&lt;p&gt;Hello, there 👋&lt;/p&gt;

&lt;p&gt;On the 11th of November, 2023, I gave a talk at a tech conference with about 100 attendees (whom I barely know). Exciting, right? It wasn't always like that, so let's go behind the scenes of my journey as a first-time speaker and how I overcame small roadblocks.&lt;/p&gt;

&lt;p&gt;I came across the opportunity in the community I Lead, &lt;a href="https://gdsc.community.dev/michael-okpara-university-of-agriculture-umudike/" rel="noopener noreferrer"&gt;Google Developer Student Clubs, MOUAU&lt;/a&gt;. One of the co-organizers posted about the event on the community, &lt;a href="https://gdg.community.dev/events/details/google-gdg-umuahia-presents-devfest-umuahia-2023/" rel="noopener noreferrer"&gt;DevFest Umuahia&lt;/a&gt;, and this is the first time it's happening in the city of Umuahia. I just had to attend! I made sure GDSC MOUAU partnered with GDG Umuahia to promote the event.&lt;/p&gt;

&lt;p&gt;A few weeks later, they announced the call for speakers, and I was skeptical about applying because I hadn't spoken at a large crowd or a tech conference. More so, I didn't have the &lt;em&gt;"public speaker"&lt;/em&gt; vibe. I didn't apply immediately; I had a few conversations with my friends, who all pushed me to apply. They said, &lt;em&gt;"If you get rejected, you won't regret not applying."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next was choosing a topic; I didn't want to sing the same old song every speaker was singing; I wanted my topic to be different and unique but simple. The first week of October, I got an offer to &lt;a href="https://pieces.app/" rel="noopener noreferrer"&gt;join Pieces for Developers&lt;/a&gt; as a Developer Advocate Intern, so I decided to speak about their tool. I have used it for a while, and it is useful to developers, so &lt;em&gt;"why not talk about my experience with Pieces OS?"&lt;/em&gt; I had settled on a topic for my talk, perfect!&lt;/p&gt;

&lt;p&gt;I didn't think the topic through and sent my Call For Proposal within 2 days. This was my mistake. I should have consulted my manager, Cole Stark(CMO), first, but when I told him I would speak at a conference. He connected me with the Lead Developer Advocate, Shivay Lamba, who gave me tips on public speaking, addressing the crowd, and staying calm when speaking. I acknowledged my mistakes and worked on giving a better talk during the event (if I got accepted).&lt;/p&gt;

&lt;p&gt;On the 23rd of October, 2023, I got an email that my talk was accepted. Oh my! I was excited. Someone appreciated my poorly thought topic and wanted to learn about it, and that was it. Any doubt I had just vanished! You know when you applied for a job you didn't qualify for but still got an interview? Yup! That was how I felt.&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%2F818jguyg48qwph0jqfqi.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%2F818jguyg48qwph0jqfqi.png" alt=" " width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next was crafting the perfect slide for my talk. This was the tricky part. I usually get my slides done by AI on &lt;a href="https://gamma.app/" rel="noopener noreferrer"&gt;gamma&lt;/a&gt;, but this wasn't my usual community virtual event or meetup. This was a foreign land, and I needed a PERFECT slide, which was not good enough.&lt;/p&gt;

&lt;p&gt;I reached out to Shivay to get a slide template from the team, and editing it was frustrating; I was blank for 2 days. I had no idea what to write or how to start editing it. Now, this is where I appreciate AI; we talked and came up with a great outline for the slide.&lt;/p&gt;

&lt;p&gt;Also, I conducted a survey on Twitter to learn about the productivity challenges other developers face. This helped me to collect useful information.&lt;/p&gt;

&lt;p&gt;For the next three days, I worked on a 15-page slide presentation based on the outline that my boo, ChatGPT, and I had created. 😂&lt;/p&gt;

&lt;p&gt;I didn't work alone since I would partially discuss a company's product. I contacted my managers, Cole Stark and Shivay Lamba, for assistance so I wouldn't make any mistakes or sell false claims.&lt;/p&gt;

&lt;p&gt;With the help of Cole, Shivay, and AI, I created a great slide and shared it with event organizers. I studied this several times because I was anxious to ensure I got everything right.&lt;/p&gt;

&lt;p&gt;Besides Cole and Shivay, I contacted Leon and Segun to get an outsider's perspective and to see if they understood the slide. They were all helpful. The slide is &lt;a href="https://docs.google.com/presentation/d/1o7F-MQ87FqPsGIxlNf9tnrH7XvOQgx3h/edit?usp=sharing&amp;amp;ouid=112963019252710584877&amp;amp;rtpof=true&amp;amp;sd=true" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡&lt;br&gt;
Pro-tip: If you are trying something new, don't hesitate to ask for help. You can contact your friends, mentors, colleagues, or tech on Twitter. Getting help can save you from a lot of solo "debugging."&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Event (D-day)
&lt;/h2&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%2Fnetophft0i1pzrdavy9c.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%2Fnetophft0i1pzrdavy9c.png" alt=" " width="800" height="1062"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was the day of the event, Saturday, 11th November 2023. I was excited, thrilled, and anxious all at once. I was part of the organizers, so I had to get to the venue at 8 am to set things up.&lt;/p&gt;

&lt;p&gt;I had a chance to talk to some volunteers despite being very shy. I'm working on overcoming my shyness, but it's hard for me to approach you and greet you. It was a bit of a challenge, but I managed to converse with some volunteers, who hyped me. I felt less nervous by the end of the setup.&lt;/p&gt;

&lt;p&gt;The event started at exactly 10:20 am. This was it! My first DevFest event as a speaker. Attendees arrived a bit late, so the event started a bit late. I saw the event agenda by 10 am, and my talk was scheduled for 12:30 am.&lt;/p&gt;

&lt;p&gt;I had to grab something to snack on, so I left around 10:30 am and tried calming my nerves. It did work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡&lt;br&gt;
Pro-tip: If you ever feel nervous about an interview, event, or anything. Take a walk!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After listening to the amazing speakers' talk, I was ready for my talk. My topic was &lt;strong&gt;"Maximizing Developer Productivity with Pieces&lt;/strong&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%2F71g3jjehm1r87h3miwc4.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%2F71g3jjehm1r87h3miwc4.png" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Due to some delay, my talk was shifted to 1:30 pm. At first, I was sad I could not grab the crowd's attention because the attendees were getting tired. I had to remind myself that pushing myself out of my comfort zone was good enough, and if my talk flopped, I would take this as a training phase to improve.&lt;/p&gt;

&lt;p&gt;I got up stage and talked extensively to the best of my knowledge about developer productivity, how to boost productivity as a developer, tools to use, and how Pieces can help boost developer workflow. It was awesome! I wasn't nervous at the end! I had delivered an amazing talk. I did answer a question about Pieces OS, though (and I did that confidently).&lt;/p&gt;

&lt;p&gt;When I returned to my seat, a friend whispered, "You did good. That was awesome". I just knew that if my talk were confusing, it would help a few people at least. I was so surprised by how many people approached me about productivity. We talked, exchanged WhatsApp contacts, and had a fun conversation.&lt;/p&gt;

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

&lt;p&gt;Yeah, this is my experience. I may have missed some details, but I am still excited and proud to be taking this huge step. It's not easy, but it's worth it.&lt;/p&gt;

&lt;p&gt;If you can speak at a conference or local meetups, seize it! It's fun but scary, and you meet more people faster.&lt;/p&gt;

</description>
      <category>techtalks</category>
      <category>publicspeaking</category>
      <category>devrel</category>
    </item>
    <item>
      <title>REST vs. GraphQL: A Detailed Comparison of API Architectures for Developers</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Wed, 27 Mar 2024 10:19:01 +0000</pubDate>
      <link>https://dev.to/studio1hq/rest-vs-graphql-a-detailed-comparison-of-api-architectures-for-developers-1i4k</link>
      <guid>https://dev.to/studio1hq/rest-vs-graphql-a-detailed-comparison-of-api-architectures-for-developers-1i4k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;APIs (Application Programming Interfaces) are the backbone of software development, creating a bridge or a link for applications to communicate and share data with a database or a server seamlessly. While there are so many API architectures, two styles stand out: REST (Representational State Transfer) and GraphQL. Both have merits and demerits, and developers often have difficulty deciding which architecture to explore in their projects.&lt;/p&gt;

&lt;p&gt;This article guide will teach you about these API architectures, their principles, pros, drawbacks, and use cases. By the end of this article, you'll gain insights to make better-informed decisions about API architectures to use in your projects.&lt;/p&gt;

&lt;p&gt;So, let's dive into REST and GraphQL, comparing their strengths and weaknesses to help you make the right choices as a developer!&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding REST APIs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.ibm.com/topics/rest-apis#:~:text=the%20next%20step-,What%20is%20a%20REST%20API%3F,representational%20state%20transfer%20architectural%20style." rel="noopener noreferrer"&gt;REST&lt;/a&gt; is an acronym for REpresentational State Transfer. It is the most common API architectural style used on most servers and websites today. APIs built using the REST style are called RESTful APIs.&lt;/p&gt;

&lt;p&gt;A RESTful API organizes resources into Uniform Resource Identifiers(URIs). Resources are entities or objects that the API represents or interacts with. The URI differentiates resources on a server: it could be a user resource, product resource, or image resource, depending on what you are building on your backend server.&lt;/p&gt;

&lt;p&gt;The resources are ALWAYS grouped in nouns and not verbs - &lt;code&gt;example/com/api/v1/user, not example/com/api/v1/getauser.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why are Resources important?&lt;/strong&gt; If a client wants to retrieve user details from the server, the client sends a request using &lt;a href="https://code.pieces.app/blog/practical-guide-api-methods" rel="noopener noreferrer"&gt;HTTP codes&lt;/a&gt; to the server, targeting the user resources. The resource in question is like a table of users on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases of REST
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Web Services:
&lt;/h3&gt;

&lt;p&gt;REST is widely used To build web services that provide functionalities. Popular examples are payment gateways, weather services, public API, and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile App Services:
&lt;/h3&gt;

&lt;p&gt;REST APIs are used to build mobile applications that access remote servers, making it easy to authenticate users, handle transactions, share content, and much more.&lt;/p&gt;

&lt;h3&gt;
  
  
  IoT servers:
&lt;/h3&gt;

&lt;p&gt;RESTful APIs are used for IoT devices to communicate with remote servers, enabling the servers to share data and receive commands from a centralized network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third-Party Integrations:
&lt;/h3&gt;

&lt;p&gt;RESTful APIs simplify integration between different systems or servers, making them fit for data exchange, cloud service, and enterprise applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security:
&lt;/h3&gt;

&lt;p&gt;RESTful API has a layered REST system, making it scalable and able to handle numerous requests without storing the client state.&lt;/p&gt;

&lt;h3&gt;
  
  
  API Documentation:
&lt;/h3&gt;

&lt;p&gt;RESTful APIs allow clients to request a specific resource or representation of that resource, such as JSON or XML, making it adaptable to different client or end-user needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pros of REST
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;REST is easy to understand and use. It follows a standard HTTP method and is widely used by many.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caching in REST reduces server load and improves performance on the server and client side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST supports lots of tools and libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST endpoints have a clear, predictable structure for API interactions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cons of REST
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;RESTful APIs rely on HTTP, which may result in many connections to multiple sites over time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RESTful APIs may not be suitable for complex activities due to several round trips between client and server and complex server-side logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RESTful API relies on HTTP security, which may not fit all security requirements; this would cause an additional security layer to be added.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RESTful API may be difficult to handle complex queries, searching, and filtering, unlike a query language like GraphQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exploring GraphQL APIs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//graphql.org"&gt;GraphQL&lt;/a&gt; is a Query architectural style language built by &lt;a href="//about.meta.com"&gt;Meta&lt;/a&gt;. It provides the schema of the data of an API and lets the client ask for specific data. It's like a link between the client and the backend servers or services.&lt;/p&gt;

&lt;p&gt;Here are some core concepts in GraphQL:&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema:
&lt;/h3&gt;

&lt;p&gt;GraphQL uses schemas to define the operations or queries that can be performed. The schema acts as an interface between the client and the server to fetch or modify data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types:
&lt;/h3&gt;

&lt;p&gt;GraphQL, like REST, has various data types in an API. These include the developer defines String, Int, Boolean, or custom object types. Each field of a GraphQL type has its type. For example, in your GraphQL, the book_name field of the Book type is a String, and the publish_date field is an Int. Is that clear?&lt;/p&gt;

&lt;h3&gt;
  
  
  Queries:
&lt;/h3&gt;

&lt;p&gt;GraphQL is a query language that lets clients specify the shape and content of the data they want from the server. Clients can use GraphQL to request specific fields and nested data in their queries, and the server will respond with data that matches the structure of the queries. This enables clients to fetch only the needed data, avoiding unnecessary or excessive requests to the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutations:
&lt;/h3&gt;

&lt;p&gt;Mutations are a way of modifying data with GraphQL. Unlike queries, which are mainly for retrieving data from the server, mutations are for creating, updating, or deleting data on the server. Mutations ensure that the data written to the server is predictable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subscriptions:
&lt;/h3&gt;

&lt;p&gt;Subscriptions in GraphQL enable real-time updates such as notifications. Clients can use subscriptions to listen for specific events or actions on the server. When those events or actions occur, the server sends notifications to the subscribed clients.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolvers:
&lt;/h3&gt;

&lt;p&gt;A resolver is a function that connects a schema field to a data source, where it can fetch or modify data according to the query. Resolvers are the bridge between the schema and the data, and they handle the logic for data manipulation and retrieval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features of GraphQL
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GraphQL lets clients request only the data they need and combines multiple queries into a single request, reducing the number of network calls and the load on the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL schema is easy to use and understand. It clearly documents what a GraphQL API can and can't do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL supports real-time updates of data, which makes this API architecture style fit for real-time applications such as chat, live feeds, collaborative tools, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL uses the HTTP methods(POST, GET, PUT, PATCH) but has one single endpoint, making it easy for the API surface. This means only one endpoint can be used to query a resource. It doesn't use URLs to specify resources; it uses schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL sends complex queries using the relationships defined on the schema. Clients can query the schema to understand the available types, fields, and API documentation. This helps in client development.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pros of GraphQL
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GraphQL lets clients request only data they need to reduce overload on the server side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL lets clients define the structure of their response by customizing the request query.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL has a single endpoint that simplifies API management and reduces network requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL schemas support real-time features through subscriptions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Drawbacks of GraphQL
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In GraphQL, writing complex queries may be difficult and requires deep knowledge of data schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL APIs make it harder to cache data since it uses a single point of entry and POST HTTP method to query the server. This prevents the use of the GET HTTP caching method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Poorly implemented GraphQL APIs can expose data and become vulnerable to deceitful queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a basic web app or server that performs CRUD operations, GraphQL is a more costly option.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL has a steep learning curve for developers and clients due to its syntax and implementations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL has fewer tools and libraries than REST.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL queries can cause over-fetching if they are not designed well.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Differences between REST and GraphQL
&lt;/h2&gt;

&lt;p&gt;Data Retrieval and Manipulation:&lt;/p&gt;

&lt;p&gt;A key difference between REST and GraphQL is how they handle data retrieval and manipulation. REST uses predefined endpoints that map to specific resources, while GraphQL allows clients to request specific data and get a response that matches the data structure of the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexibility and Efficiency:
&lt;/h3&gt;

&lt;p&gt;REST handles multiple queries because each entity is accessed by a different endpoint which leads to over-fetching from the client side, while GraphQL has customizable queries that help tailor responses to client needs or requests. It prevents over-fetching or under-fetching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network Requests:
&lt;/h3&gt;

&lt;p&gt;REST has multiple endpoints due to multiple results because each resource is accessed through a separate endpoint, which increases network round-trips, especially when gathering related data from various endpoints, while GraphQL has a single endpoint for all queries, reducing network round-trips. This helps clients query the endpoint targeting the data they need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost &amp;amp; Maintenance:
&lt;/h3&gt;

&lt;p&gt;REST is cost-efficient and easy to maintain since it is a common API architecture style best used for hobby projects or small projects, while GraphQL costs more to use and maintain. It offers fewer tools, so maintaining it would be a challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coding Examples
&lt;/h3&gt;

&lt;p&gt;This is an example of GraphQL (using Node.JS and Apollo Server):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { ApolloServer, gql } = require('apollo-server');

// Query Schema
const typeDefs = gql`
  type Query {
    hello: String
  }
`;

// Endpoints
const resolvers = {
  Query: {
    hello: () =&amp;gt; 'Hello, World!',
  },
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) =&amp;gt; {
  console.log(`Server ready at ${url}`);
});

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

&lt;/div&gt;



&lt;p&gt;This is an example of REST (using Django):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# REST VIEWS
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer

class BookList(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class BookDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

# REST Endpoints
from django.urls import path
from . import views

urlpatterns = [
    path('books/', views.BookList.as_view(), name='book-list'),
    path('books/&amp;lt;int:pk&amp;gt;/', views.BookDetail.as_view(), name='book-detail'),
]

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

&lt;/div&gt;



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

&lt;p&gt;In conclusion, choosing the right API architecture depends on your project's needs and goals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/news/what-is-rest-rest-api-definition-for-beginners/" rel="noopener noreferrer"&gt;REST&lt;/a&gt; and &lt;a href="https://graphql.org/" rel="noopener noreferrer"&gt;GraphQL&lt;/a&gt; have advantages, drawbacks, and use cases for different environments. REST is for simple logic and a more structured architecture, while GraphQL is for a more tailored response and flexible request.&lt;/p&gt;

&lt;p&gt;Now that you've understood the differences, you can make decisions to fit your project's needs.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>api</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Importance of Data Concurrency</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Tue, 13 Feb 2024 15:16:45 +0000</pubDate>
      <link>https://dev.to/sophyia/the-importance-of-data-concurrency-4ne8</link>
      <guid>https://dev.to/sophyia/the-importance-of-data-concurrency-4ne8</guid>
      <description>&lt;p&gt;In the world of data-intensive computing, managing concurrent data access and processing is a significant challenge. As more and more users and processes interact with shared data, problems such as data inconsistencies, conflicts, and performance bottlenecks can arise.&lt;/p&gt;

&lt;p&gt;Understanding the importance of data concurrency and effectively implementing it can help solve these problems and unlock the full potential of data-driven systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Concurrency
&lt;/h2&gt;

&lt;p&gt;In my understanding, data concurrency is letting multiple users interact with shared data at the same time.&lt;/p&gt;

&lt;p&gt;In the tech space, Data concurrency refers to the ability to perform multiple operations or transactions simultaneously on shared data within a computing system. It involves allowing multiple users or processes to access, modify, and interact with the same data concurrently.&lt;/p&gt;

&lt;p&gt;The main objective of data concurrency is to improve system performance, enhance scalability, and maintain data consistency.&lt;/p&gt;

&lt;p&gt;Before we get lost in the technical terms, data transactions. Let’s define it.&lt;/p&gt;

&lt;p&gt;Simply put, data transactions or transactions are database operations such as accessing, modifying, creating, and deleting data within the database.&lt;/p&gt;

&lt;p&gt;In data concurrency, when data is modified, the unsaved data is stored in a temporary log, which we call the Transaction log. This log keeps track of every data before it is saved; once the modified data is saved to the database, it then takes the spot of the original data in the database.&lt;/p&gt;

&lt;p&gt;Types of Data Concurrency&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here are some common types of data concurrency:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read-Write Concurrency&lt;/strong&gt;: In this type of concurrency, multiple processes can read the shared data at once, but only one process can write or modify the data at a time. It improves performance while the integrity of the data is maintained by giving exclusive write access. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write-Write Concurrency&lt;/strong&gt;: This type of concurrency is triggered when multiple processes attempt to write to the shared data simultaneously. It brings about conflicts within the shared data if not managed properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write-Read Concurrency&lt;/strong&gt;: In this type of concurrency, a process updates data while the other processes read the same data. To achieve this, ensure readers do not access partially updated data. Versioning can be of great help.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Read-Read Concurrency&lt;/strong&gt;: In this type of concurrency, multiple processes read the same data simultaneously without the risk of potential or possible conflict within the shared data. This method of concurrency is allowed without the need for any form of data synchronization.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Importance of Data Concurrency
&lt;/h2&gt;

&lt;p&gt;Now that you’ve finally understood what data concurrency is and some types of data concurrency.&lt;/p&gt;

&lt;p&gt;Here are a few reasons why we need data concurrency in a data-driven system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It improves performance on the database&lt;/strong&gt;: Concurrency allows multiple transactions or processes to be executed at once, which maximizes resources and improves the system at large.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It enhances Scalability&lt;/strong&gt;: Concurrency enables a system to handle increased workloads and scale easily. It does this by allowing multiple processes to access and manipulate data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It increases User Experience&lt;/strong&gt;: Concurrency lets multiple users access the database without unnecessary waiting times. It leads to a better user experience, especially when so many users need to access and modify shared data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It improves real-time data processing&lt;/strong&gt;: Concurrency is needed in a system that requires real-time or near-real-time data processing because it allows simultaneous updates to determine timely decision-making.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;It helps maintain consistent data&lt;/strong&gt;: A proper concurrency control maintains data in a multi-user environment by preventing conflicts and ensuring that transactions execute consistently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Database concurrency is vital for efficient, scalable, and reliable systems. It enables concurrent access to data while ensuring data consistency, integrity, and performance, thus supporting the smooth operation of various applications and business processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus
&lt;/h3&gt;

&lt;p&gt;Data Concurrency Control is important in a Database Management System (DBMS) because it ensures data manipulation by several processes without resulting in data inconsistency. This control deals with the interleaved execution of more than one transaction.&lt;/p&gt;

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

&lt;p&gt;In conclusion, data concurrency plays a huge role in modern systems by allowing multiple processes to operate on data simultaneously; it enhances system performance, scalability, and responsiveness. It facilitates real-time data processing, fosters collaboration, and improves the user experience.&lt;/p&gt;

&lt;p&gt;Moreover, data concurrency ensures consistency and prevents conflicts, inconsistencies, and corruption. With the increasing demands of concurrent access and the need for efficient data operations, understanding and implementing effective concurrency control mechanisms have become essential for businesses to thrive in today's data-driven world. Embracing data concurrency empowers organizations to unlock the full potential of their data while delivering enhanced performance, scalability, and reliability across various applications and user interactions.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>database</category>
    </item>
    <item>
      <title>Medusa vs Shopify</title>
      <dc:creator>Sophia Iroegbu</dc:creator>
      <pubDate>Mon, 13 Mar 2023 15:22:41 +0000</pubDate>
      <link>https://dev.to/sophyia/medusa-vs-shopify-1h45</link>
      <guid>https://dev.to/sophyia/medusa-vs-shopify-1h45</guid>
      <description>&lt;p&gt;There are many options for building an ecommerce web app. Two of the most popular options are Medusa and Shopify, which offer a range of strengths and weaknesses.&lt;/p&gt;

&lt;p&gt;This article will explain Medusa and Shopify, comparing their features, prices, and overall capabilities to help you decide which platform is the best fit for your ecommerce needs. Whether you are a small business owner or a large enterprise, this comparison will provide valuable insights into what each platform has to offer and see which suits you best.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://medusajs.com/" rel="noopener noreferrer"&gt;Medusa&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Medusa is an open source composable commerce platform. It has fantastic developer experience with unlimited customizations and plugins for merchants to scale their e-store. It is best suited for business owners and entrepreneurs looking to manage their stores with a development team. &lt;/p&gt;

&lt;p&gt;Medusa offers third-party plugins, including payment integrations, notification integrations, shipping integrations, content management system integration, search integration, analytics, and some plugins that could be used to extend the store's features, such as SendGrid integration which sends SMS and Email notification to buyers. &lt;/p&gt;

&lt;p&gt;In addition, it offers an easy-to-use &lt;a href="https://docs.medusajs.com/admin/quickstart" rel="noopener noreferrer"&gt;admin dashboard&lt;/a&gt; where merchants can easily manage their sales and customer records. Medusa offers a storefront for developers to get started; check it out &lt;a href="https://docs.medusajs.com/starters/nextjs-medusa-starter" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of Using Medusa
&lt;/h3&gt;

&lt;p&gt;Medusa has impressive benefits for those who can use it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility &amp;amp; Customization Options&lt;/strong&gt;: Medusa offers flexibility to integrate your e-store backend with multiple services, from CMS to payment to shipping to analysis and lots more. Such integrations could be used to extend or create new features. Medusa offers complete control of the codebase for developers when building using their platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique Admin Interface&lt;/strong&gt;: Medusa offers an easy-to-use admin interface where merchants can manage their products, customers, and sales records and maintain their e-store. Medusa also offers a ready-to-use &lt;a href="https://github.com/medusajs/nextjs-starter-medusa" rel="noopener noreferrer"&gt;storefront&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Source&lt;/strong&gt;: Medusa is an open source tool; hence, as a developer, you can modify the codebase to suit your business needs and requirements and contribute to the platform to help other developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Medusa is a free and open source platform, meaning businesses do not have to pay license fees or monthly subscription charges. Although, Medusa offers Premium support that has more dedicated support for users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large Ecosystem &amp;amp; Plugins:&lt;/strong&gt;Medusa has ready-to-use plugins with documentation to aid you in integration. Some integrations may include payment, analytics, reporting, search engine, and shipping integrations to your e-store. You can also &lt;a href="https://docs.medusajs.com/advanced/backend/plugins/create" rel="noopener noreferrer"&gt;create your own plugin&lt;/a&gt; to extend an existing feature or create a new feature on the codebase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community-Driven&lt;/strong&gt;: Medusa has a large and active community of developers and merchants (users) who contribute to the platform and provide support and assistance to other users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple Languages&lt;/strong&gt;:  Medusa currently has more than 20 languages to aid international buyers in purchasing goods and products easily. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Disadvantages of Using Medusa
&lt;/h3&gt;

&lt;p&gt;Every tool has drawbacks; here are some of Medusa’s:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Technical Knowledge Required:&lt;/strong&gt; Medusa is an easy tool, and it has friendly guides and documentation, but the downside is that Medusa is created for developers. Hence, it requires technical knowledge to use it. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited Support:&lt;/strong&gt; Medusa is community-driven, meaning businesses won’t have the support a sole proprietary platform would provide, and the support would also be limited. This is because Medusa does not have a dedicated support team for businesses. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited Language Support:&lt;/strong&gt; Medusa does not offer multiple languages, so ecommerce websites built would have a complex getting sales from international buyers. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.shopify.com/" rel="noopener noreferrer"&gt;Shopify&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Shopify is a proprietary, closed source, ecommerce platform allowing individuals and businesses to create and manage online stores. . It is best suited for small business owners, entrepreneurs, and individuals looking to manage their stores with minimal technical experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of using Shopify
&lt;/h3&gt;

&lt;p&gt;Here are some benefits of using Shopify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Easy to Use and Set up&lt;/strong&gt;: Shopify is a tool that has an excellent user-friendly interface for creating ecommerce websites, and it is straightforward to set up with or without a technical team.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large Ecosystem and Plugins&lt;/strong&gt;: Shopify has ready-to-use plugins to extend and add new features to your online store.  Shopify’s plugins aim to manage your store.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple Languages and Currencies:&lt;/strong&gt; Shopify currently has more than 20 languages and currencies to aid international buyers in purchasing goods and products quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust Customer Support&lt;/strong&gt;: Shopify has an impressive and ever-ready-to-help customer support team. Generally, the customer experience when building an e-store on Shopify is bliss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting and Security&lt;/strong&gt;: Shopify provides an easy way to host and secure your online store; this makes it easy for businesses to worry about other aspects of the store as it manages their servers and secures the website.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store Scalability&lt;/strong&gt;:  Shopify can handle a larger volume of customers, orders, and data without crashing. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO-Friendly&lt;/strong&gt;: Shopify provides built-in SEO features such as meta descriptions, meta tags, customized URLs, and header tags. This helps improve the visibility of the store on search engines.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Disadvantages of Using Shopify
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Limited Customization Options&lt;/strong&gt;: Although Shopify offers many plugins, it is closed-source. Hence, customizing the core functions could be tricky. It could make it difficult to create a unique and customer-tailored store. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Although Shopify pricing plans are affordable, the additional options, such as themes, custom developments, etc. cost more and it could quickly add up. This will make it difficult for businesses on a tight budget to leverage the platform and expand its capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited Data Control&lt;/strong&gt;: Shopify has an internal server for hosting ecommerce websites, which means the business or store owners will have little to no control over the data. Also, it will take a lot of work to migrate to another platform in the future.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monolithic Architecture&lt;/strong&gt;: Medusa has the website design, the database, and the checkout process, which are all put together in one big package. Shopify’s monolithic architecture makes it difficult to scale parts of the ecommerce websites without affecting the entire system, this is an issue for businesses with rapid growth or high traffic. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Medusa vs. Shopify
&lt;/h2&gt;

&lt;p&gt;Medusa and Shopify are both ecommerce platforms, but they have different target audiences and are pretty different in terms of features and capabilities. Here are some unique differences between the two platforms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;: Medusa is highly customizable, as it is an open source platform, while Shopify is a closed source platform with limited customization. Medusa customization offers a flexible means for users to develop their plugins to help their online stores and Medusa is better and more flexible in terms of customization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugins &amp;amp; Extensions&lt;/strong&gt;: Shopify has plugins and extensions which businesses can use to extend the platform’s functionality. Medusa has official and community plugins ; businesses can use third-party plugins and extensions or develop custom plugins that are compatible with the platform. Shopify has more plugins than Medusa but not all plugins are free as Medusa’s. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting and Security&lt;/strong&gt;: Shopify takes care of hosting and security for the online store, making it easy for businesses to maintain their stores as they don’t need to manage their servers. Medusa is open source, so businesses are required to manage hosting and security themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store Scalability&lt;/strong&gt;: Medusa has better scalability than Shopify because, as a developer, you can add or develop resources for your store as needed. Shopify controls business infrastructure, so it will be difficult to add or remove resources as you want. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO-Friendly Features&lt;/strong&gt;: Shopify offers built-in SEO features like meta description and tags and allows customization of URLs; this feature helps improve the visibility of the online store on search engines. Medusa is open source, so it offers more flexibility in terms of SEO customization and may require more technical expertise to implement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As an open source ecommerce platform, Medusa offers a high degree of flexibility and customization but less support.  Shopify, a closed-source ecommerce platform, is easy to use and provides a broader range of apps and plugins but less flexibility and control over the codebase.&lt;/p&gt;

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

&lt;p&gt;Medusa and Shopify are two of the leading ecommerce platforms available today, each with advantages and disadvantages. The choice between Medusa and Shopify will depend entirely on the business's unique requirements and team.&lt;/p&gt;

&lt;p&gt;Medusa would be suitable for you if you want a highly customizable and unique frontend experience for your ecommerce websites while Shopify helps with functionalities to manage your ecommerce websites. Both platforms can help businesses create, manage and maintain their online stores. &lt;/p&gt;

&lt;p&gt;Medusa is best for businesses or developers that want a customizable, scalable, and flexible ecommerce platform. &lt;a href="https://medusajs.com/blog/medusa-b2b-part-1/" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is an article that explains how to create a B2B store using Medusa. To begin building with Medusa, &lt;a href="https://docs.medusajs.com/usage/create-medusa-app" rel="noopener noreferrer"&gt;get started here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>programming</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
