<?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: Ernest Kabahima</title>
    <description>The latest articles on DEV Community by Ernest Kabahima (@kabahima).</description>
    <link>https://dev.to/kabahima</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F112234%2Fa0dbe1aa-685f-4b89-9a69-a776dda32d26.png</url>
      <title>DEV Community: Ernest Kabahima</title>
      <link>https://dev.to/kabahima</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kabahima"/>
    <language>en</language>
    <item>
      <title>Guide to Scalable ML Pipelines</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Fri, 31 Jul 2026 17:48:08 +0000</pubDate>
      <link>https://dev.to/kabahima/guide-to-scalable-ml-pipelines-hp7</link>
      <guid>https://dev.to/kabahima/guide-to-scalable-ml-pipelines-hp7</guid>
      <description>&lt;h2&gt;
  
  
  Guide to Scalable ML Pipelines
&lt;/h2&gt;

&lt;p&gt;Machine learning projects often start small: a notebook, a CSV file, and a model that works well enough on one dataset. The trouble begins when the project needs to grow into something repeatable, reliable, and production-ready. A scalable ML pipeline solves that problem by turning one-off experiments into a system that can ingest data, validate it, train models, package them, deploy them, and monitor them over time. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will build that idea step by step. We will start with the core concepts of scalable ML pipelines, then move into practical code labs that show how to build each stage in Python. By the end, you will have a clear picture of how to move from a simple local training script to a more production-friendly machine learning workflow. &lt;a href="https://github.com/RamiKrispin/pydata-ny-ga-workshop/" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an ML pipeline?
&lt;/h2&gt;

&lt;p&gt;An ML pipeline is the sequence of steps that takes raw data and produces a usable machine learning model. In a scalable setup, the pipeline is modular so that each stage can be developed, tested, and run independently instead of being buried inside one large script. That modular design makes the system easier to maintain, easier to debug, and easier to scale when data volume or team size increases. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A typical pipeline includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data ingestion,&lt;/li&gt;
&lt;li&gt;validation and preprocessing,&lt;/li&gt;
&lt;li&gt;feature engineering,&lt;/li&gt;
&lt;li&gt;training and tuning,&lt;/li&gt;
&lt;li&gt;evaluation and approval,&lt;/li&gt;
&lt;li&gt;packaging and deployment,&lt;/li&gt;
&lt;li&gt;monitoring and retraining. &lt;a href="https://medium.com/@lokeshv2403/scaling-machine-learning-pipelines-proven-best-practices-bf8624ec1352" rel="noopener noreferrer"&gt;medium&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important thing to understand is that ML in production is not just about model accuracy. It is also about repeatability, traceability, reliability, and operational safety. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why scalability matters
&lt;/h2&gt;

&lt;p&gt;A pipeline becomes “scalable” when it can handle growing data, more frequent training, more users, and more production complexity without breaking down. That does not always mean huge distributed systems or expensive infrastructure. Sometimes scalability just means the pipeline is organized well enough to grow gradually without being rewritten from scratch. &lt;a href="https://medium.com/@lokeshv2403/scaling-machine-learning-pipelines-proven-best-practices-bf8624ec1352" rel="noopener noreferrer"&gt;medium&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A scalable ML pipeline helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reproduce training runs,&lt;/li&gt;
&lt;li&gt;version data and model artifacts,&lt;/li&gt;
&lt;li&gt;automate repetitive tasks,&lt;/li&gt;
&lt;li&gt;reduce human error,&lt;/li&gt;
&lt;li&gt;detect issues after deployment,&lt;/li&gt;
&lt;li&gt;support future growth. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you skip pipeline design early on, you usually end up with notebooks that cannot be rerun, manual deployment steps, and no way to tell whether the model in production is still behaving correctly. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Core design principles
&lt;/h2&gt;

&lt;p&gt;A strong ML pipeline is built on a few principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modularity
&lt;/h3&gt;

&lt;p&gt;Each stage should do one thing well. Data ingestion should not also train the model. Training should not also manage deployment. This separation makes the workflow easier to test and replace. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reproducibility
&lt;/h3&gt;

&lt;p&gt;You should be able to rerun the pipeline and get the same or nearly the same results using the same code, data version, and dependencies. Reproducibility is one of the biggest reasons to introduce version control, data tracking, and experiment logging. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation
&lt;/h3&gt;

&lt;p&gt;The pipeline should run with as little manual effort as possible. That may mean scheduled jobs, triggers from new data, or CI/CD workflows that test and deploy automatically. &lt;a href="https://github.com/RamiKrispin/pydata-ny-ga-workshop/" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Observability
&lt;/h3&gt;

&lt;p&gt;Once the model is live, you need visibility into performance, latency, errors, and drift. Monitoring is what keeps a “working” model from slowly becoming a bad one. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Governance
&lt;/h3&gt;

&lt;p&gt;For serious production use, you also need approvals, lineage, and audit trails. This matters for regulated industries, internal accountability, and debugging model behavior later. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 1: Build a local training pipeline
&lt;/h2&gt;

&lt;p&gt;The easiest place to start is a single Python script that loads data, validates it, trains a model, and saves the result. This first lab gives you a baseline pipeline you can improve later. &lt;a href="https://vishaluttammane.medium.com/end-to-end-machine-learning-pipeline-design-from-data-ingestion-to-production-grade-systems-24c62e7f2afc" rel="noopener noreferrer"&gt;vishaluttammane.medium&lt;/a&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.model_selection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train_test_split&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.ensemble&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RandomForestClassifier&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;accuracy_score&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;joblib&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&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;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing target column&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isnull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Missing values detected&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&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;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&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="nc"&gt;RandomForestClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&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="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;preds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&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;accuracy:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preds&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;joblib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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;model.pkl&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;This example is simple on purpose. It shows the basic shape of an ML pipeline without hiding the logic behind too many abstractions. You can already see the beginning of a scalable design: data validation, train/test splitting, model training, evaluation, and artifact saving. &lt;a href="https://vishaluttammane.medium.com/end-to-end-machine-learning-pipeline-design-from-data-ingestion-to-production-grade-systems-24c62e7f2afc" rel="noopener noreferrer"&gt;vishaluttammane.medium&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 2: Add preprocessing
&lt;/h2&gt;

