diff --git a/unravel-emacs.org b/unravel-emacs.org
index f6463ee..1b193e5 100644
--- a/unravel-emacs.org
+++ b/unravel-emacs.org
@@ -4804,35 +4804,92 @@ Prot is the developer of this package.
 :CREATED: [2024-11-21 Thu 22:51]
 :END:
 
-The built-in Python mode for Emacs goes a long way. We build minimal tooling around this mode, specifically to support ~eglot~ and Python's virtualenv system.
+The built-in Python mode for Emacs goes a long way. I use the following stack when programming Python:
 
-Run the following commands to make sure you have the developer dependencies installed globally:
+- =poetry= for package and venv management
+- =pylsp= as the language server
+- =ruff= as the linting and formatting tool
 
-- =pipx= : Installed by =brew install pipx=
-- =ruff= : An extremely fast Python linter, and code formatter, written in Rust. Installed by  =pipx install ruff=
-  - Ruff is also a langauge server, but it only provides functionality related to formating and linting. As it adds more over time (like go-to definition), I may make it my primary language server
-- =pylsp= : The defacto language server for Python. Install with =pipx install python-lsp-server=
+Run the following commands in every virtualenv environment to setup the necessary developer tooling:
+
+- =poetry add ruff python-lsp-server python-lsp-ruff --group dev=
+  + Ruff is an extremely fast Python linter, and code formatter, written in Rust. Ruff is also a langauge server, but it only provides functionality related to formating and linting. As it adds more over time (like go-to definition), I may make it my primary language server
+  + Python LSP Server (provides the binary ~pylsp~) is the defacto language server for Python.
+  + =python-lsp-ruff= provides tight integration between ~pylsp~ and ~ruff~, enabling the language server to use ruff for it's linting and formatting capabilities.
+- =poetry add pytest --group test=
+
+Poetry takes care of setting up the venv properly, so if you replace the default commands with poetry versions, you are good to go. In practice, this means:
+
+- Use ~C-u C-c C-p~ command (=run-python=, with an argument) to start the Inferior Python Shell, instead of ~C-c C-p~.
+  - This will prompt you for a command, with the default value being =python3 -i=. Change it to =poetry run python3 -i=.
+- Modify the ~C-c C-v~ command (=python-check=) to =poetry run ruff check <filename>=
+
+I run ~eglot~ on demand, that is, I do not start a language server automatically when I open a Python file. This ensures that ~emacs-pet~ can setup the venv for the project and use executables only from the virtualenv. (Note: We also setup the ~emacs-pet~ hook to be the first thing that runs when python mode is activated, so automatically starting ~eglot~ by uncommenting the ~eglot-ensure~ hook below should also work. But running manually is just how I prefer it.)
+
+If you want to start the language server automatically you need to:
+
+- Install ~python-language-server~ and ~ruff~ globally, so that it's always available to Emacs.
+  - =brew install pipx=
+  - =pipx install ruff python-language-server=
+- Uncomment the ~:hook~ in the Python ~use-package~ form below
 
 #+begin_src emacs-lisp :tangle "unravel-modules/unravel-langs.el"
   ;;;; Configuration for Python Programming
 
   (use-package python
     :ensure nil
-    :hook
-    ((python-ts-mode . eglot-ensure)
-     (python-mode . eglot-ensure))
+    :ensure-system-package (dasel sqlite3)
+  ;;; Uncomment this if you want Eglot to start automatically. I don't
+  ;;; recommend it because it does not give you time to activate the
+  ;;; appropriate VirtualEnv and get the best of the situation.
+    ;; :hook ((python-base-mode . eglot-ensure))
     :config
-    (setq python-shell-dedicated 'project))
+    (setq python-shell-dedicated 'project)
+    ;; Apheleia is an Emacs package for formatting code as you save
+    ;; it. Here we are asking Apheleia to use Ruff for formatting our
+    ;; Python code.
+    (with-eval-after-load 'apheleia
+      (setf (alist-get 'python-mode apheleia-mode-alist)
+            '(ruff-isort ruff))
+      (setf (alist-get 'python-ts-mode apheleia-mode-alist)
+            '(ruff-isort ruff)))
+    (with-eval-after-load 'eglot
+      (require 'vedang-pet)
+      ;; The -10 here is a way to define the priority of the function in
+      ;; the list of hook functions. We want `pet-mode' to run before
+      ;; any other configured hook function.
+      (add-hook 'python-base-mode-hook #'pet-mode -10)))
+#+end_src
 
+*** Tooling I have tried and rejected or failed to setup correctly
+:PROPERTIES:
+:CUSTOM_ID: h:AA769AC9-18D9-4971-81C9-8DF7AD920013
+:END:
+
+- Auto-virtualenv: For virtualenv setup and detection
+- Pyvenv's WORKON_HOME: WORKON_HOME is useful if you keep all your venvs in the same directory. This is not generally what most people do.
+  - Config: ~(setenv "WORKON_HOME" "~/.cache/venvs/")~
+
+#+begin_src emacs-lisp
   (use-package pyvenv
     :ensure t
+    :after python
     :commands (pyvenv-create pyvenv-workon pyvenv-activate pyvenv-deactivate)
+    :hook
+    ((python-base-mode . pyvenv-mode)))
+
+  (use-package pet ;; Python Environment Tracker
+    :ensure t
+    :after (python eglot)
+    :ensure-system-package (dasel sqlite3)
     :config
-    (setenv "WORKON_HOME" "~/.cache/venvs/")
-    (pyvenv-tracking-mode 1))
+    ;; We use `add-hook' instead of :hook to be able to specify the -10
+    ;; (call as early as possible)
+    (add-hook 'python-base-mode-hook #'pet-mode -10))
 
   (use-package auto-virtualenv
     :ensure t
+    :after python
     :config
     (setq auto-virtualenv-verbose t)
     (auto-virtualenv-setup))
diff --git a/unravel-modules/unravel-langs.el b/unravel-modules/unravel-langs.el
index d2d8fde..7097dec 100644
--- a/unravel-modules/unravel-langs.el
+++ b/unravel-modules/unravel-langs.el
@@ -356,16 +356,23 @@ Perform the comparison with `string<'."
 
 (use-package python
   :ensure nil
-  :hook ((python-base-mode . eglot-ensure))
+  :ensure-system-package (dasel sqlite3)
+;;; Uncomment this if you want Eglot to start automatically. I don't
+;;; recommend it because it does not give you time to activate the
+;;; appropriate VirtualEnv and get the best of the situation.
+  ;; :hook ((python-base-mode . eglot-ensure))
   :config
-  (setq python-shell-dedicated 'project))
-
-(use-package pyvenv
-  :ensure t
-  :after python
-  :commands (pyvenv-create pyvenv-workon pyvenv-activate pyvenv-deactivate)
-  :config
-  (setenv "WORKON_HOME" "~/.cache/venvs/")
-  (pyvenv-tracking-mode 1))
+  (setq python-shell-dedicated 'project)
+  ;; Apheleia is an Emacs package for formatting code as you save
+  ;; it. Here we are asking Apheleia to use Ruff for formatting our
+  ;; Python code.
+  (with-eval-after-load 'apheleia
+    (setf (alist-get 'python-mode apheleia-mode-alist)
+          '(ruff-isort ruff))
+    (setf (alist-get 'python-ts-mode apheleia-mode-alist)
+          '(ruff-isort ruff)))
+  (with-eval-after-load 'eglot
+    (require 'vedang-pet)
+    (add-hook 'python-base-mode-hook #'pet-mode -10)))
 
 (provide 'unravel-langs)