{"id":4827,"date":"2026-07-01T22:54:50","date_gmt":"2026-07-01T17:24:50","guid":{"rendered":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/"},"modified":"2026-07-01T22:54:50","modified_gmt":"2026-07-01T17:24:50","slug":"python-best-practices-guide","status":"publish","type":"post","link":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/","title":{"rendered":"Python Best Practices &#8211; Guide"},"content":{"rendered":"<p>Timestamp: 03:14:22 UTC. The cluster started bleeding, and it was all because someone thought they were too good for type hints.<\/p>\n<pre class=\"codehilite\"><code class=\"language-python\">Traceback (most recent call last):\n  File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 299, in app\n    raw_response = await run_endpoint_function(\n                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 210, in run_endpoint_function\n    return await dependant.call(**values)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File &quot;\/app\/api\/v2\/endpoints\/processor.py&quot;, line 84, in process_data\n    result = compute_weighted_average(payload.items)\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File &quot;\/app\/logic\/math_utils.py&quot;, line 12, in compute_weighted_average\n    return sum(item.value * item.weight for item in items) \/ sum(item.weight for item in items)\n               ^^^^^^^^^^\nAttributeError: 'dict' object has no attribute 'value'\n<\/code><\/pre>\n<p>I\u2019ve been awake for 48 hours. My keyboard is sticky with spilled espresso and my monitors are burning a hole through my retinas. The cooling fan in the server rack next to my desk is screaming at 5000 RPM, which is a fitting soundtrack for the absolute wreckage I\u2019ve been digging through. We had a 99.99% uptime SLA. We had a reputation. Then Kevin\u2014our &#8220;rockstar&#8221; junior who thinks documentation is for people who can\u2019t read code\u2014pushed a &#8220;minor optimization&#8221; to the data processing pipeline. He didn&#8217;t use type hints. He didn&#8217;t use a linter. He just pushed. And because our CI\/CD pipeline was apparently configured by a toddler, it let his unmitigated disaster of a PR slide right into production.<\/p>\n<p>The error above is the smoking gun. It\u2019s a Python 3.12.1 runtime failure that should have been caught at the IDE level, or at the very least, during a pre-commit hook. But no. We\u2019re running Python 3.12.1, taking advantage of the new f-string parsing improvements and the per-interpreter GIL work, yet we\u2019re writing code like it\u2019s 2005 and we\u2019re trying to build a guestbook for a hobby site. This isn&#8217;t just about style; it&#8217;s about the fundamental python best practices that keep the lights on when the traffic spikes at 3:00 AM.<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_80 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a45b7f2c6c5c\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a45b7f2c6c5c\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#The_Anatomy_of_a_Runtime_Catastrophe\" >The Anatomy of a Runtime Catastrophe<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#The_Dependency_Hellscape_and_the_Death_of_Determinism\" >The Dependency Hellscape and the Death of Determinism<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#Type_Hinting_as_a_Survival_Mechanism\" >Type Hinting as a Survival Mechanism<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#The_Ruff_Mandate_Linting_or_Chaos\" >The Ruff Mandate: Linting or Chaos<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#Structured_Logging_A_Love_Letter_to_Sanity\" >Structured Logging: A Love Letter to Sanity<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#Memory_Leaks_and_the_CPython_3121_Garbage_Collector\" >Memory Leaks and the CPython 3.12.1 Garbage Collector<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#The_CICD_Gatekeeper\" >The CI\/CD Gatekeeper<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#Related_Articles\" >Related Articles<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"The_Anatomy_of_a_Runtime_Catastrophe\"><\/span>The Anatomy of a Runtime Catastrophe<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The failure started in the <code>compute_weighted_average<\/code> function. In Python 3.12.1, the interpreter is faster, sure, but it\u2019s not a mind reader. Kevin decided that passing a list of objects was &#8220;too heavy&#8221; and instead passed a list of dictionaries, but he forgot to update the attribute access to key access. Or rather, he mixed them up. In a statically typed language, the compiler would have laughed him out of the room. In Python, without <code>mypy<\/code> 1.8.0 or <code>pyright<\/code> 1.1.350, the code just sits there like a landmine, waiting for a specific payload to trigger a <code>TypeError<\/code> or an <code>AttributeError<\/code>.<\/p>\n<p>This is the cost of &#8220;clever&#8221; code. Clever code is code that bypasses safety checks to save three lines of boilerplate. Clever code is what causes SREs to lose their weekends. If you want to claim you follow python best standards, you start by acknowledging that your brain is a faulty biological machine and you need the machine to check your work. The <code>items<\/code> variable was supposed to be a <code>list[Item]<\/code>, where <code>Item<\/code> is a Pydantic v2.6.1 model. Instead, it was a raw <code>list[dict]<\/code>. The <code>sum()<\/code> function started iterating, hit a dictionary, tried to access <code>.value<\/code>, and the whole service collapsed under the weight of its own incompetence.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_Dependency_Hellscape_and_the_Death_of_Determinism\"><\/span>The Dependency Hellscape and the Death of Determinism<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When I finally got into the pod to see why the rollback was failing, I found the next layer of the nightmare. The <code>requirements.txt<\/code> file. I hate <code>requirements.txt<\/code>. It is a relic of a simpler, stupider time. It\u2019s a flat list of lies. Kevin had added <code>requests<\/code> without pinning a version. <\/p>\n<pre class=\"codehilite\"><code class=\"language-text\"># Raw terminal output: pip list on the failing pod\nPackage            Version\n------------------ ---------\nannotated-types    0.6.0\nanyio              4.2.0\nclick              8.1.7\nfastapi            0.109.0\nh11                0.14.0\nidna               3.6\npydantic           2.6.1\npydantic_core      2.16.2\nrequests           2.31.0\nsniffio            1.3.0\nstarlette          0.35.1\ntyping_extensions  4.9.0\nuvicorn            0.27.0.post1\n<\/code><\/pre>\n<p>Look at that. <code>requests 2.31.0<\/code>. Yesterday it was <code>2.28.1<\/code>. Somewhere in the transit, a sub-dependency shifted, and because we aren&#8217;t using a lockfile, the build system just grabbed whatever was newest on PyPI. This is why <code>pyproject.toml<\/code> is not optional. If you aren&#8217;t using <code>poetry<\/code> 1.7.1 or <code>pdm<\/code> 2.12.0 to generate a deterministic lockfile, you aren&#8217;t running a production environment; you&#8217;re running a gambling ring. <\/p>\n<p>The python best way to handle dependency management is to use <code>pyproject.toml<\/code> with strict pins and a cryptographic lockfile. I spent four hours just trying to reconstruct the exact environment that existed before the &#8220;optimization&#8221; push because the <code>pip freeze<\/code> output from the dev environment didn&#8217;t match the staging environment. We are using Python 3.12.1, which has excellent support for modern packaging standards, yet we\u2019re still acting like we\u2019re installing packages on a shared hosting provider in 2010.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Type_Hinting_as_a_Survival_Mechanism\"><\/span>Type Hinting as a Survival Mechanism<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I\u2019m tired of hearing that type hints make Python &#8220;look like Java.&#8221; You know what Java has? Fewer 3:00 AM outages caused by <code>NoneType<\/code> errors. In Python 3.12.1, we have the new <code>type<\/code> statement (PEP 695) which makes generics actually readable. We have <code>Annotated<\/code> for metadata. We have zero excuses.<\/p>\n<p>When I ran <code>mypy<\/code> against the &#8220;optimized&#8221; code, the output was a wall of red text that looked like a crime scene.<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\"># Raw terminal output: mypy --strict logic\/math_utils.py\nlogic\/math_utils.py:12: error: &quot;dict[Any, Any]&quot; has no attribute &quot;value&quot;  [attr-defined]\nlogic\/math_utils.py:12: error: &quot;dict[Any, Any]&quot; has no attribute &quot;weight&quot;  [attr-defined]\nlogic\/math_utils.py:15: error: Argument 1 to &quot;compute_weighted_average&quot; has incompatible type &quot;list[dict[str, float]]&quot;; expected &quot;list[Item]&quot;  [arg-type]\nFound 3 errors in 1 file (checked 1 source file)\n<\/code><\/pre>\n<p>Three errors. It took <code>mypy<\/code> 0.4 seconds to find what took me 4 hours of log aggregation to isolate. This is why I insist on <code>mypy<\/code> 1.8.0 being a blocking step in the CI. If the types don&#8217;t check out, the code doesn&#8217;t exist. I don&#8217;t care if it &#8220;works&#8221; on your local machine. Your local machine isn&#8217;t handling 50,000 requests per second. Your local machine isn&#8217;t running in a container with limited cgroups memory. <\/p>\n<p>The python best way to write functions is to define the contract. <code>def compute_weighted_average(items: list[Item]) -&gt; float:<\/code>. It\u2019s not a suggestion. It\u2019s a contract. When Kevin changed <code>Item<\/code> (a Pydantic model) to a <code>dict<\/code>, he broke the contract. Because he didn&#8217;t update the type hints, the IDE didn&#8217;t complain. Because he didn&#8217;t run <code>mypy<\/code>, the CI didn&#8217;t complain. And because he\u2019s a &#8220;rockstar,&#8221; he didn&#8217;t think he needed to check.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_Ruff_Mandate_Linting_or_Chaos\"><\/span>The Ruff Mandate: Linting or Chaos<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We used to use <code>flake8<\/code>, <code>isort<\/code>, and <code>black<\/code>. It was a mess of different config files and slow execution times. Now we have <code>Ruff<\/code> 0.2.1. It\u2019s written in Rust. It\u2019s fast. It\u2019s exhaustive. And yet, Kevin had disabled the Ruff pre-commit hook because it was &#8220;slowing down his workflow.&#8221; <\/p>\n<p>His workflow. His precious seconds of saved time cost the company thousands of dollars in lost revenue and cost me my sanity. <\/p>\n<p>If you aren&#8217;t using Ruff, you are failing. The python best approach to code quality is an automated, uncompromising linter that runs on every save. Ruff catches things that <code>mypy<\/code> misses\u2014unused imports that bloat the namespace, mutable default arguments that create persistent state across function calls, and the use of <code>eval()<\/code> which is basically an open invitation for a remote code execution exploit.<\/p>\n<p>I had to go back and fix his <code>try...except<\/code> blocks. He was using <code>except Exception:<\/code>, catching everything including <code>KeyboardInterrupt<\/code> and <code>SystemExit<\/code>, and then\u2014this is the best part\u2014he was using <code>pass<\/code>. He silenced the errors. He literally buried the evidence of his own code\u2019s failure. If Ruff had been running, it would have flagged <code>E722<\/code> (do not use bare <code>except<\/code>) and <code>F841<\/code> (local variable assigned but never used). <\/p>\n<h2><span class=\"ez-toc-section\" id=\"Structured_Logging_A_Love_Letter_to_Sanity\"><\/span>Structured Logging: A Love Letter to Sanity<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>When the system started failing, I went to the logs. What did I find? <\/p>\n<p><code>ERROR: Something went wrong in the math function.<\/code><\/p>\n<p>That\u2019s it. That was the log entry. No stack trace (because he caught the exception and passed), no request ID, no user ID, no payload snippet. Just a vague sense of dread in string format. <\/p>\n<p>We are using <code>structlog<\/code> 24.1.0 for a reason. We need JSON-formatted logs that can be ingested by Elasticsearch and queried with precision. The python best way to handle logging is to treat logs as data, not as a diary. A good log entry should look like this:<\/p>\n<pre class=\"codehilite\"><code class=\"language-json\">{\n  &quot;event&quot;: &quot;calculation_failed&quot;,\n  &quot;level&quot;: &quot;error&quot;,\n  &quot;timestamp&quot;: &quot;2024-05-20T03:14:22.123Z&quot;,\n  &quot;request_id&quot;: &quot;a8f3-4b92-91c1&quot;,\n  &quot;exception&quot;: &quot;AttributeError: 'dict' object has no attribute 'value'&quot;,\n  &quot;input_payload_summary&quot;: {&quot;item_count&quot;: 42, &quot;type&quot;: &quot;list[dict]&quot;}\n}\n<\/code><\/pre>\n<p>Instead, I got a string that told me nothing. I had to inject <code>sys.settrace<\/code> into a running process like some kind of digital surgeon just to see what the hell was happening inside the event loop. In Python 3.12.1, the <code>sys<\/code> module and the new monitoring API (PEP 669) actually make this easier, but I shouldn&#8217;t have to use debugger-level tools to find a basic logic error. <\/p>\n<p>Logging is not an afterthought. It is the only window you have into the black box of production. If you don&#8217;t log with context, you are flying blind in a storm. I\u2019ve spent the last six hours rewriting the logging middleware for FastAPI 0.109.0 to ensure that every single request carries a trace ID through the entire stack, from the load balancer to the database driver.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Memory_Leaks_and_the_CPython_3121_Garbage_Collector\"><\/span>Memory Leaks and the CPython 3.12.1 Garbage Collector<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>As if the logic errors weren&#8217;t enough, the &#8220;optimization&#8221; also introduced a massive memory leak. Kevin thought it would be a good idea to cache the results of the weighted average calculation in a global dictionary. He didn&#8217;t use an LRU cache. He didn&#8217;t use <code>functools.lru_cache<\/code>. He just appended to a global dict.<\/p>\n<p>In Python 3.12.1, the garbage collector is efficient, but it can\u2019t collect things that are still referenced. By the time I got the alerts, the RSS (Resident Set Size) of the worker processes was climbing at a 45-degree angle.<\/p>\n<pre class=\"codehilite\"><code class=\"language-bash\"># Raw terminal output: pytest traceback from the memory leak reproduction script\n_________________________ test_memory_growth __________________________\ndef test_memory_growth():\n    initial_mem = get_process_memory()\n    for _ in range(10000):\n        process_request({&quot;items&quot;: [{&quot;value&quot;: 10, &quot;weight&quot;: 1}]})\n    final_mem = get_process_memory()\n&gt;   assert final_mem &lt; initial_mem * 1.1\nE   AssertionError: assert 1024.5 &gt; 110.0\nE   Note: Memory grew from 100MB to 1GB in 10,000 iterations.\n<\/code><\/pre>\n<p>He created a reference cycle that even the generational collector couldn&#8217;t break because the root was a global variable. This is basic memory management. This is &#8220;Python 101,&#8221; yet here we are. The python best practice for caching is to use a dedicated store like Redis 7.2 or, if it must be in-memory, a bounded cache with a clear eviction policy. <\/p>\n<p>I had to kill the worker processes manually because the OOM (Out Of Memory) killer was taking too long and the swap space was starting to thrash. When a Linux kernel starts thrashing swap, the whole node becomes unresponsive. I couldn&#8217;t even SSH in for ten minutes. I had to hard-reboot the instances through the AWS console. All of this because someone didn&#8217;t want to use a standard library decorator.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_CICD_Gatekeeper\"><\/span>The CI\/CD Gatekeeper<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The final failure wasn&#8217;t Kevin&#8217;s code; it was our culture. We allowed a PR to be merged without a green light from the static analysis tools. We allowed &#8220;clever&#8221; to beat &#8220;stable.&#8221; <\/p>\n<p>From now on, the rules are changing. I don&#8217;t care if the feature is needed for a demo to the CEO. I don&#8217;t care if it&#8217;s a &#8220;one-line fix.&#8221; <\/p>\n<ol>\n<li><strong>Strict Typing:<\/strong> Every function must have type hints. No <code>Any<\/code>. No <code>ignore<\/code>. If <code>mypy<\/code> 1.8.0 isn&#8217;t happy, the build fails.<\/li>\n<li><strong>Ruff Enforcement:<\/strong> The Ruff linter will run with the <code>ALL<\/code> rule set. Any violation is a build failure.<\/li>\n<li><strong>Pydantic Everywhere:<\/strong> No raw dictionaries will be passed between architectural layers. We use Pydantic v2.6.1 for all data validation. The performance overhead is negligible compared to the cost of a 48-hour War Room.<\/li>\n<li><strong>Lockfiles:<\/strong> <code>requirements.txt<\/code> is banned. We use <code>poetry.lock<\/code>.<\/li>\n<li><strong>Testing:<\/strong> 100% coverage is a myth, but 0% coverage on new logic is a fireable offense. <code>pytest<\/code> 8.0.0 must run and pass.<\/li>\n<\/ol>\n<p>I\u2019m going to sleep now. If the cluster starts bleeding again, don&#8217;t call me. Call Kevin. Tell him to check his types. Tell him to read the CPython source code for <code>gc.c<\/code> until he understands why global dictionaries are a bad idea. Tell him that &#8220;clever&#8221; is the enemy of &#8220;reliable.&#8221; <\/p>\n<p>I\u2019ve written this post-mortem not just to document the failure, but to serve as a warning. Python is a powerful, sophisticated language in its 3.12.1 iteration. It deserves better than the hacky, unoptimized garbage that was pushed this weekend. Stability is not a feature; it is a prerequisite. If you can&#8217;t write code that survives the night, you shouldn&#8217;t be writing code at all. <\/p>\n<p>The next time I see a PR without type hints, I\u2019m not just going to reject it. I\u2019m going to delete the branch and revoke the committer&#8217;s access. We are SREs. We are the thin line between a functioning platform and a pile of smoking silicon. We don&#8217;t have time for &#8220;clever.&#8221; We only have time for what works. <\/p>\n<p>Go fix your code. Use Ruff. Use Mypy. Use Pydantic. Follow the python best practices I\u2019ve laid out, or find another profession where your &#8220;creativity&#8221; doesn&#8217;t wake me up at 3:00 AM. My coffee is cold, my head hurts, and I\u2019m done.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Related_Articles\"><\/span>Related Articles<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Explore more insights and best practices:<\/p>\n<ul>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/how-to-install-asterisk-16-on-ubuntu-18-04-lts\/\">How To Install Asterisk 16 On Ubuntu 18 04 Lts<\/a><\/li>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/what-is-kubernetes-a-simple-guide-to-container-orchestration\/\">What Is Kubernetes A Simple Guide To Container Orchestration<\/a><\/li>\n<li><a href=\"https:\/\/itsupportwale.com\/blog\/machine-learning-best-practices-7-tips-for-success\/\">Machine Learning Best Practices 7 Tips For Success<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Timestamp: 03:14:22 UTC. The cluster started bleeding, and it was all because someone thought they were too good for type hints. Traceback (most recent call last): File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 299, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 210, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/app\/api\/v2\/endpoints\/processor.py&quot;, line 84, in process_data result = &#8230; <a title=\"Python Best Practices &#8211; Guide\" class=\"read-more\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\" aria-label=\"Read more  on Python Best Practices &#8211; Guide\">Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4827","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Python Best Practices - Guide - ITSupportWale<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python Best Practices - Guide - ITSupportWale\" \/>\n<meta property=\"og:description\" content=\"Timestamp: 03:14:22 UTC. The cluster started bleeding, and it was all because someone thought they were too good for type hints. Traceback (most recent call last): File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 299, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 210, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/app\/api\/v2\/endpoints\/processor.py&quot;, line 84, in process_data result = ... Read more\" \/>\n<meta property=\"og:url\" content=\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"ITSupportWale\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-01T17:24:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Techie\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Techie\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\"},\"author\":{\"name\":\"Techie\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\"},\"headline\":\"Python Best Practices &#8211; Guide\",\"datePublished\":\"2026-07-01T17:24:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\"},\"wordCount\":1936,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\",\"name\":\"Python Best Practices - Guide - ITSupportWale\",\"isPartOf\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\"},\"datePublished\":\"2026-07-01T17:24:50+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/itsupportwale.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python Best Practices &#8211; Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#website\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"name\":\"ITSupportWale\",\"description\":\"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides\",\"publisher\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#organization\",\"name\":\"itsupportwale\",\"url\":\"https:\/\/itsupportwale.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"contentUrl\":\"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png\",\"width\":1119,\"height\":144,\"caption\":\"itsupportwale\"},\"image\":{\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Itsupportwale-298547177495978\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d\",\"name\":\"Techie\",\"sameAs\":[\"https:\/\/itsupportwale.com\",\"iswblogadmin\"],\"url\":\"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Python Best Practices - Guide - ITSupportWale","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/","og_locale":"en_US","og_type":"article","og_title":"Python Best Practices - Guide - ITSupportWale","og_description":"Timestamp: 03:14:22 UTC. The cluster started bleeding, and it was all because someone thought they were too good for type hints. Traceback (most recent call last): File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 299, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/usr\/local\/lib\/python3.12\/site-packages\/fastapi\/routing.py&quot;, line 210, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File &quot;\/app\/api\/v2\/endpoints\/processor.py&quot;, line 84, in process_data result = ... Read more","og_url":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/","og_site_name":"ITSupportWale","article_publisher":"https:\/\/www.facebook.com\/Itsupportwale-298547177495978","article_published_time":"2026-07-01T17:24:50+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2021\/05\/android-chrome-512x512-1.png","type":"image\/png"}],"author":"Techie","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Techie","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#article","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/"},"author":{"name":"Techie","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d"},"headline":"Python Best Practices &#8211; Guide","datePublished":"2026-07-01T17:24:50+00:00","mainEntityOfPage":{"@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/"},"wordCount":1936,"commentCount":0,"publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/","url":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/","name":"Python Best Practices - Guide - ITSupportWale","isPartOf":{"@id":"https:\/\/itsupportwale.com\/blog\/#website"},"datePublished":"2026-07-01T17:24:50+00:00","breadcrumb":{"@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/itsupportwale.com\/blog\/python-best-practices-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/itsupportwale.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Python Best Practices &#8211; Guide"}]},{"@type":"WebSite","@id":"https:\/\/itsupportwale.com\/blog\/#website","url":"https:\/\/itsupportwale.com\/blog\/","name":"ITSupportWale","description":"Tips, Tricks, Fixed-Errors, Tutorials &amp; Guides","publisher":{"@id":"https:\/\/itsupportwale.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/itsupportwale.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/itsupportwale.com\/blog\/#organization","name":"itsupportwale","url":"https:\/\/itsupportwale.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","contentUrl":"https:\/\/itsupportwale.com\/blog\/wp-content\/uploads\/2023\/09\/cropped-Logo-trans-without-slogan.png","width":1119,"height":144,"caption":"itsupportwale"},"image":{"@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Itsupportwale-298547177495978"]},{"@type":"Person","@id":"https:\/\/itsupportwale.com\/blog\/#\/schema\/person\/8c5a2b3d36396e0a8fd91ec8242fd46d","name":"Techie","sameAs":["https:\/\/itsupportwale.com","iswblogadmin"],"url":"https:\/\/itsupportwale.com\/blog\/author\/iswblogadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4827","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/comments?post=4827"}],"version-history":[{"count":0,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/posts\/4827\/revisions"}],"wp:attachment":[{"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/media?parent=4827"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/categories?post=4827"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itsupportwale.com\/blog\/wp-json\/wp\/v2\/tags?post=4827"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}