&lt;p&gt;In many real projects, raw data is not ready for modeling. Missing values, scale differences, and mixed feature types require preprocessing. A scalable pipeline should handle these transformations in a repeatable way so training and inference use the same logic. &lt;a href="https://medium.com/@lokeshv2403/scaling-machine-learning-pipelines-proven-best-practices-bf8624ec1352" rel="noopener noreferrer"&gt;medium&lt;/a&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.pipeline&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pipeline&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.impute&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SimpleImputer&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StandardScaler&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.compose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ColumnTransformer&lt;/span&gt;

&lt;span class="n"&gt;numeric_features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_dtypes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;include&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;int64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;float64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;

&lt;span class="n"&gt;numeric_transformer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="o"&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;imputer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SimpleImputer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median&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;scaler&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;StandardScaler&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;preprocessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ColumnTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;transformers&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;num&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric_transformer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numeric_features&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="o"&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;preprocessor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preprocessor&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;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RandomForestClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;preds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&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;accuracy:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preds&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version is better because preprocessing is no longer a one-off step hidden inside the training code. It is part of the pipeline itself, which makes the whole workflow easier to reuse and maintain. &lt;a href="https://www.labellerr.com/blog/end-to-end-ml-pipeline/" rel="noopener noreferrer"&gt;labellerr&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 3: Track experiments
&lt;/h2&gt;

&lt;p&gt;A scalable ML team needs to know what happened in each training run. Which data version was used? What accuracy did the model achieve? Which hyperparameters were changed? Without experiment tracking, it becomes very hard to compare models or reproduce results. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;metrics&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;accuracy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;accuracy_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preds&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;metrics.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple version of experiment tracking, but it teaches the right idea: every run should leave behind a record. In larger systems, tools such as MLflow can store runs, parameters, artifacts, and metrics more systematically. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 4: Package the model for serving
&lt;/h2&gt;

&lt;p&gt;Training is only half the story. At some point, the model has to make predictions for real users or systems. The usual pattern is to expose the model behind an API so other software can call it. &lt;a href="https://vishaluttammane.medium.com/end-to-end-machine-learning-pipeline-design-from-data-ingestion-to-production-grade-systems-24c62e7f2afc" rel="noopener noreferrer"&gt;vishaluttammane.medium&lt;/a&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;joblib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&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="n"&gt;joblib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&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.pkl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InputData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@app.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;/predict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;InputData&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prediction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prediction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lab introduces the separation between training and serving. That separation is one of the most important ideas in scalable ML architecture because it allows models to be updated independently of the applications that consume them. &lt;a href="https://medium.com/@lokeshv2403/scaling-machine-learning-pipelines-proven-best-practices-bf8624ec1352" rel="noopener noreferrer"&gt;medium&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 5: Add GitHub Actions CI
&lt;/h2&gt;

&lt;p&gt;Once your pipeline works locally, the next step is automation. GitHub Actions can run your tests every time code is pushed so broken changes do not move further down the pipeline. &lt;a href="https://github.com/RamiKrispin/pydata-ny-ga-workshop/" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ml-ci&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.11"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pytest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the beginning of CI/CD for ML. At first, it may only run unit tests. Over time, you can expand it to include data validation, training checks, model packaging, and deployment steps. &lt;a href="https://github.com/RamiKrispin/pydata-ny-ga-workshop/" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Lab 6: Dockerize the pipeline
&lt;/h2&gt;

