{"id":1821,"date":"2024-11-01T21:44:21","date_gmt":"2024-11-01T16:14:21","guid":{"rendered":"https:\/\/geekpython.in\/?p=1821"},"modified":"2024-11-01T21:47:11","modified_gmt":"2024-11-01T16:17:11","slug":"circular-import-error-in-python","status":"publish","type":"post","link":"https:\/\/geekpython.in\/circular-import-error-in-python","title":{"rendered":"Fixing Circular Import Error in Python"},"content":{"rendered":"\n<p>Have you ever come across <strong>circular imports<\/strong> in Python? Well, it\u2019s a very common <a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_smell\" target=\"_blank\" rel=\"noopener\">code smell<\/a> that indicates something\u2019s wrong with the design or structure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Circular Import Example<\/h2>\n\n\n\n<p><strong>How does circular import occur?<\/strong> This import error usually occurs when two or more modules depending on each other try to import before fully initializing.<\/p>\n\n\n\n<p>Let\u2019s say we have two modules: <code>module_1.py<\/code> and <code>module_2.py<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nfrom module_2 import ModY\nclass ModX:\n    mody_obj = ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nfrom module_1 import ModX\nclass ModY:\n    modx_obj = ModX()<\/pre><\/div>\n\n\n\n<p>In the above code snippets, both <code>module_1<\/code> and <code>module_2<\/code> are mutually dependent on each other.<\/p>\n\n\n\n<p>The initialization of <code>mody_obj<\/code> in <code>module_1<\/code> depends on <code>module_2<\/code> and the initialization of <code>modx_obj<\/code> in <code>module_2<\/code> depends on <code>module_1<\/code>.<\/p>\n\n\n\n<p>This is what we call a circular dependency. Both modules will stuck in the import loops while attempting to load each other.<\/p>\n\n\n\n<p>If we run module_1.py, we\u2019ll get the following traceback.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:ps decode:true \">Traceback (most recent call last):\n  File \"module_1.py\", line 1, in &lt;module&gt;\n    from module_2 import ModY\n  File \"module_2.py\", line 1, in &lt;module&gt;\n    from module_1 import ModX\n  File \"module_1.py\", line 1, in &lt;module&gt;\n    from module_2 import ModY\nImportError: cannot import name 'ModY' from partially initialized module 'module_2' (most likely due to a circular import)<\/pre><\/div>\n\n\n\n<p>This error explains the situation of circular import. When the program attempted to import <code>ModY<\/code> from <code>module_2<\/code>, at that time <code>module_2<\/code> wasn\u2019t fully initialized (due to another import statement that attempts to import <code>ModX<\/code> from <code>module_1<\/code>).<\/p>\n\n\n\n<p><strong>How to fix circular imports in Python?<\/strong> There are different ways to get rid of circular imports in Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fix Circular Imports in Python<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<p class=\"responsive-video-wrap clr\"><iframe loading=\"lazy\" title=\"How to fix circular imports in Python | 2MinutesPy\" width=\"1200\" height=\"675\" src=\"https:\/\/www.youtube.com\/embed\/zRwg7w93klA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<\/div><figcaption class=\"wp-element-caption\"><strong>Summary Video<\/strong><\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Move code into a common file<\/h3>\n\n\n\n<p>We can move the code into a common file to avoid import errors and then try to import the modules from that file.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># main.py ----&gt; common file\nclass ModX:\n    pass\n\nclass ModY:\n    pass<\/pre><\/div>\n\n\n\n<p>In the above code snippet, we moved the classes <code>ModX<\/code> and <code>ModY<\/code> into a common file (<code>main.py<\/code>).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nfrom main import ModY\n\nclass Mod_X:\n    mody_obj = ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nfrom main import ModX\n\nclass Mod_Y:\n    modx_obj = ModX()<\/pre><\/div>\n\n\n\n<p>Now, <code>module_1<\/code> and <code>module_2<\/code> import the classes from <code>main<\/code> which fixes the circular import situation.<\/p>\n\n\n\n<p>There is a problem with this approach, sometimes the codebase is so large that it becomes risky to move the code into another file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Move the import to the end of the module<\/h3>\n\n\n\n<p>We can shift the import statement at the end of the module. This will give time to fully initialize the module before importing another module.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nclass ModX:\n   pass\n\nfrom module_2 import ModY\n\nclass Mod_X:\n   mody_obj = ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nclass ModY:\n   pass\n\nfrom module_1 import ModX<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Importing module within the class\/function scope<\/h3>\n\n\n\n<p>Importing modules within the class or function scope can avoid circular imports. This allows the module to be imported only when the class or function is invoked. It\u2019s relevant when we want to minimize memory use.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nclass ModX:\n  pass\n\nclass Mod_X:\n   from module_2 import ModY\n   mody_obj = ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nclass ModY:\n   pass\n\nclass Mod_Y:\n   from module_1 import ModX\n   modx_obj = ModX()<\/pre><\/div>\n\n\n\n<p>We moved the import statements within classes <code>Mod_X<\/code> and <code>Mod_Y<\/code> scope in <code>module_1<\/code> and <code>module_2<\/code> respectively.<\/p>\n\n\n\n<p>If we run either <code>module_1<\/code> or <code>module_2<\/code>, we\u2019ll not get a circular import error. However, this approach makes the class accessible only within the class\u2019s scope, so we can\u2019t leverage the import globally.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using module name\/alias<\/h3>\n\n\n\n<p>Using the module name or just an alias like this solves the problem. This allows both modules to load fully by deferring circular dependency until runtime.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nimport module_2 as m2\n\nclass ModX:\n    def __init__(self):\n        self.mody_obj = m2.ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nimport module_1 as m1\n\nclass ModY:\n    def __init__(self):\n        self.modx_obj = m1.ModX()<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Using importlib library<\/h3>\n\n\n\n<p>We can also use the <code>importlib<\/code> library to import the modules dynamically.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_1.py\nimport importlib\n\nclass ModX:\n    def __init__(self):\n        m2 = importlib.import_module('module_2')\n        self.mody_obj = m2.ModY()<\/pre><\/div>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \"># module_2.py\nimport importlib\n\nclass ModY:\n    def __init__(self):\n        m1 = importlib.import_module('module_1')\n        self.mody_obj = m1.ModX()<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Circular Imports in Python Packages<\/h2>\n\n\n\n<p>Usually, <strong>circular imports<\/strong> <strong>come from modules within the same package<\/strong>. In complex projects, the directory structure is also complex, with packages within packages.<\/p>\n\n\n\n<p>These packages and sub-packages contain <code>__init__.py<\/code> files to provide easier access to modules. That\u2019s where sometimes arises circular dependencies among modules unintentionally.<\/p>\n\n\n\n<p>We have the following directory structure.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex decode:true \">root_dir\/\n|- mainpkg\/\n|---- modpkg_x\/\n|-------- __init__.py\n|-------- module_1.py\n|-------- module_1_1.py\n|---- modpkg_y\/\n|-------- __init__.py\n|-------- module_2.py\n|---- __init__.py\n|- main.py<\/pre><\/div>\n\n\n\n<p>We have a package <code>mainpkg<\/code> and a <code>main.py<\/code> file. We have two sub-packages <code>modpkg_x<\/code> and <code>modpkg_y<\/code> within <code>mainpkg<\/code>.<\/p>\n\n\n\n<p>Here\u2019s what each Python file within <code>modpkg_x<\/code> and <code>modpkg_y<\/code> looks like.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>modpkg_x<\/code>\/<code>__init__.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from .module_1 import ModX\nfrom .module_1_1 import ModA<\/pre><\/div>\n\n\n\n<p>This file imports both classes (<code>ModX<\/code> and <code>ModA<\/code>) from <code>module_1<\/code> and <code>module_1_1<\/code>.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>modpkg_x<\/code>\/<code>module_1.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from ..modpkg_y.module_2 import ModY\nclass ModX:\n    mody_obj = ModY()<\/pre><\/div>\n\n\n\n<p>The <code>module_1<\/code> imports a class <code>ModY<\/code> from <code>module_2<\/code>.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>modpkg_x<\/code>\/<code>module_1_1.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">class ModA:\n    pass<\/pre><\/div>\n\n\n\n<p>The <code>module_1_1<\/code> imports nothing. It is not dependent on any module.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>modpkg_y<\/code>\/<code>__init__.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from .module_2 import ModY<\/pre><\/div>\n\n\n\n<p>This file imports the class <code>ModY<\/code> from <code>module_2<\/code>.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>modpkg_y<\/code>\/<code>module_2.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from ..modpkg_x.module_1_1 import ModA\nclass ModY:\n    moda_obj = ModA()<\/pre><\/div>\n\n\n\n<p>The <code>module_2<\/code> imports a class <code>ModA<\/code> from the <code>module_1_1<\/code>.<\/p>\n\n\n\n<p>We have the following code within the <code>main.py<\/code> file.<\/p>\n\n\n\n<p><code>root_dir<\/code>\/<code>main.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from mainpkg.modpkg_y.module_2 import ModY\n\ndef mody():\n    y_obj = ModY()\n\nmody()<\/pre><\/div>\n\n\n\n<p>The <code>main<\/code> file imports a class <code>ModY<\/code> from <code>module_2<\/code>. This file is dependent on <code>module_2<\/code>.<\/p>\n\n\n\n<p>If we visualize the import cycle here, it would look like the following ignoring the <code>__init__.py<\/code> files within the <code>modpkg_x<\/code> and <code>modpkg_y<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image.png\" alt=\"Import cycle\" class=\"wp-image-1822\" srcset=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image.png 1920w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-300x169.png 300w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1024x576.png 1024w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-768x432.png 768w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1536x864.png 1536w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-800x450.png 800w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/figure>\n\n\n\n<p>We can see that the <code>main<\/code> file depends on <code>module_2<\/code>, <code>module_1<\/code> also depends on <code>module_2<\/code> and <code>module_2<\/code> depends on <code>module_1_1<\/code>. There is no import cycle.<\/p>\n\n\n\n<p>But you know, modules depend on their <code>__init__.py<\/code> file, so the <code>__init__.py<\/code> file initializes first, and modules are re-imported.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1.png\" alt=\"Import cycle changed due to __init__.py file\" class=\"wp-image-1823\" srcset=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1.png 1920w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1-300x169.png 300w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1-1024x576.png 1024w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1-768x432.png 768w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1-1536x864.png 1536w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-1-800x450.png 800w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/figure>\n\n\n\n<p>This is what the import cycle looks like now.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2.png\" alt=\"Final import cycle\" class=\"wp-image-1824\" srcset=\"https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2.png 1920w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2-300x169.png 300w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2-1024x576.png 1024w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2-768x432.png 768w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2-1536x864.png 1536w, https:\/\/geekpython.in\/wp-content\/uploads\/2024\/11\/image-2-800x450.png 800w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/figure>\n\n\n\n<p>This made <code>module_1_1<\/code> depend on <code>module_1<\/code>, which is a fake dependency.<\/p>\n\n\n\n<p>If this is the case, empty the sub-packages <code>__init__.py<\/code> files and using a separate <code>__init__.py<\/code> file can help by centralizing imports at the package level.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex mark:10-11 decode:true \">root_dir\/\n|- mainpkg\/\n|---- modpkg_x\/\n|-------- __init__.py  # empty file\n|-------- module_1.py\n|-------- module_1_1.py\n|---- modpkg_y\/\n|-------- __init__.py  # empty file\n|-------- module_2.py\n|---- subpkg\/\n|-------- __init__.py\n|---- __init__.py\n|- main.py<\/pre><\/div>\n\n\n\n<p>In this structure, we added another sub-package <code>subpkg<\/code> within <code>mainpkg<\/code>.<\/p>\n\n\n\n<p><code>mainpkg<\/code>\/<code>subpkg<\/code>\/<code>__init__.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \">from ..modpkg_x.module_1 import ModX\nfrom ..modpkg_x.module_1_1 import ModA\nfrom ..modpkg_y.module_2 import ModY<\/pre><\/div>\n\n\n\n<p>This will allow internal modules to import from a single source, reducing the need for cross-imports.<\/p>\n\n\n\n<p>Now we can update the import statement within the <code>main.py<\/code> file.<\/p>\n\n\n\n<p><code>root_dir<\/code>\/<code>main.py<\/code><\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python mark:1 decode:true \">from mainpkg.subpkg import ModY\ndef mody():\n    y_obj = ModY()\n\nmody()<\/pre><\/div>\n\n\n\n<p>This solves the problem of circular dependency between the modules within the same package.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Circular dependency or import in Python is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_smell\" target=\"_blank\" rel=\"noopener\"><strong>code smell<\/strong><\/a> which is an indication of serious re-structuring and refactoring of the code.<\/p>\n\n\n\n<p>You can try any of these above-mentioned ways to avoid circular dependency in Python.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>That\u2019s all for now.<\/strong><\/p>\n\n\n\n<p><strong>Keep Coding\u270c\u270c.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever come across circular imports in Python? Well, it\u2019s a very common code smell that indicates something\u2019s wrong with the design or structure. Circular Import Example How does circular import occur? This import error usually occurs when two or more modules depending on each other try to import before fully initializing. Let\u2019s say [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1828,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[2,71],"tags":[31],"class_list":["post-1821","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","category-misc","tag-python3","entry","has-media"],"_links":{"self":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1821","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/comments?post=1821"}],"version-history":[{"count":4,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1821\/revisions"}],"predecessor-version":[{"id":1830,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1821\/revisions\/1830"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media\/1828"}],"wp:attachment":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media?parent=1821"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/categories?post=1821"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/tags?post=1821"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}