flask/flask-docs/patterns/packages.html
Edgar Alvarado Taleno 77f3f78332 Preparar para publicar en Read the Docs
Signed-off-by: Edgar Alvarado Taleno <edgar.alvaradotaleno@ucr.ac.cr>
2025-04-10 15:52:02 -06:00

226 lines
No EOL
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" data-content_root="../">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Large Applications as Packages &#8212; Flask Documentation (3.2.x)</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=6625fa76" />
<link rel="stylesheet" type="text/css" href="../_static/flask.css?v=b87c8d14" />
<script src="../_static/documentation_options.js?v=56528222"></script>
<script src="../_static/doctools.js?v=9bcbadda"></script>
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
<script data-project="flask" data-version="3.2.x" src="../_static/describe_version.js?v=fa7f30d0"></script>
<link rel="icon" href="../_static/shortcut-icon.png"/>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Application Factories" href="appfactories.html" />
<link rel="prev" title="Patterns for Flask" href="index.html" />
</head><body>
<div class="related" role="navigation" aria-label="Related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="appfactories.html" title="Application Factories"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="index.html" title="Patterns for Flask"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="../index.html">Flask Documentation (3.2.x)</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Patterns for Flask</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Large Applications as Packages</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="large-applications-as-packages">
<h1>Large Applications as Packages<a class="headerlink" href="#large-applications-as-packages" title="Link to this heading"></a></h1>
<p>Imagine a simple flask application structure that looks like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="n">yourapplication</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
</pre></div>
</div>
<p>While this is fine for small applications, for larger applications
its a good idea to use a package instead of a module.
The <a class="reference internal" href="../tutorial/index.html"><span class="doc">Tutorial</span></a> is structured to use the package pattern,
see the <a class="reference external" href="https://github.com/pallets/flask/tree/main/examples/tutorial">example code</a>.</p>
<section id="simple-packages">
<h2>Simple Packages<a class="headerlink" href="#simple-packages" title="Link to this heading"></a></h2>
<p>To convert that into a larger one, just create a new folder
<code class="file docutils literal notranslate"><span class="pre">yourapplication</span></code> inside the existing one and move everything below it.
Then rename <code class="file docutils literal notranslate"><span class="pre">yourapplication.py</span></code> to <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>. (Make sure to delete
all <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> files first, otherwise things would most likely break)</p>
<p>You should then end up with something like that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="o">/</span><span class="n">yourapplication</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
</pre></div>
</div>
<p>But how do you run your application now? The naive <code class="docutils literal notranslate"><span class="pre">python</span>
<span class="pre">yourapplication/__init__.py</span></code> will not work. Lets just say that Python
does not want modules in packages to be the startup file. But that is not
a big problem, just add a new file called <code class="file docutils literal notranslate"><span class="pre">pyproject.toml</span></code> next to the inner
<code class="file docutils literal notranslate"><span class="pre">yourapplication</span></code> folder with the following contents:</p>
<div class="highlight-toml notranslate"><div class="highlight"><pre><span></span><span class="k">[project]</span>
<span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;yourapplication&quot;</span>
<span class="n">dependencies</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
<span class="w"> </span><span class="s2">&quot;flask&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="k">[build-system]</span>
<span class="n">requires</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;flit_core&lt;4&quot;</span><span class="p">]</span>
<span class="n">build-backend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;flit_core.buildapi&quot;</span>
</pre></div>
</div>
<p>Install your application so it is importable:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>$ pip install -e .
</pre></div>
</div>
<p>To use the <code class="docutils literal notranslate"><span class="pre">flask</span></code> command and run your application you need to set
the <code class="docutils literal notranslate"><span class="pre">--app</span></code> option that tells Flask where to find the application
instance:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>$ flask --app yourapplication run
</pre></div>
</div>
<p>What did we gain from this? Now we can restructure the application a bit
into multiple modules. The only thing you have to remember is the
following quick checklist:</p>
<ol class="arabic simple">
<li><p>the <code class="code docutils literal notranslate"><span class="pre">Flask</span></code> application object creation has to be in the
<code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> file. That way each module can import it safely and the
<code class="code docutils literal notranslate"><span class="pre">__name__</span></code> variable will resolve to the correct package.</p></li>
<li><p>all the view functions (the ones with a <a class="reference internal" href="../api.html#flask.Flask.route" title="flask.Flask.route"><code class="xref py py-meth docutils literal notranslate"><span class="pre">route()</span></code></a>
decorator on top) have to be imported in the <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> file.
Not the object itself, but the module it is in. Import the view module
<strong>after the application object is created</strong>.</p></li>
</ol>
<p>Heres an example <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">flask</span><span class="w"> </span><span class="kn">import</span> <span class="n">Flask</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">yourapplication.views</span>
</pre></div>
</div>
<p>And this is what <code class="file docutils literal notranslate"><span class="pre">views.py</span></code> would look like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">yourapplication</span><span class="w"> </span><span class="kn">import</span> <span class="n">app</span>
<span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">index</span><span class="p">():</span>
<span class="k">return</span> <span class="s1">&#39;Hello World!&#39;</span>
</pre></div>
</div>
<p>You should then end up with something like that:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">/</span><span class="n">yourapplication</span>
<span class="n">pyproject</span><span class="o">.</span><span class="n">toml</span>
<span class="o">/</span><span class="n">yourapplication</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">views</span><span class="o">.</span><span class="n">py</span>
<span class="o">/</span><span class="n">static</span>
<span class="n">style</span><span class="o">.</span><span class="n">css</span>
<span class="o">/</span><span class="n">templates</span>
<span class="n">layout</span><span class="o">.</span><span class="n">html</span>
<span class="n">index</span><span class="o">.</span><span class="n">html</span>
<span class="n">login</span><span class="o">.</span><span class="n">html</span>
<span class="o">...</span>
</pre></div>
</div>
<div class="admonition-circular-imports admonition">
<p class="admonition-title">Circular Imports</p>
<p>Every Python programmer hates them, and yet we just added some:
circular imports (Thats when two modules depend on each other. In this
case <code class="file docutils literal notranslate"><span class="pre">views.py</span></code> depends on <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code>). Be advised that this is a
bad idea in general but here it is actually fine. The reason for this is
that we are not actually using the views in <code class="file docutils literal notranslate"><span class="pre">__init__.py</span></code> and just
ensuring the module is imported and we are doing that at the bottom of
the file.</p>
</div>
</section>
<section id="working-with-blueprints">
<h2>Working with Blueprints<a class="headerlink" href="#working-with-blueprints" title="Link to this heading"></a></h2>
<p>If you have larger applications its recommended to divide them into
smaller groups where each group is implemented with the help of a
blueprint. For a gentle introduction into this topic refer to the
<a class="reference internal" href="../blueprints.html"><span class="doc">Modular Applications with Blueprints</span></a> chapter of the documentation.</p>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<span id="sidebar-top"></span>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/flask-vertical.png" alt="Logo of Flask"/>
</a></p>
<h3>Contents</h3>
<ul>
<li><a class="reference internal" href="#">Large Applications as Packages</a><ul>
<li><a class="reference internal" href="#simple-packages">Simple Packages</a></li>
<li><a class="reference internal" href="#working-with-blueprints">Working with Blueprints</a></li>
</ul>
</li>
</ul>
<h3>Navigation</h3>
<ul>
<li><a href="../index.html">Overview</a>
<ul>
<li><a href="index.html">Patterns for Flask</a>
<ul>
<li>Previous: <a href="index.html" title="previous chapter">Patterns for Flask</a>
<li>Next: <a href="appfactories.html" title="next chapter">Application Factories</a></ul>
</li>
</ul>
</li>
</ul>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><div id="ethical-ad-placement"></div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2010 Pallets.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.1.3.
</div>
</body>
</html>