&lt;p&gt;Containerization makes the pipeline easier to move between environments. A Docker image packages your Python runtime, dependencies, and application code into a consistent unit that can run on a laptop, server, or cloud platform. &lt;a href="https://codezup.com/streamlining-ml-workflows-ci-cd-mlpops-guide/" rel="noopener noreferrer"&gt;codezup&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11-slim&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["uvicorn", "serve:app", "--host", "0.0.0.0", "--port", "8000"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker is especially helpful when you want the same environment for local testing, CI, and production. It reduces the “works on my machine” problem and gives you a cleaner deployment unit. &lt;a href="https://codezup.com/streamlining-ml-workflows-ci-cd-mlpops-guide/" rel="noopener noreferrer"&gt;codezup&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment and monitoring
&lt;/h2&gt;

&lt;p&gt;Once the model is deployed, the work is not finished. In production, the pipeline should monitor latency, errors, input drift, and prediction drift. When those metrics change, you may need to retrain, rollback, or investigate the data source. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Useful monitoring signals include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API latency,&lt;/li&gt;
&lt;li&gt;failure rate,&lt;/li&gt;
&lt;li&gt;feature distribution drift,&lt;/li&gt;
&lt;li&gt;prediction drift,&lt;/li&gt;
&lt;li&gt;business outcome changes. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your model is not monitored, it may quietly degrade while still appearing to work. That is one of the biggest operational risks in machine learning systems. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices for scalable pipelines
&lt;/h2&gt;

&lt;p&gt;A strong pipeline usually follows a few habits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep steps modular,&lt;/li&gt;
&lt;li&gt;version data and code,&lt;/li&gt;
&lt;li&gt;automate tests and validation,&lt;/li&gt;
&lt;li&gt;log experiments and metrics,&lt;/li&gt;
&lt;li&gt;deploy through controlled release steps,&lt;/li&gt;
&lt;li&gt;monitor after deployment,&lt;/li&gt;
&lt;li&gt;retrain only when needed. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another important practice is to start small. Many teams try to build a fully distributed MLOps platform too early. In practice, it is often better to create a simple, reliable pipeline first and add complexity only when the project truly needs it. &lt;a href="https://medium.com/@lokeshv2403/scaling-machine-learning-pipelines-proven-best-practices-bf8624ec1352" rel="noopener noreferrer"&gt;medium&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;p&gt;The most common mistakes are surprisingly simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;training logic locked inside notebooks,&lt;/li&gt;
&lt;li&gt;no dataset versioning,&lt;/li&gt;
&lt;li&gt;manual model promotion,&lt;/li&gt;
&lt;li&gt;no experiment tracking,&lt;/li&gt;
&lt;li&gt;no production monitoring,&lt;/li&gt;
&lt;li&gt;too much infrastructure too soon. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These mistakes make models hard to reproduce and hard to trust. Scalability is not only about hardware; it is about building a system that stays understandable as it grows. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;A scalable ML pipeline is a structured way to move from raw data to a live, monitored model without losing control of the process. The best way to build one is to start with a simple local workflow, then add preprocessing, tracking, automation, containerization, deployment, and monitoring in stages. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you treat each stage as a small, testable piece, you will end up with a pipeline that is much easier to maintain and much easier to scale. That is the real goal of MLOps: not just building models, but building systems that can keep delivering them reliably over time. &lt;a href="https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5226791" rel="noopener noreferrer"&gt;papers.ssrn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>kubernetes</category>
      <category>mlops</category>
    </item>
    <item>
      <title># Automating Python Deployments to a VPS with GitHub Actions</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Fri, 31 Jul 2026 17:36:13 +0000</pubDate>
      <link>https://dev.to/kabahima/-automating-python-deployments-to-a-vps-with-github-actions-3c4p</link>
      <guid>https://dev.to/kabahima/-automating-python-deployments-to-a-vps-with-github-actions-3c4p</guid>
      <description>&lt;p&gt;If you are learning deployment for the first time, the best path is to start simple: run your Python app on a VPS, keep it alive with &lt;code&gt;systemd&lt;/code&gt;, put Nginx in front of it, and only then automate the whole process with GitHub Actions. This two-part approach makes CI/CD much easier to understand because you first learn how deployment works by hand, then you learn how to automate it. &lt;a href="https://onehost.in/blog/how-to-keep-a-python-app-running-with-systemd/" rel="noopener noreferrer"&gt;onehost&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Deployment is the process of moving your application from development into a live environment where other people can access it. For a beginner, that usually means a VPS, a reverse proxy like Nginx, and a process manager such as &lt;code&gt;systemd&lt;/code&gt; to keep the app running reliably. &lt;a href="https://onehost.in/blog/how-to-keep-a-python-app-running-with-systemd/" rel="noopener noreferrer"&gt;onehost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article is split into two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Part 1&lt;/strong&gt;: Set up the VPS, run the Python app, configure Nginx, and keep the system live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Part 2&lt;/strong&gt;: Add GitHub Actions to automate testing and deployment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 1: VPS and Nginx Lab
&lt;/h2&gt;

&lt;p&gt;The goal in Part 1 is to get a working production-style setup without automation first. Once you understand this manual setup, CI/CD in Part 2 will make a lot more sense. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Choose your Python app
&lt;/h3&gt;

&lt;p&gt;Start with a simple Python web app using Flask, FastAPI, or Django. Keep the app small so you can focus on deployment rather than application complexity, and make sure it has a health endpoint such as &lt;code&gt;/health&lt;/code&gt; so you can test whether it is alive after deployment.&lt;/p&gt;

&lt;p&gt;A minimal app should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;respond to web requests,&lt;/li&gt;
&lt;li&gt;read environment variables,&lt;/li&gt;
&lt;li&gt;have clearly defined dependencies,&lt;/li&gt;
&lt;li&gt;expose a health check route.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Prepare the VPS
&lt;/h3&gt;

&lt;p&gt;Use an Ubuntu VPS for the simplest beginner-friendly setup. Connect with SSH, install Python and Git, and create a dedicated user for deployment rather than using the root account.&lt;/p&gt;

&lt;p&gt;A basic VPS setup usually includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;installing Python,&lt;/li&gt;
&lt;li&gt;installing &lt;code&gt;git&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;creating a virtual environment,&lt;/li&gt;
&lt;li&gt;opening only the ports you need,&lt;/li&gt;
&lt;li&gt;configuring SSH access securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Keep the app live with systemd
&lt;/h3&gt;

&lt;p&gt;If you run &lt;code&gt;python app.py&lt;/code&gt; manually in a terminal, the app stops when you disconnect or reboot the server. &lt;code&gt;systemd&lt;/code&gt; fixes this by running the app as a service, starting it automatically on boot, and restarting it if it crashes. &lt;a href="https://onehost.in/blog/how-to-keep-a-python-app-running-with-systemd/" rel="noopener noreferrer"&gt;onehost&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A typical &lt;code&gt;systemd&lt;/code&gt; service gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatic start on boot,&lt;/li&gt;
&lt;li&gt;automatic restart on failure,&lt;/li&gt;
&lt;li&gt;centralized logs,&lt;/li&gt;
&lt;li&gt;easier service management with &lt;code&gt;systemctl&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the most important beginner deployment lessons because it turns a fragile script into a real service.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Put Nginx in front
&lt;/h3&gt;

&lt;p&gt;Nginx acts as a reverse proxy: it receives traffic from the internet and forwards requests to your Python app running on localhost. This is the standard way to expose a web app on a VPS because it keeps the app private while Nginx handles public traffic on ports 80 and 443. &lt;a href="https://space-node.net/blog/nginx-ssl-reverse-proxy-vps-2026" rel="noopener noreferrer"&gt;space-node&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why use Nginx?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It handles domain routing.&lt;/li&gt;
&lt;li&gt;It can terminate HTTPS.&lt;/li&gt;
&lt;li&gt;It can proxy traffic cleanly to your app.&lt;/li&gt;
&lt;li&gt;It keeps your Python app off the public internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, your app listens on something like &lt;code&gt;127.0.0.1:8000&lt;/code&gt;, and Nginx listens on your public domain or IP address.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Test the manual setup
&lt;/h3&gt;

&lt;p&gt;Before moving to automation, make sure the manual setup is stable.&lt;/p&gt;

&lt;p&gt;Check that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the app starts correctly,&lt;/li&gt;
&lt;li&gt;the app survives a restart,&lt;/li&gt;
&lt;li&gt;Nginx routes requests properly,&lt;/li&gt;
&lt;li&gt;the health endpoint works,&lt;/li&gt;
&lt;li&gt;logs are readable through &lt;code&gt;journalctl&lt;/code&gt; or your app logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, you have a real production-style deployment, even though it is not automated yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: CI/CD Lab
&lt;/h2&gt;

&lt;p&gt;Now that the app is running manually, you can automate the process with GitHub Actions. The goal here is to make every push to GitHub test the app and then deploy it to the VPS safely. &lt;a href="https://www.advantch.com/blog/how-to-deploy-your-python-app-to-a-virtual-private-server-vps-using-github-actions" rel="noopener noreferrer"&gt;advantch&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Understand GitHub Actions
&lt;/h3&gt;

&lt;p&gt;GitHub Actions is GitHub’s automation system. It runs workflows on events such as pushes, pull requests, or manual triggers, and those workflows can install dependencies, run tests, and deploy code.&lt;/p&gt;

&lt;p&gt;A workflow usually has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a trigger,&lt;/li&gt;
&lt;li&gt;one or more jobs,&lt;/li&gt;
&lt;li&gt;steps inside each job.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Add build and test steps
&lt;/h3&gt;

&lt;p&gt;Start automation with testing, not deployment. Your workflow should install Python dependencies and run tests so bad code never reaches the server.&lt;/p&gt;

&lt;p&gt;Typical CI steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checkout the repository,&lt;/li&gt;
&lt;li&gt;set up Python,&lt;/li&gt;
&lt;li&gt;install dependencies,&lt;/li&gt;
&lt;li&gt;run unit tests,&lt;/li&gt;
&lt;li&gt;run lint checks if you have them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If tests fail, deployment should stop immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Deploy to the VPS
&lt;/h3&gt;

&lt;p&gt;Once testing passes, GitHub Actions can connect to your VPS over SSH and deploy the new code. The workflow can either pull the latest commit on the server or send a build artifact, depending on how your app is structured.&lt;/p&gt;

&lt;p&gt;A simple deployment flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Push code to &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;GitHub Actions runs tests.&lt;/li&gt;
&lt;li&gt;If tests pass, it SSHs into the VPS.&lt;/li&gt;
&lt;li&gt;The server updates the code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemd&lt;/code&gt; restarts the app.&lt;/li&gt;
&lt;li&gt;Nginx continues serving traffic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This pattern is easy to understand and works well for small to medium Python apps. &lt;/p&gt;

&lt;h3&gt;
  
  
  4. Store secrets safely
&lt;/h3&gt;

&lt;p&gt;Never hardcode passwords or private keys in your repository. Use GitHub Secrets for SSH keys, server addresses, and other sensitive values. This keeps your pipeline secure and prevents credentials from leaking into source control.&lt;/p&gt;

&lt;p&gt;Good secret management means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no private keys in Git,&lt;/li&gt;
&lt;li&gt;no passwords in code,&lt;/li&gt;
&lt;li&gt;minimal access on the VPS,&lt;/li&gt;
&lt;li&gt;clear separation between app config and source code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Keep the system live during deploys
&lt;/h3&gt;

&lt;p&gt;A good deployment does not just copy files; it keeps the service available as much as possible. &lt;code&gt;systemd&lt;/code&gt; helps by restarting the app after an update, and Nginx keeps the public side stable while the backend is refreshed. &lt;/p&gt;

&lt;p&gt;For beginners, the simplest practical target is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;short downtime or near-zero downtime,&lt;/li&gt;
&lt;li&gt;a fast restart,&lt;/li&gt;
&lt;li&gt;a health check after deployment,&lt;/li&gt;
&lt;li&gt;logs ready for troubleshooting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Add production safety
&lt;/h3&gt;

&lt;p&gt;Once deployment works, make it safer.&lt;/p&gt;

&lt;p&gt;Add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rollback steps,&lt;/li&gt;
&lt;li&gt;health checks,&lt;/li&gt;
&lt;li&gt;deployment logs,&lt;/li&gt;
&lt;li&gt;branch protection,&lt;/li&gt;
&lt;li&gt;staging before production if possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not just “it deploys,” but “it deploys reliably.”&lt;/p&gt;




&lt;h2&gt;
  
  
  Crossroads: Docker, Terraform, and Kubernetes
&lt;/h2&gt;

&lt;p&gt;After you understand the VPS workflow, you reach a crossroads where you decide whether to stay simple or move into more advanced deployment tooling. This is where Docker, Terraform, and Kubernetes become relevant. &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/infrastructure-as-code" rel="noopener noreferrer"&gt;developer.hashicorp&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker
&lt;/h3&gt;

&lt;p&gt;Docker packages your app and dependencies into a container, making the runtime more consistent across machines. This helps reduce environment drift and makes the app easier to move between local development, testing, and production.&lt;/p&gt;

&lt;p&gt;Use Docker when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;environment consistency matters,&lt;/li&gt;
&lt;li&gt;you want portable builds,&lt;/li&gt;
&lt;li&gt;your app depends on multiple services.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Terraform
&lt;/h3&gt;

&lt;p&gt;Terraform lets you define infrastructure as code, so you can provision and manage infrastructure with configuration files instead of clicking through a cloud console. It is useful when you want your VPS, networking, and cloud resources to be reproducible and version-controlled. &lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/infrastructure-as-code" rel="noopener noreferrer"&gt;developer.hashicorp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use Terraform when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;infrastructure changes often,&lt;/li&gt;
&lt;li&gt;you want repeatable cloud provisioning,&lt;/li&gt;
&lt;li&gt;your team needs auditable infrastructure changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Kubernetes
&lt;/h3&gt;

&lt;p&gt;Kubernetes is an orchestration platform for running containerized apps at scale. It is powerful, but it also adds a lot of complexity, so it is usually not the best starting point for a beginner with a single Python app and one VPS. &lt;a href="https://docs.docker.com/guides/python/deploy/" rel="noopener noreferrer"&gt;docs.docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use Kubernetes when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have multiple services,&lt;/li&gt;
&lt;li&gt;you need auto-scaling or advanced orchestration,&lt;/li&gt;
&lt;li&gt;you are ready for the operational overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other tools
&lt;/h3&gt;

&lt;p&gt;Other useful tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker Compose&lt;/strong&gt; for multi-container apps on one server,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ansible&lt;/strong&gt; for server configuration,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cloud-init&lt;/strong&gt; for server bootstrap automation,&lt;/li&gt;
&lt;li&gt;managed cloud platforms when you want less server maintenance.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Choosing the right path
&lt;/h2&gt;

&lt;p&gt;For most beginners, the best path is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the Python app.&lt;/li&gt;
&lt;li&gt;Deploy it to a VPS.&lt;/li&gt;
&lt;li&gt;Run it with &lt;code&gt;systemd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Put Nginx in front.&lt;/li&gt;
&lt;li&gt;Add GitHub Actions for CI/CD.&lt;/li&gt;
&lt;li&gt;Only then explore Docker, Terraform, or Kubernetes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This order works because each step builds on the one before it. You learn the fundamentals first, then you add tooling only when you have a real need.&lt;/p&gt;




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

&lt;p&gt;The simplest reliable deployment system is often the best one to start with. For a beginner, Python + VPS + &lt;code&gt;systemd&lt;/code&gt; + Nginx gives you the foundation, and GitHub Actions adds automation once you understand the manual process.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>deployment</category>
      <category>devops</category>
      <category>python</category>
    </item>
    <item>
      <title># 🛠️ Fixing “No Valid Android SDK Root Found” Error in WSL (Ubuntu)</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Thu, 13 Nov 2025 17:05:35 +0000</pubDate>
      <link>https://dev.to/kabahima/-fixing-no-valid-android-sdk-root-found-error-in-wsl-ubuntu-361o</link>
      <guid>https://dev.to/kabahima/-fixing-no-valid-android-sdk-root-found-error-in-wsl-ubuntu-361o</guid>
      <description>&lt;p&gt;When developing Android or Ionic apps inside &lt;strong&gt;WSL (Windows Subsystem for Linux)&lt;/strong&gt;, you might hit this frustrating error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ERROR] Error while getting native targets for android: No valid Android SDK root found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This usually happens when running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev:android
