<?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: Krishna Modepalli</title>
    <description>The latest articles on DEV Community by Krishna Modepalli (@krishnamodepalli).</description>
    <link>https://dev.to/krishnamodepalli</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%2F1084329%2F620719c1-e86b-4d1e-9013-c8fc969f8a76.jpg</url>
      <title>DEV Community: Krishna Modepalli</title>
      <link>https://dev.to/krishnamodepalli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krishnamodepalli"/>
    <language>en</language>
    <item>
      <title>Stop Putting Everything in .env — Runtime Config for Django</title>
      <dc:creator>Krishna Modepalli</dc:creator>
      <pubDate>Wed, 01 Apr 2026 13:30:00 +0000</pubDate>
      <link>https://dev.to/krishnamodepalli/stop-putting-everything-in-env-runtime-config-for-django-k8f</link>
      <guid>https://dev.to/krishnamodepalli/stop-putting-everything-in-env-runtime-config-for-django-k8f</guid>
      <description>&lt;p&gt;Hello all! 👋&lt;/p&gt;

&lt;p&gt;TL;DR I created a runtime configuration Django app called &lt;a href="https://github.com/krishnamodepalli/django-sysconfig" rel="noopener noreferrer"&gt;&lt;code&gt;django-sysconfig&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fkrishnamodepalli%2Fdjango-sysconfig%2Freleases%2Fdownload%2Fv0.3.0%2Fdjango-sysconfig.gif" 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%2Fgithub.com%2Fkrishnamodepalli%2Fdjango-sysconfig%2Freleases%2Fdownload%2Fv0.3.0%2Fdjango-sysconfig.gif" alt="Django Sysconfig app usage" width="760" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the problem that led me to build it. We all tend to bloat the &lt;code&gt;settings.py&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; files to store all these secrets and other API URLs for 3rd-party integrations. This approach requires the server restart on each change to &lt;code&gt;.env&lt;/code&gt; file, and also this is not a scalable solution.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/krishnamodepalli/django-sysconfig" rel="noopener noreferrer"&gt;&lt;code&gt;django-sysconfig&lt;/code&gt;&lt;/a&gt; is a schema-driven database-backed typed runtime configuration app for Django&lt;/strong&gt;. This app has in-built cache support (using Django Cache Framework) with a simple Admin UI to allow non-IT admins to easily manage the project configurations.&lt;/p&gt;

