[{"data":1,"prerenderedAt":821},["ShallowReactive",2],{"\u002Fblogs\u002Funderstanding-python-import-error-message":3},{"id":4,"title":5,"body":6,"coverImage":809,"description":812,"extension":813,"meta":814,"navigation":369,"path":815,"publishedOn":816,"seo":817,"sitemap":818,"stem":819,"__hash__":820},"content\u002Fblogs\u002Funderstanding-python-import-error-message.md","Understanding Why Your FastAPI Throws an ImportError Message",{"type":7,"value":8,"toc":803},"minimark",[9,13,37,61,64,71,78,81,117,122,142,145,154,300,319,336,527,534,537,543,568,571,579,585,595,604,617,624,633,644,650,674,687,693,713,722,734,738,749,799],[10,11,12],"p",{},"If you worked on a Python project before you would know, the said programming\nlanguage is a very handy scripting & interpreted language. You could take a\nsimple Python file & invoke the following CLI command without any issues:",[14,15,20],"pre",{"className":16,"code":17,"language":18,"meta":19,"style":19},"language-console shiki shiki-themes everforest-dark","$ python script.py\n# ... output of the code in the Python script\n","console","",[21,22,23,31],"code",{"__ignoreMap":19},[24,25,28],"span",{"class":26,"line":27},"line",1,[24,29,30],{},"$ python script.py\n",[24,32,34],{"class":26,"line":33},2,[24,35,36],{},"# ... output of the code in the Python script\n",[10,38,39,40,47,48,56,57,60],{},"Its scripting capabilities allows the programming language to be used on with\nother scripting languages like ",[41,42,46],"a",{"href":43,"rel":44},"https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fbash",[45],"nofollow","Bash",". But\nwhat makes Python truly stand out from its competitors are its\n\"",[41,49,52],{"href":50,"rel":51},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FModular_programming",[45],[53,54,55],"em",{},"modular programming","\"\ncapabilities. As such its not uncommon to build large modular projects where\neach functional aspects of the project are separated in to their own individual\nmodules (or ",[53,58,59],{},"namespace",") using Python.",[10,62,63],{},"And since Python is a scripting language its possible to execute Python Modules\nas scripts as well when & wherever necessary. Although how the program's runtime\nbehaviour post-execution might differ which might or might not be as intended.",[10,65,66,67,70],{},"Besides, the language is also unopinionated on an \"",[53,68,69],{},"entrypoint","\" during\nexecution which makes things a tad bit complicated for the uninitiated. And\nwe'll discuss more about it in the rest of the article.",[10,72,73,74,77],{},"We will also shed light on how to fix the dreaded\n",[21,75,76],{},"ImportError: attempted relative import with no known parent package'"," error\nmessage you might have stumbled upon. And just to let you know, the primary\nfocus of this article will be to understand the said error & figure out why\nPython throws such tantrums some times.",[10,79,80],{},"That said, towards the end of the article you should've a better idea about;",[82,83,84,97,104],"ol",{},[85,86,87,92,93,96],"li",{},[41,88,91],{"href":89,"rel":90},"https:\u002F\u002Fdocs.python.org\u002F3\u002Ftutorial\u002Fmodules.html",[45],"Python Modules"," & its\n",[21,94,95],{},"import"," system.",[85,98,99,100,103],{},"Organising your Python project's source code properly so as to not face its\n",[21,101,102],{},"ImportError"," tantrums.",[85,105,106,107,110,111,116],{},"The ",[21,108,109],{},"python"," Interpreter in the\n",[41,112,115],{"href":113,"rel":114},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCommand-line_interface",[45],"Command-Line Interface (CLI)",".",[118,119,121],"h2",{"id":120},"understanding-python-modules-with-a-hands-on-approach","Understanding Python Modules With a Hands-On Approach",[10,123,124,125,129,130,135,136,141],{},"Depending on how you look at it, Python modules will either be ",[126,127,128],"strong",{},"VERY","\nconfusing to you or a complete game-changer! If you asked me, I personally\nprefer how the other languages like JavaScript & Golang handles their modular\nfile imports. Here's where you can read more about\n",[41,131,134],{"href":132,"rel":133},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FGuide\u002FModules",[45],"ES6 JavaScript Modules","\n& ",[41,137,140],{"href":138,"rel":139},"https:\u002F\u002Fgo.dev\u002Fblog\u002Fusing-go-modules",[45],"Go Modules"," if you're interested in\nthem.",[10,143,144],{},"But without side-tracking much let's head back to our brief lesson Python\nModules.",[10,146,147,148,153],{},"Below we've a very close-to-real-world replication of what an example\n",[41,149,152],{"href":150,"rel":151},"https:\u002F\u002Ffastapi.tiangolo.com",[45],"FastAPI"," project is structured like. Each Python\nfiles contain some functional aspect of the end-product hence making the most\nout of a modular approach.",[14,155,159],{"className":156,"code":157,"language":158,"meta":19,"style":19},"language-bash shiki shiki-themes everforest-dark",".     # root of the project's repository\n├── config     # package containing constant config files like DB URLs\n│   ├── loaders.py\n│   ├── settings.py\n│   └── ...     # more such modules\n├── ...     # more such sub-packages each with its own set of modules\n├── routes     # package containing modules with the routes of the API\n│   ├── login.py     # example route for the \"login\" API endpoint\n│   ├── admin.py     # another example route\n│   └── ...     # more example routes as mentioned above\n├── main.py     # the entrypoint file which will programatically execute the webserver\n└── requirements.py     # the dependencies file for the project\n","bash",[21,160,161,170,182,194,204,218,228,239,252,265,277,288],{"__ignoreMap":19},[24,162,163,166],{"class":26,"line":27},[24,164,116],{"class":165},"sySyC",[24,167,169],{"class":168},"s67c6","     # root of the project's repository\n",[24,171,172,176,179],{"class":26,"line":33},[24,173,175],{"class":174},"sRC7j","├──",[24,177,178],{"class":165}," config",[24,180,181],{"class":168},"     # package containing constant config files like DB URLs\n",[24,183,185,188,191],{"class":26,"line":184},3,[24,186,187],{"class":174},"│",[24,189,190],{"class":165},"   ├──",[24,192,193],{"class":165}," loaders.py\n",[24,195,197,199,201],{"class":26,"line":196},4,[24,198,187],{"class":174},[24,200,190],{"class":165},[24,202,203],{"class":165}," settings.py\n",[24,205,207,209,212,215],{"class":26,"line":206},5,[24,208,187],{"class":174},[24,210,211],{"class":165},"   └──",[24,213,214],{"class":165}," ...",[24,216,217],{"class":168},"     # more such modules\n",[24,219,221,223,225],{"class":26,"line":220},6,[24,222,175],{"class":174},[24,224,214],{"class":165},[24,226,227],{"class":168},"     # more such sub-packages each with its own set of modules\n",[24,229,231,233,236],{"class":26,"line":230},7,[24,232,175],{"class":174},[24,234,235],{"class":165}," routes",[24,237,238],{"class":168},"     # package containing modules with the routes of the API\n",[24,240,242,244,246,249],{"class":26,"line":241},8,[24,243,187],{"class":174},[24,245,190],{"class":165},[24,247,248],{"class":165}," login.py",[24,250,251],{"class":168},"     # example route for the \"login\" API endpoint\n",[24,253,255,257,259,262],{"class":26,"line":254},9,[24,256,187],{"class":174},[24,258,190],{"class":165},[24,260,261],{"class":165}," admin.py",[24,263,264],{"class":168},"     # another example route\n",[24,266,268,270,272,274],{"class":26,"line":267},10,[24,269,187],{"class":174},[24,271,211],{"class":165},[24,273,214],{"class":165},[24,275,276],{"class":168},"     # more example routes as mentioned above\n",[24,278,280,282,285],{"class":26,"line":279},11,[24,281,175],{"class":174},[24,283,284],{"class":165}," main.py",[24,286,287],{"class":168},"     # the entrypoint file which will programatically execute the webserver\n",[24,289,291,294,297],{"class":26,"line":290},12,[24,292,293],{"class":174},"└──",[24,295,296],{"class":165}," requirements.py",[24,298,299],{"class":168},"     # the dependencies file for the project\n",[10,301,302,303,311,312,315,316,318],{},"While our imaginary project contains a lot of\n",[41,304,307,308],{"href":305,"rel":306},"https:\u002F\u002Fdocs.python.org\u002F3\u002Ftutorial\u002Fmodules.html#packages",[45],"Python ",[53,309,310],{},"Packages",",\nwhat we need to look at is the ",[21,313,314],{},"main.py"," file. Since Python has no opinion about\nwhat an \"entrypoint\" should be like, by convention its usually named ",[21,317,314],{},"\nfile.",[10,320,321,322,324,325,332,333,335],{},"This ",[21,323,314],{}," file is responsible for importing all the necessary modules from\naround the project's repository & invoke ",[41,326,329],{"href":327,"rel":328},"https:\u002F\u002Fwww.uvicorn.org",[45],[21,330,331],{},"uvicorn"," (a\nfast ASGI webserver) to start the web server. And to give you a general idea of\nthe contents of our ",[21,334,314],{}," here's a minimal example:",[14,337,340],{"className":338,"code":339,"language":109,"meta":19,"style":19},"language-python shiki shiki-themes everforest-dark","from uvicorn\nfrom fastapi import FastAPI\n\nfrom .routes import login\n# import the rest of the API routes\n\nfrom .config import info\n# import the rest of the static information\n\n# Instantiate the FastAPI instance which \"uvicorn\" will understand\napp = FastAPI()\n\n# Ensure the FastAPI recognises the URL endpoints\napp.include_router(login.router)\n\nif __name__ == \"__main__\":\n    # Run \"uvicorn\" programmatically for debugging reasons & for a more fine-tuned control\n    uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n",[21,341,342,352,365,371,387,392,396,410,415,419,424,439,443,449,468,473,491,497],{"__ignoreMap":19},[24,343,344,348],{"class":26,"line":27},[24,345,347],{"class":346},"safYi","from",[24,349,351],{"class":350},"sY0Nt"," uvicorn\n",[24,353,354,357,360,362],{"class":26,"line":33},[24,355,347],{"class":356},"s9lfW",[24,358,359],{"class":350}," fastapi ",[24,361,95],{"class":356},[24,363,364],{"class":350}," FastAPI\n",[24,366,367],{"class":26,"line":184},[24,368,370],{"emptyLinePlaceholder":369},true,"\n",[24,372,373,375,379,382,384],{"class":26,"line":196},[24,374,347],{"class":356},[24,376,378],{"class":377},"s3WQq"," .",[24,380,381],{"class":350},"routes ",[24,383,95],{"class":356},[24,385,386],{"class":350}," login\n",[24,388,389],{"class":26,"line":206},[24,390,391],{"class":168},"# import the rest of the API routes\n",[24,393,394],{"class":26,"line":220},[24,395,370],{"emptyLinePlaceholder":369},[24,397,398,400,402,405,407],{"class":26,"line":230},[24,399,347],{"class":356},[24,401,378],{"class":377},[24,403,404],{"class":350},"config ",[24,406,95],{"class":356},[24,408,409],{"class":350}," info\n",[24,411,412],{"class":26,"line":241},[24,413,414],{"class":168},"# import the rest of the static information\n",[24,416,417],{"class":26,"line":254},[24,418,370],{"emptyLinePlaceholder":369},[24,420,421],{"class":26,"line":267},[24,422,423],{"class":168},"# Instantiate the FastAPI instance which \"uvicorn\" will understand\n",[24,425,426,429,433,436],{"class":26,"line":279},[24,427,428],{"class":350},"app ",[24,430,432],{"class":431},"sDOmQ","=",[24,434,435],{"class":174}," FastAPI",[24,437,438],{"class":350},"()\n",[24,440,441],{"class":26,"line":290},[24,442,370],{"emptyLinePlaceholder":369},[24,444,446],{"class":26,"line":445},13,[24,447,448],{"class":168},"# Ensure the FastAPI recognises the URL endpoints\n",[24,450,452,455,457,460,463,465],{"class":26,"line":451},14,[24,453,454],{"class":350},"app",[24,456,116],{"class":377},[24,458,459],{"class":174},"include_router",[24,461,462],{"class":350},"(login",[24,464,116],{"class":377},[24,466,467],{"class":350},"router)\n",[24,469,471],{"class":26,"line":470},15,[24,472,370],{"emptyLinePlaceholder":369},[24,474,476,479,482,485,488],{"class":26,"line":475},16,[24,477,478],{"class":346},"if",[24,480,481],{"class":350}," __name__ ",[24,483,484],{"class":431},"==",[24,486,487],{"class":165}," \"__main__\"",[24,489,490],{"class":350},":\n",[24,492,494],{"class":26,"line":493},17,[24,495,496],{"class":168},"    # Run \"uvicorn\" programmatically for debugging reasons & for a more fine-tuned control\n",[24,498,500,503,505,508,511,513,516,519,521,524],{"class":26,"line":499},18,[24,501,502],{"class":350},"    uvicorn",[24,504,116],{"class":377},[24,506,507],{"class":174},"run",[24,509,510],{"class":350},"(app, host",[24,512,432],{"class":431},[24,514,515],{"class":165},"\"0.0.0.0\"",[24,517,518],{"class":350},", port",[24,520,432],{"class":431},[24,522,523],{"class":356},"8000",[24,525,526],{"class":350},")\n",[10,528,529,530,533],{},"And now I bet any intermediate Python programmers would think they could try\nexecuting the ",[21,531,532],{},"python main.py"," set of commands & call it a day. But sorry to\nbreak it you, there's a little surprise waiting for you!",[10,535,536],{},"If you're learning to code, I suggest copying the code snippet above & try\nexecuting it by following the instructions as laid down in this article till\nnow. Not only will get some practice writing code but you'll also get used to\nseeing your code crash when you believe it shouldn't do so.",[10,538,539,540,542],{},"That said if you tried executing the code snippet with the command\n",[21,541,532],{},", Python will cry & throw you an error message which looks\nsimilar to the one below:",[14,544,546],{"className":16,"code":545,"language":18,"meta":19,"style":19},"Traceback (most recent call last):\n  File \"\u002F...\u002Fsrc\u002Fmain.py\", line #, in \u003Cmodule>\n    from .routes import login\nImportError: attempted relative import with no known parent package\n",[21,547,548,553,558,563],{"__ignoreMap":19},[24,549,550],{"class":26,"line":27},[24,551,552],{},"Traceback (most recent call last):\n",[24,554,555],{"class":26,"line":33},[24,556,557],{},"  File \"\u002F...\u002Fsrc\u002Fmain.py\", line #, in \u003Cmodule>\n",[24,559,560],{"class":26,"line":184},[24,561,562],{},"    from .routes import login\n",[24,564,565],{"class":26,"line":196},[24,566,567],{},"ImportError: attempted relative import with no known parent package\n",[10,569,570],{},"You try to scratch you head because you're pretty sure there's nothing wrong\nwith the source code, yet you don't understand why does the code crash! Well,\nPython isn't wrong & neither are you (well to an extent at least)!",[10,572,573,574],{},"If you want to learn more about structuring large FastAPI projects, take a look\nat the documentations on -\n",[41,575,578],{"href":576,"rel":577},"https:\u002F\u002Ffastapi.tiangolo.com\u002Ftutorial\u002Fbigger-applications",[45],"\"Building Larger Applications - Multiple Files\"",[10,580,581,582,584],{},"Any way what went wrong here is the way the ",[21,583,109],{}," Interpreter was invoked in\nthe CLI environment. We'll get to the core issue at hand eventually but before\nthat I believe it's necessary to understand some stuff beforehand.",[10,586,587,588,591,592,594],{},"For example, take a second look at the code snippet I shared above & you'll see\nthe ",[21,589,590],{},"if __name__ == \"__main__\":"," block. For many Python programmers just\nstarting out, this block of code is ",[126,593,128],{}," confusing, yet they see it\neverywhere used across almost all Python projects. Hence, the next section takes\na deeper dive in to explaining that concept.",[10,596,597,598,600,601,116],{},"But to give you a gist, when a Python script is executed, the ",[21,599,109],{},"\nInterpreter understands the context of execution i.e if the executed file is\neither a standalone script or a module based on the value of ",[21,602,603],{},"__name__",[10,605,606,607,610,611,613,614,116],{},"Regardless, before you proceed with the rest of the article I suggest giving the\nofficial documentations on\n",[41,608,91],{"href":89,"rel":609},[45]," a thorough\nread. It'll give you a better idea about why the ",[21,612,590],{},"\nblock is necessary when invoking Python Modules as a ",[53,615,616],{},"script",[118,618,620,621,623],{"id":619},"how-does-the-value-of-__name__-change-based-on-the-execution-context","How Does the Value of ",[21,622,603],{}," Change Based on the Execution Context",[10,625,626,627,629,630,632],{},"In the previous section we briefly mentioned the ",[21,628,590],{},"\nblock & how it helps the ",[21,631,109],{}," Interpreter understand the context of\nexecution. But in this section of the article we'll try to understand it in a\nmore in-depth manner.",[10,634,635,636,639,640,643],{},"So as we know Python is capable of executing any Python files disregarding the\nconcept of \"entrypoint\" like other languages have. In that case how would the\nInterpreter properly differentiate \"",[53,637,638],{},"a module to be imported into the namespace\nwithout executing it's content","\" & \"",[53,641,642],{},"executing the contents of the file as is","\"?",[10,645,646,647,649],{},"That's where the value of ",[21,648,603],{}," comes handy!",[10,651,652,653,655,656,658,659,661,662,664,665,667,668,670,671,673],{},"So each Python Modules is injected with a ",[21,654,603],{}," in their respective\nnamespaces during execution. If the said Module is executed directly on the CLI\nenvironment, the value of ",[21,657,603],{}," is assigned to the filename of that\nspecific module. For example, executing this command ",[21,660,532],{}," would\nassign the value of ",[21,663,603],{}," to ",[21,666,314],{},". And hence, the ",[21,669,109],{}," Interpreter\nidentifies ",[21,672,314],{}," as a standalone script. Such scripts do not have access to\nother Python files by default. Although you can access other standalone Python\nscripts inside another script's namespace as well & I'll leave that topic for\nanother article.",[10,675,676,677,679,680,682,683,686],{},"That said, on the other hand, if a Python Module is imported as another module\nusing the ",[21,678,95],{}," statement, then the ",[21,681,603],{}," value is assigned to the\nstring ",[21,684,685],{},"\"__main__\"",". And in doing so, the imported module's namespace is\naccessible to the executed module as well!",[10,688,689,690,692],{},"People just learning to code might find this concept ",[126,691,128],{}," confusing & I'm\nwell aware of it. I was confused of it too once upon a time but bear with it for\na while & its totally worth understanding it. Having a strong grasp on Python\nModules is perhaps by far the most important concept to learn well. Hence,\ntowards the end of the article I have shared some resources you might want to\nrefer to for further studying.",[10,694,695,696,698,699,702,703,706,707,709,710,712],{},"That said, there's a way to execute Python Module as scripts from the CLI\nenvironment. With respect to the same ",[21,697,314],{}," file from our imaginary FastAPI\nproject above, you can then run this command - ",[21,700,701],{},"python -m main",". Notice the ",[21,704,705],{},"-m","\nflag passed to the ",[21,708,109],{}," Interpreter which signals to the interpreter to run\n",[21,711,314],{}," file as a Module and not as a standalone script!",[10,714,715,716,718,719,721],{},"In other words, you no have to face the weird ",[21,717,102],{}," messages anymore\nbecause ",[21,720,314],{}," is treated as any other Module & the namespaces of the other\nModules are always accessible to it.",[10,723,724,725,730,731,733],{},"Regardless I'm quite impressed how well developed the functionality is! So hats\noff to the ",[41,726,729],{"href":727,"rel":728},"https:\u002F\u002Fgithub.com\u002Forgs\u002Fpython\u002Fpeople",[45],"Python Core Developers"," who\nbuilt the feature into the ",[21,732,109],{}," Interpreter.",[118,735,737],{"id":736},"recommended-resources-for-further-reading","Recommended Resources for Further Reading",[10,739,740,741,744,745,748],{},"I hope you now have a better understanding on how to execute either Python\n",[53,742,743],{},"Scripts"," or ",[53,746,747],{},"Modules",". If you still feel there are a couple of holes in your\nunderstanding I've a few suggestions which might be worth checking out. Give\nthese recommended resources a thorough read & then come back to this article to\nfill the gaps in understanding more about Python Modules.",[750,751,752,760,768,776,783],"ul",{},[85,753,754,759],{},[41,755,758],{"href":756,"rel":757},"https:\u002F\u002Frealpython.com\u002Fpython-modules-packages",[45],"Python Modules and Packages – An Introduction","\nby Real Python",[85,761,762,767],{},[41,763,766],{"href":764,"rel":765},"https:\u002F\u002Fyoutu.be\u002FCqvZ3vGoGs0",[45],"Python Tutorial for Beginners 9: Import Modules and Exploring The Standard Library","\nby Corey Schafer",[85,769,770,775],{},[41,771,774],{"href":772,"rel":773},"https:\u002F\u002Fdocs.python.org\u002F3\u002Ftutorial\u002Finterpreter.html",[45],"Using the Python Interpreter","\nof the official Python Tutorial.",[85,777,778,759],{},[41,779,782],{"href":780,"rel":781},"https:\u002F\u002Frealpython.com\u002Fpython-main-function",[45],"Defining Main Functions in Python",[85,784,785,798],{},[41,786,789,790,793,794,797],{"href":787,"rel":788},"https:\u002F\u002Fyoutu.be\u002FsugvnHA7ElY",[45],"Python Tutorial: if ",[126,791,792],{},"name"," == \"",[126,795,796],{},"main","\":"," by\nCorey Schafer",[800,801,802],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sySyC, html code.shiki .sySyC{--shiki-default:#DBBC7F}html pre.shiki code .s67c6, html code.shiki .s67c6{--shiki-default:#859289;--shiki-default-font-style:italic}html pre.shiki code .sRC7j, html code.shiki .sRC7j{--shiki-default:#A7C080}html pre.shiki code .safYi, html code.shiki .safYi{--shiki-default:#E67E80}html pre.shiki code .sY0Nt, html code.shiki .sY0Nt{--shiki-default:#D3C6AA}html pre.shiki code .s9lfW, html code.shiki .s9lfW{--shiki-default:#D699B6}html pre.shiki code .s3WQq, html code.shiki .s3WQq{--shiki-default:#859289}html pre.shiki code .sDOmQ, html code.shiki .sDOmQ{--shiki-default:#E69875}",{"title":19,"searchDepth":33,"depth":33,"links":804},[805,806,808],{"id":120,"depth":33,"text":121},{"id":619,"depth":33,"text":807},"How Does the Value of __name__ Change Based on the Execution Context",{"id":736,"depth":33,"text":737},{"url":810,"alt":811},"https:\u002F\u002Fik.imagekit.io\u002Fjarmos\u002Funderstanding-python-import-error-message.png?updatedAt=1702974989269","Understanding the \"ImportError\" Message in Python","Master Python module execution! Learn about modular programming, FastAPI project structuring, and resolving the \"ImportError: attempted relative import with no known parent package.\" Understand Python's `__name__` and execute modules correctly. Boost your Python skills! 🚀","md",{},"\u002Fblogs\u002Funderstanding-python-import-error-message","2021-03-24",{"title":5,"description":812},{"loc":815},"blogs\u002Funderstanding-python-import-error-message","QhPA-YJwPzGuyqgKfYAoxfABogQmMqIgoPFTSWCdxww",1788604450054]