ionic cap run android
ionic cordova run android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t worry — it’s a common issue when working across Windows and WSL.&lt;br&gt;
Here’s what causes it and how to fix it cleanly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why This Happens
&lt;/h2&gt;

&lt;p&gt;There are two main culprits behind this error:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. WSL Can’t See the Android SDK
&lt;/h3&gt;

&lt;p&gt;Your Android SDK is installed on &lt;strong&gt;Windows&lt;/strong&gt;, not inside WSL.&lt;br&gt;
Typically, it lives here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Users\&amp;lt;Your-Username&amp;gt;\AppData\Local\Android\Sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In WSL, that same folder appears under:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/mnt/c/Users/&amp;lt;Your-Username&amp;gt;/AppData/Local/Android/Sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if your Windows username contains a &lt;strong&gt;space&lt;/strong&gt; (like &lt;code&gt;FIRST  NAME&lt;/code&gt;), Linux treats it as two separate paths unless you &lt;strong&gt;quote it properly&lt;/strong&gt;.&lt;br&gt;
That’s why the Android build tools inside WSL can’t find your SDK.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Missing Android Command-Line Tools
&lt;/h3&gt;

&lt;p&gt;Even if the SDK path is correct, you might still lack the essential Android tools (&lt;code&gt;sdkmanager&lt;/code&gt;, &lt;code&gt;avdmanager&lt;/code&gt;, etc.) that WSL needs to manage devices and builds.&lt;br&gt;
Without these, the SDK can’t be validated — hence the “no valid SDK root” message.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step-by-Step Fix
&lt;/h2&gt;