&lt;p&gt;Some features of this app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validations (email, url, ip, port, hostname, min-max, regex, etc. Each config value will be validated before saving to DB)&lt;/li&gt;
&lt;li&gt;A clean Admin UI to manage configurations.&lt;/li&gt;
&lt;li&gt;Schema based config. Your schema updates as your app grows and is distributed across your apps instead of a single place)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;on_save&lt;/code&gt; callbacks for each config (helpful for DevOps notifications)&lt;/li&gt;
&lt;li&gt;CLI management command to manage configs through cli.&lt;/li&gt;
&lt;li&gt;Runtime typed. The values are automatically converted to the field defined type.&lt;/li&gt;
&lt;li&gt;Secrets. Store secrets securely in DB (encrypted) and are decrypted when used in code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This app is built to be extended from the core. You don't like the admin UI. Make your own the core &lt;code&gt;config&lt;/code&gt; API and simple templates. Need new validators or new config Field types? Create your own very easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it compare?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;django-sysconfig&lt;/strong&gt; ⭐&lt;/th&gt;
&lt;th&gt;django-constance&lt;/th&gt;
&lt;th&gt;django-dynamic-preferences&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Schema definition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sysconfig.py&lt;/code&gt; per app, auto-discovered&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CONSTANCE_CONFIG&lt;/code&gt; dict in &lt;code&gt;settings.py&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Decorated Python class, registered manually&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Redis, Database, or Memory&lt;/td&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Caching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ No expiry, invalidated on write.&lt;/td&gt;
&lt;td&gt;✅ Redis TTL or DB cache backend&lt;/td&gt;
&lt;td&gt;✅ Django cache, invalidated on write&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Typed fields&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ String, Int, Decimal, Bool, Select, Textarea, Secret&lt;/td&gt;
&lt;td&gt;Basic — custom types via &lt;code&gt;CONSTANCE_ADDITIONAL_FIELDS&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅ Bool, String, Int, Float, Choice, File, ModelChoice…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Built-in validators&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ 20 — email, URL, IP, range, regex, slug, JSON, port…&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Basic form field validation only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Encryption at rest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;code&gt;SecretFrontendModel&lt;/code&gt; (Fernet AES-128 + HMAC)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;on_save callback&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Per-field, fires after DB write + cache update&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Management CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;code&gt;get&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, &lt;code&gt;reset&lt;/code&gt;, &lt;code&gt;export&lt;/code&gt;, &lt;code&gt;import&lt;/code&gt; (with &lt;code&gt;--dry-run&lt;/code&gt;, &lt;code&gt;--force&lt;/code&gt;, &lt;code&gt;--skip-on-save-callbacks&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-user / instance settings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Global only&lt;/td&gt;
&lt;td&gt;❌ Global only&lt;/td&gt;
&lt;td&gt;✅ Global + per-user/model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Admin UI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom staff-only views at &lt;code&gt;/admin/config/&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Standard Django admin (flat list)&lt;/td&gt;
&lt;td&gt;Standard Django admin (grouped by section)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accessing values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;config.get("app.section.field")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;config.SETTING_NAME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;global_preferences["section__name"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;REST API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Optional, DRF-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Min Python / Django&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python 3.11 / Django 4.2&lt;/td&gt;
&lt;td&gt;Python 3.x / Django 3.2&lt;/td&gt;
&lt;td&gt;Python 3.6 / Django 3.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🆕 Early stage&lt;/td&gt;
&lt;td&gt;🏆 Mature, Jazzband-maintained&lt;/td&gt;
&lt;td&gt;✅ Stable, active community&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I've recently released the &lt;a href="https://github.com/krishnamodepalli/django-sysconfig/releases/tag/v1.0.0" rel="noopener noreferrer"&gt;&lt;code&gt;v1.0.0&lt;/code&gt;&lt;/a&gt; to PyPi. Feel free to try it out. Would love your feedback on this.&lt;/p&gt;

&lt;p&gt;GitHub Repo: &lt;a href="https://github.com/krishnamodepalli/django-sysconfig" rel="noopener noreferrer"&gt;https://github.com/krishnamodepalli/django-sysconfig&lt;/a&gt;&lt;br&gt;
Docs: &lt;a href="https://krishnamodepalli.github.io/django-sysconfig/" rel="noopener noreferrer"&gt;https://krishnamodepalli.github.io/django-sysconfig/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Automatically pull, when you enter a git repo (cli)</title>
      <dc:creator>Krishna Modepalli</dc:creator>
      <pubDate>Sat, 31 Aug 2024 17:41:12 +0000</pubDate>
      <link>https://dev.to/krishnamodepalli/automatically-pull-when-you-enter-a-git-repo-cli-5bgk</link>
      <guid>https://dev.to/krishnamodepalli/automatically-pull-when-you-enter-a-git-repo-cli-5bgk</guid>
      <description>&lt;p&gt;We all work with git repositories once we start learning programming and coding. When we use git a lot and starting to get used to it, someday we will encounter the problem of committing new changes locally and pushing when we have some changes to pull, in the first place, which we did forget. &lt;/p&gt;

&lt;p&gt;Some IDE's like jetbrains (and vscode maybe) provide you the feature to pull any recent changes to the repository in the remote, Which will save us from this problem. But fate is too harsh on us sometimes, we can do nothing but revert the code and just re-commit our changes.&lt;/p&gt;

&lt;p&gt;So I did want to come up with a solution which is simple and easy to set-up. So what I did is, when ever I enter a git repo (local git repo folder), I will run a simple bash script which will ask the user to either &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt; or just do nothing.&lt;/p&gt;

&lt;p&gt;The script is very simple, please check my &lt;a href="https://github.com/krishnamodepalli/gitautopull" rel="noopener noreferrer"&gt;github repo&lt;/a&gt; for this simple bash automation project.&lt;/p&gt;

&lt;p&gt;Currently I am trying to give it a bit more flavour. The bash script is sometimes very annoying, if we frequently move between projects. So I want to implement a time barrier, which checks the last time I opened this project. If it is more than 20 mins, then the script will ask to fetch new changes. Other-wise, the script silently continues to exit.&lt;/p&gt;

</description>
      <category>git</category>
      <category>automation</category>
      <category>gitpull</category>
    </item>
    <item>
      <title>Setting up a git-server on linux</title>
      <dc:creator>Krishna Modepalli</dc:creator>
      <pubDate>Mon, 25 Sep 2023 18:11:59 +0000</pubDate>
      <link>https://dev.to/krishnamodepalli/setting-up-a-git-server-on-linux-cbp</link>
      <guid>https://dev.to/krishnamodepalli/setting-up-a-git-server-on-linux-cbp</guid>
      <description>&lt;p&gt;Before starting, Let us know the part of &lt;strong&gt;What is a git-server&lt;/strong&gt;?&lt;br&gt;
A git-server is server where we can host git repositories, for e.g. &lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &amp;amp; &lt;a href="https://gitlab.com" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;, etc.. The git platform is a decentralized version control system, which means we have the local copy of the repo, and we can externally host the repo at any place. This increases the usability for the user to even code the project even the server is offline, and can upload the changes once hit online. Setting-Up a private git-server is a good option for a private organizations like companies, or can be a nice project for a college student. &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting-Up the linux Machine
&lt;/h2&gt;

&lt;p&gt;You can use any flavour of linux distro. Make sure you setup every-thing you need to set a basic server, like &lt;em&gt;&lt;strong&gt;Opening the required ports&lt;/strong&gt;&lt;/em&gt; and stuff, accessing your server via &lt;strong&gt;SSH or Display&lt;/strong&gt;. You can do this by the guidance from any developer or just tutorials. &lt;/p&gt;

&lt;p&gt;SSH port is must for the git. So make sure to open the 22 port. You can do this with &lt;code&gt;ufw&lt;/code&gt; command&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="nv"&gt;$ &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;               &lt;span class="c"&gt;# To start the ufw&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ufw allow OpenSSH        &lt;span class="c"&gt;# To Open the 22 port&lt;/span&gt;
&lt;span class="c"&gt;# To check if done 👍?&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see an output saying Port 22 is enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting-Up the user for handling git server
&lt;/h2&gt;

&lt;p&gt;You need to add a new user named &lt;code&gt;git&lt;/code&gt; on your linux machine, make sure that you add that user to sudoers file. After that, you need to access the user &lt;code&gt;git&lt;/code&gt; using some ssh keys. For that You need to generate ssh-keys on your local machine and copy the public keys to access your repo via SSH from your private server.&lt;/p&gt;

&lt;p&gt;Steps for setting-up a user for git-server&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Create a sudo user named &lt;strong&gt;git&lt;/strong&gt;
&lt;/h2&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;useradd git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;git
&lt;span class="nv"&gt;$ &lt;/span&gt;su git                &lt;span class="c"&gt;# change to git user&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Create a &lt;code&gt;.ssh&lt;/code&gt; folder &amp;amp; store the public keys for the repositories
&lt;/h2&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/.ssh
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; ~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
Generate your ssh-keys on your local machine to access your repo on server. Copy the public key and paste it in this file.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Create the /git/repo-name or /repo-name file in the file-system.
&lt;/h2&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo chown &lt;/span&gt;git /git or /repo-name
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;test_repo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
By default /git folder belongs to root only. Change the Owner-Ship to git using &lt;code&gt;chown&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Initialize the git repository. 
&lt;/h2&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git init &lt;span class="nt"&gt;--bare&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
Always use the --bare flag, because this makes the repository convenient for pulling from &amp;amp; pushing to. The normal repositories doesn't help pulling or pushing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Completed
&lt;/h2&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone git@your-server-ip:/git/test_repo.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br&gt;
You can use this repo just like the one cloned from your github account&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;That's it, your private git-server is ready to server now.&lt;/p&gt;

</description>
      <category>git</category>
      <category>linux</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