&lt;p&gt;Follow these steps in your WSL terminal 👇&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Set Correct Android SDK Paths
&lt;/h3&gt;

&lt;p&gt;Run these commands (replace your username if needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export ANDROID_HOME="/mnt/c/Users/Ernest Kabahima/AppData/Local/Android/Sdk"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export ANDROID_SDK_ROOT="$ANDROID_HOME"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PATH="$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$ANDROID_HOME&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/mnt/c/Users/Ernest Kabahima/AppData/Local/Android/Sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Android Command-Line Tools
&lt;/h3&gt;

&lt;p&gt;If &lt;code&gt;sdkmanager&lt;/code&gt; isn’t recognized, install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;google-android-cmdline-tools-11.0-installer &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This installs the latest command-line tools inside &lt;code&gt;/usr/lib/android-sdk/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Link WSL Tools to Your Windows SDK
&lt;/h3&gt;

&lt;p&gt;Make sure your Windows SDK has the proper structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"/mnt/c/Users/Ernest Kabahima/AppData/Local/Android/Sdk/cmdline-tools/latest"&lt;/span&gt;
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /usr/lib/android-sdk/cmdline-tools/&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="s2"&gt;"/mnt/c/Users/Ernest Kabahima/AppData/Local/Android/Sdk/cmdline-tools/latest/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now WSL and Windows share the same SDK tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Accept SDK Licenses
&lt;/h3&gt;

&lt;p&gt;This ensures the tools can run properly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;yes&lt;/span&gt; | sdkmanager &lt;span class="nt"&gt;--licenses&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Verify Your Setup
&lt;/h3&gt;

&lt;p&gt;Check versions and SDK content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adb version
sdkmanager &lt;span class="nt"&gt;--list&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both work, your SDK is ready.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Run Your Project Again
&lt;/h3&gt;

&lt;p&gt;Now re-run your dev command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev:android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you still get a &lt;code&gt;native-run&lt;/code&gt; error, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev:android &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--no-native-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells the system to fall back to Cordova’s runner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;No valid Android SDK root&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WSL can’t find Windows SDK&lt;/td&gt;
&lt;td&gt;Use quoted path &lt;code&gt;/mnt/c/...&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;sdkmanager not found&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Missing SDK tools&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sudo apt install google-android-cmdline-tools-11.0-installer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;native-run errors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Emulator or device not found&lt;/td&gt;
&lt;td&gt;Start emulator or use &lt;code&gt;--no-native-run&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Bonus Tip: Avoid Spaces in SDK Paths
&lt;/h2&gt;

&lt;p&gt;If possible, move your Android SDK to a path &lt;strong&gt;without spaces&lt;/strong&gt;, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Android\Sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then update your environment variables accordingly.&lt;br&gt;
This avoids quoting issues entirely and makes WSL integration smoother.&lt;/p&gt;




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

&lt;p&gt;This issue boils down to two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WSL not interpreting Windows paths with spaces&lt;/li&gt;
&lt;li&gt;Missing command-line tools for Android builds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By setting your environment variables properly and installing the SDK tools, you can run and build Android apps inside WSL just like a native Linux environment — no more “No valid Android SDK root” headaches.&lt;/p&gt;

</description>
      <category>cordova</category>
      <category>ionic</category>
      <category>linux</category>
    </item>
    <item>
      <title>"Exploring Top MLOps Platforms for Efficient Machine Learning Lifecycle Management"</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Fri, 31 Jan 2025 14:50:58 +0000</pubDate>
      <link>https://dev.to/kabahima/exploring-top-mlops-platforms-for-efficient-machine-learning-lifecycle-management-1knl</link>
      <guid>https://dev.to/kabahima/exploring-top-mlops-platforms-for-efficient-machine-learning-lifecycle-management-1knl</guid>
      <description>&lt;p&gt;These platforms help with automating and streamlining various stages of the machine learning lifecycle, from development to deployment and monitoring, and many integrate with popular cloud services like AWS, Google Cloud, and Azure. The choice of platform depends on specific needs such as scalability, integration with existing tools, and the complexity of the machine learning operations.&lt;/p&gt;

&lt;p&gt;There are several MLOps platforms available, each catering to different aspects of machine learning lifecycle management, such as model development, deployment, monitoring, and governance. Here are some of the popular MLOps platforms:&lt;/p&gt;

&lt;h2&gt;
  
  
  Kubeflow
&lt;/h2&gt;

&lt;p&gt;An open-source platform designed to facilitate the development, deployment, and monitoring of machine learning models on Kubernetes.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Supports end-to-end pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model training, serving, and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built on Kubernetes for scalability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MLflow
&lt;/h2&gt;

&lt;p&gt;An open-source platform for managing the complete machine learning lifecycle, including experimentation, reproducibility, and deployment.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experiment tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model versioning and packaging.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  TensorFlow Extended (TFX)
&lt;/h2&gt;

&lt;p&gt;An end-to-end platform for deploying production machine learning pipelines using TensorFlow.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Model training, evaluation, and deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data validation and transformation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model monitoring and versioning.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Seldon
&lt;/h2&gt;

&lt;p&gt;A platform focused on deploying, monitoring, and managing machine learning models at scale.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Model deployment and scaling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model monitoring and explainability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrates with Kubernetes and supports many model types.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Amazon SageMaker
&lt;/h2&gt;

&lt;p&gt;A fully managed service by AWS that provides an integrated environment for developing, training, and deploying machine learning models.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Managed Jupyter notebooks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated hyperparameter tuning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End-to-end deployment and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Azure ML
&lt;/h2&gt;

&lt;p&gt;A cloud-based platform from Microsoft Azure for building, training, and deploying machine learning models.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experiment tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated ML and hyperparameter tuning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model deployment and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Google AI Platform
&lt;/h2&gt;

&lt;p&gt;A cloud-based machine learning platform by Google that helps with building and deploying models at scale.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Integration with TensorFlow and other ML frameworks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model deployment and monitoring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated machine learning.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Databricks
&lt;/h2&gt;

&lt;p&gt;A cloud platform that provides collaborative notebooks and unified analytics for data engineering and machine learning.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Managed Spark clusters for scalable ML.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collaborative notebooks for team development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration with MLflow for managing models.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Comet.ml&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An experiment tracking platform for machine learning, focused on collaboration, model versioning, and visualization.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tracking and visualizing experiments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model and dataset versioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collaboration for teams.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Weights &amp;amp; Biases (W&amp;amp;B)
&lt;/h2&gt;

&lt;p&gt;A platform for tracking experiments, visualizing results, and managing datasets and models.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experiment tracking and visualization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model versioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collaborative team features.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  DataRobot
&lt;/h2&gt;

&lt;p&gt;An enterprise AI platform that automates machine learning and helps with model deployment and monitoring.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automated model training and selection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model monitoring and deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interpretability and explainability features.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MLflow
&lt;/h2&gt;

&lt;p&gt;A popular open-source platform for managing the machine learning lifecycle, especially for tracking experiments and managing models.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Experiment tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Model packaging and versioning.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Model deployment and serving.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flyte
&lt;/h2&gt;

&lt;p&gt;An open-source workflow orchestration platform that supports building, deploying, and managing ML workflows.&lt;/p&gt;

&lt;p&gt;Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Supports batch and streaming data workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalable orchestration and execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in integrations with ML frameworks like TensorFlow and PyTorch.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pachyderm
&lt;/h2&gt;

&lt;p&gt;An open-source data versioning platform designed for machine learning workflows.&lt;br&gt;
Key Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Data lineage tracking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalable ML pipelines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Version-controlled data for reproducibility.&lt;/p&gt;
&lt;h2&gt;
  
  
  Polyaxon
&lt;/h2&gt;

&lt;p&gt;A platform for building, training, and deploying machine learning and deep learning models.&lt;br&gt;
Key Features:&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Experiment tracking and model versioning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalable deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kubernetes-native architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mlops</category>
      <category>kubernetes</category>
      <category>ubuntu</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Safeguard Against Disruptions from Data Schema Changes</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Fri, 31 Jan 2025 14:00:41 +0000</pubDate>
      <link>https://dev.to/kabahima/how-to-safeguard-against-disruptions-from-data-schema-changes-41ni</link>
      <guid>https://dev.to/kabahima/how-to-safeguard-against-disruptions-from-data-schema-changes-41ni</guid>
      <description>&lt;p&gt;Data schema changes are inevitable as applications grow and evolve. However, if not handled properly, they can lead to broken functionality, data loss, or downtime. To prevent these disruptions, developers must follow a structured approach that ensures seamless transitions while maintaining data integrity. Below, we discuss key strategies to safeguard against disruptions caused by schema changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Migrations Instead of Direct Changes
&lt;/h2&gt;

&lt;p&gt;Making direct changes to a live database, such as adding or removing columns manually, can be risky. Instead, developers should use database migration tools that provide a structured way to apply and track schema changes. Some popular migration tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Alembic (for SQLAlchemy/Python)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flyway (for various databases including PostgreSQL and MySQL)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Liquibase (for version-controlled database changes)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Knex.js (for Node.js applications)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools allow for version control, rollback options, and a safer way to update the database without disrupting the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make Schema Changes Backward-Compatible
&lt;/h2&gt;

&lt;p&gt;Ensuring backward compatibility is crucial when updating a database, especially in production environments. Backward-compatible changes allow existing functionalities to continue working while transitioning to the new schema. Some key practices include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Adding new fields without removing old ones immediately to prevent breaking queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using default values when adding new columns to avoid unexpected NULL values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gradually phasing out deprecated fields only after all application parts are updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement API and Database Versioning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versioning ensures different parts of the system remain compatible during schema transitions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database versioning: Use version numbers or timestamps for database migrations to track and roll back changes if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API versioning: Create new API versions (e.g., /v2/products) instead of modifying existing ones immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grace periods: Allow clients time to adapt before deprecating older versions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automate Testing &amp;amp; Schema Validation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing prevents unexpected errors before rolling out schema changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Schema validation tools (e.g., JSON Schema) ensure data adheres to the expected format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated database tests in CI/CD pipelines detect issues before deployment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load testing helps assess performance impact from schema modifications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Maintain Database Backups &amp;amp; Audits
&lt;/h2&gt;

&lt;p&gt;Despite careful planning, things can go wrong. Regular backups and audit logs help mitigate risks.Perform full backups before applying schema modifications for quick recovery.&lt;/p&gt;

&lt;p&gt;Use point-in-time recovery for databases that support it. Maintain an audit trail to track schema changes and modifications.&lt;/p&gt;

&lt;p&gt;Implement Feature Flags for Schema-Dependent Features : Feature flags allow gradual rollout of new database features instead of immediate deployment.&lt;/p&gt;

&lt;p&gt;Use feature toggles to enable or disable schema-dependent features dynamically.&lt;/p&gt;

&lt;p&gt;Test schema updates in a staging environment before full deployment.&lt;/p&gt;

&lt;p&gt;Roll back changes easily by disabling the feature flag rather than modifying the database directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Document Schema Changes Clearly
&lt;/h2&gt;

&lt;p&gt;A lack of documentation can lead to confusion and errors when working with evolving schemas. To ensure team members understand the changes:&lt;/p&gt;

&lt;p&gt;Maintain a schema changelog recording each modification, its purpose, and impact.&lt;/p&gt;

&lt;p&gt;Update API and database documentation to reflect new structures.&lt;/p&gt;

&lt;p&gt;Communicate changes with stakeholders to avoid misalignment.&lt;/p&gt;

&lt;p&gt;Test Schema Changes in a Staging Environment&lt;/p&gt;

&lt;p&gt;Before deploying schema changes to production, always test them in a staging environment that mirrors production.&lt;/p&gt;

&lt;p&gt;Replicate real-world data scenarios to assess potential impacts.&lt;/p&gt;

&lt;p&gt;Ensure application compatibility with the new schema before final deployment.&lt;/p&gt;

&lt;p&gt;Monitor query performance to detect slow queries introduced by schema modifications.&lt;/p&gt;

&lt;p&gt;Overcoming Resistance to Change in Database Scalability&lt;/p&gt;

&lt;p&gt;Resistance to change is common when implementing database scalability improvements. However, ensuring a smooth transition requires effective strategies:&lt;/p&gt;

&lt;p&gt;Communicate the vision: Clearly articulate the benefits of scalable databases to all stakeholders.&lt;/p&gt;

&lt;p&gt;Provide training: Offer comprehensive support and education on the new systems and processes.&lt;/p&gt;

&lt;p&gt;Showcase quick wins: Demonstrate immediate improvements to motivate and build confidence in the changes.&lt;/p&gt;

&lt;p&gt;By addressing concerns early and involving stakeholders in the process, resistance can be minimized, and scalability efforts can succeed without unnecessary delays.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Database schema changes are necessary for evolving applications, but they must be managed carefully to prevent disruptions. By using migrations, ensuring backward compatibility, automating testing, maintaining backups, implementing feature flags, and documenting changes, developers can minimize risks and ensure smooth transitions. Proper planning and a structured approach help safeguard against potential issues, ensuring that schema changes do not negatively impact the system or its users. Additionally, addressing resistance to change through effective communication, training, and showcasing quick wins will ensure scalability improvements are adopted smoothly.&lt;/p&gt;

</description>
      <category>database</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Simple Event Registration API with MongoDB and Flask</title>
      <dc:creator>Ernest Kabahima</dc:creator>
      <pubDate>Thu, 28 Nov 2019 06:30:17 +0000</pubDate>
      <link>https://dev.to/kabahima/simple-event-registration-api-with-mongodb-and-flask-2968</link>
      <guid>https://dev.to/kabahima/simple-event-registration-api-with-mongodb-and-flask-2968</guid>
      <description>&lt;h1&gt;
  
  
  let's start
&lt;/h1&gt;

&lt;p&gt;Simple Event Registration API is a demonstration of how to create, read and write data with MongoDB using Flask &lt;/p&gt;

&lt;h1&gt;
  
  
  MongoDB
&lt;/h1&gt;

&lt;p&gt;MongoDB is a document database with the scalability and flexibility that you want with the querying and indexing that you need. Its document model is simple for developers to learn and use, while still providing all the capabilities needed to meet the most complex requirements at any scale but You can &lt;a href="https://docs.mongodb.com/guides/"&gt;get started here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Use cases for MongoDB include the following;
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/single-view"&gt; Single View &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/internet-of-things"&gt; The Internet Of Things &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/mobile"&gt; Mobile &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/real-time-analytics"&gt; Real-Time Analytics &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/personalization"&gt; Personalization &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/catalog"&gt; Catalog &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/use-cases/content-management"&gt; Content Management &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;To install MongoDB &lt;a href="https://docs.mongodb.com/guides/server/install/"&gt;Click here&lt;/a&gt; if not installed &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://flask.palletsprojects.com/en/1.1.x/"&gt; Flask &lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are new to python and Flask You  can get started here with the following articles &lt;br&gt;
first, get to understand &lt;a href="https://www.geeksforgeeks.org/python-language-introduction/"&gt; python &lt;/a&gt; secondly start playing with &lt;a href="https://www.geeksforgeeks.org/python-build-a-rest-api-using-flask/"&gt; Flask &lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://www.guru99.com/postman-tutorial.html"&gt; Postman &lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This is a tool that makes the game of building API's fun,  its a must-have before even thinking of building an API. Postman is currently one of the most popular tools used in API testing. It started in 2012 as a side project by Abhinav Asthana to simplify API workflow in testing and development. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;API stands for Application Programming Interface which allows software applications to communicate with each other via API calls.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More about APIs &lt;a href="https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask"&gt;Click Here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Set up
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Install python on your machine if not installed you can check by using the following command &lt;code&gt;python3 --version&lt;/code&gt; &lt;br&gt;
check if the virtual environment is installed if not install it  &lt;a href="https://gist.github.com/Geoyi/d9fab4f609e9f75941946be45000632b"&gt; Linux &lt;/a&gt; for &lt;a href="https://programwithus.com/learn-to-code/Pip-and-virtualenv-on-Windows/"&gt;Windows&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  1.Create Virtual environment
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;python3 -m venv venv&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;venv - means the name of the virtual environment it can be anything&lt;br&gt;
&lt;a href="https://www.bogotobogo.com/python/python_virtualenv_virtualenvwrapper.php"&gt;Read More&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2.Activate Virtual environment
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;source venv/bin/activate&lt;/code&gt; or &lt;code&gt;. venv/bin/activate&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2.Installing the following
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Flask &lt;br&gt;
&lt;code&gt;pip install flask&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pymongo &lt;br&gt;
&lt;code&gt;pip install pymongo&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;check using &lt;code&gt;pip list&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Create a file called app.py with the following command
&lt;code&gt;Touch app.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;paste the following code
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask, jsonify, request
from flask_pymongo import PyMongo

app = Flask(__name__)
app.config["MONGO_URI"] = "mongodb://localhost:27017/regdb"
mongo = PyMongo(app)


@app.route('/', methods = ['GET'])
def get_all_attendees():
"""To get all the items from the database.its a Get request and we use the databasename.find()"""
    attendees = mongo.db.attendees
    output = []

    for r in attendees.find():
        output.append({
                    'name':r['name'],
            'address':r['address'],
                    'Phone_Number':r['p_number']
                    })
    return jsonify({'result' : output})

@app.route('/attendee/&amp;lt;name&amp;gt;', methods = ['GET'])
def get_one_attendee(name):
"""To get one item from the database.its a Get request and We use the databasename.find_one"""
    attendees = mongo.db.attendees
    attendees.find_one({'name':name})

    output.append({
                    'name':r['name'],
            'address':r['address'],
                    'Phone_Number':r['p_number']
                    })
    return jsonify({'result' : output})

@app.route('/register', methods = ['POST'])
def register():
"""To add an item to the database. its a post request and we use databasename.insert()"""
    attendees = mongo.db.attendees
    name = request.json['name']
    language=request.json['language']
    reg_id = attendees.insert({
                    'name':r['name'],
            'address':r['address'],
                    'Phone_Number':r['p_number']
                    })
    r = attendees.find_one({'_id':reg_id})
        output = ({
                    'name':r['name'],
            'address':r['address'],
                    'Phone_Number':r['p_number']
                    })
        return jsonify({'result' : output})

if __name__== '__main__':
    app.run(debug=True)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Go ahead and test your API with Postman&lt;/p&gt;

&lt;p&gt;Thanks, Ernest &lt;/p&gt;

</description>
      <category>pymongo</category>
      <category>mongodb</category>
      <category>flask</category>
      <category>python</category>
    </item>
  </channel>
</rss>
