evennia/docs/5.x/_modules/django/test/client.html
2025-07-01 10:01:48 +02:00

1925 lines
No EOL
224 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>django.test.client &#8212; Evennia latest documentation</title>
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=d75fae25" />
<link rel="stylesheet" type="text/css" href="../../../_static/nature.css?v=245aff17" />
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/documentation_options.js?v=c6e86fd7"></script>
<script src="../../../_static/doctools.js?v=9bcbadda"></script>
<script src="../../../_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<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="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" accesskey="U">Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">django.test.client</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<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><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for django.test.client</h1><div class="highlight"><pre>
<span></span><span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">mimetypes</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">collections.abc</span><span class="w"> </span><span class="kn">import</span> <span class="n">Iterable</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">copy</span><span class="w"> </span><span class="kn">import</span> <span class="n">copy</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">functools</span><span class="w"> </span><span class="kn">import</span> <span class="n">partial</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">http</span><span class="w"> </span><span class="kn">import</span> <span class="n">HTTPStatus</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">importlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">import_module</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">io</span><span class="w"> </span><span class="kn">import</span> <span class="n">BytesIO</span><span class="p">,</span> <span class="n">IOBase</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">urllib.parse</span><span class="w"> </span><span class="kn">import</span> <span class="n">unquote_to_bytes</span><span class="p">,</span> <span class="n">urljoin</span><span class="p">,</span> <span class="n">urlparse</span><span class="p">,</span> <span class="n">urlsplit</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">asgiref.sync</span><span class="w"> </span><span class="kn">import</span> <span class="n">sync_to_async</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.conf</span><span class="w"> </span><span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.handlers.asgi</span><span class="w"> </span><span class="kn">import</span> <span class="n">ASGIRequest</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.handlers.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseHandler</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.handlers.wsgi</span><span class="w"> </span><span class="kn">import</span> <span class="n">LimitedStream</span><span class="p">,</span> <span class="n">WSGIRequest</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.serializers.json</span><span class="w"> </span><span class="kn">import</span> <span class="n">DjangoJSONEncoder</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.core.signals</span><span class="w"> </span><span class="kn">import</span> <span class="n">got_request_exception</span><span class="p">,</span> <span class="n">request_finished</span><span class="p">,</span> <span class="n">request_started</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.db</span><span class="w"> </span><span class="kn">import</span> <span class="n">close_old_connections</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.http</span><span class="w"> </span><span class="kn">import</span> <span class="n">HttpHeaders</span><span class="p">,</span> <span class="n">HttpRequest</span><span class="p">,</span> <span class="n">QueryDict</span><span class="p">,</span> <span class="n">SimpleCookie</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test</span><span class="w"> </span><span class="kn">import</span> <span class="n">signals</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.test.utils</span><span class="w"> </span><span class="kn">import</span> <span class="n">ContextList</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.urls</span><span class="w"> </span><span class="kn">import</span> <span class="n">resolve</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.encoding</span><span class="w"> </span><span class="kn">import</span> <span class="n">force_bytes</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.functional</span><span class="w"> </span><span class="kn">import</span> <span class="n">SimpleLazyObject</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.http</span><span class="w"> </span><span class="kn">import</span> <span class="n">urlencode</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.utils.regex_helper</span><span class="w"> </span><span class="kn">import</span> <span class="n">_lazy_re_compile</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;AsyncClient&quot;</span><span class="p">,</span>
<span class="s2">&quot;AsyncRequestFactory&quot;</span><span class="p">,</span>
<span class="s2">&quot;Client&quot;</span><span class="p">,</span>
<span class="s2">&quot;RedirectCycleError&quot;</span><span class="p">,</span>
<span class="s2">&quot;RequestFactory&quot;</span><span class="p">,</span>
<span class="s2">&quot;encode_file&quot;</span><span class="p">,</span>
<span class="s2">&quot;encode_multipart&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">BOUNDARY</span> <span class="o">=</span> <span class="s2">&quot;BoUnDaRyStRiNg&quot;</span>
<span class="n">MULTIPART_CONTENT</span> <span class="o">=</span> <span class="s2">&quot;multipart/form-data; boundary=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">BOUNDARY</span>
<span class="n">CONTENT_TYPE_RE</span> <span class="o">=</span> <span class="n">_lazy_re_compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;.*; charset=([\w-]+);?&quot;</span><span class="p">)</span>
<span class="c1"># Structured suffix spec: https://tools.ietf.org/html/rfc6838#section-4.2.8</span>
<span class="n">JSON_CONTENT_TYPE_RE</span> <span class="o">=</span> <span class="n">_lazy_re_compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;^application\/(.+\+)?json&quot;</span><span class="p">)</span>
<span class="n">REDIRECT_STATUS_CODES</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">(</span>
<span class="p">[</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">MOVED_PERMANENTLY</span><span class="p">,</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">FOUND</span><span class="p">,</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">SEE_OTHER</span><span class="p">,</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">TEMPORARY_REDIRECT</span><span class="p">,</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">PERMANENT_REDIRECT</span><span class="p">,</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">RedirectCycleError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The test client has been asked to follow a redirect loop.&quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">last_response</span><span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">last_response</span> <span class="o">=</span> <span class="n">last_response</span>
<span class="bp">self</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">last_response</span><span class="o">.</span><span class="n">redirect_chain</span>
<span class="k">class</span><span class="w"> </span><span class="nc">FakePayload</span><span class="p">(</span><span class="n">IOBase</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A wrapper around BytesIO that restricts what can be read since data from</span>
<span class="sd"> the network can&#39;t be sought and cannot be read outside of its content</span>
<span class="sd"> length. This makes sure that views can&#39;t do anything under the test client</span>
<span class="sd"> that wouldn&#39;t work in real life.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">initial_bytes</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__content</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">read_started</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">initial_bytes</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">initial_bytes</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span>
<span class="k">def</span><span class="w"> </span><span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="o">/</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">read_started</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">size</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">size</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span>
<span class="k">assert</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">&gt;=</span> <span class="n">size</span>
<span class="p">),</span> <span class="s2">&quot;Cannot read more than the available bytes from the HTTP incoming data.&quot;</span>
<span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">return</span> <span class="n">content</span>
<span class="k">def</span><span class="w"> </span><span class="nf">readline</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="o">/</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">read_started</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">size</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">or</span> <span class="n">size</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__len</span>
<span class="k">assert</span> <span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">&gt;=</span> <span class="n">size</span>
<span class="p">),</span> <span class="s2">&quot;Cannot read more than the available bytes from the HTTP incoming data.&quot;</span>
<span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">readline</span><span class="p">(</span><span class="n">size</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">return</span> <span class="n">content</span>
<span class="k">def</span><span class="w"> </span><span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">/</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">read_started</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unable to write a payload after it&#39;s been read&quot;</span><span class="p">)</span>
<span class="n">content</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__content</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">__len</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">closing_iterator_wrapper</span><span class="p">(</span><span class="n">iterable</span><span class="p">,</span> <span class="n">close</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">yield from</span> <span class="n">iterable</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="n">close</span><span class="p">()</span> <span class="c1"># will fire request_finished</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">aclosing_iterator_wrapper</span><span class="p">(</span><span class="n">iterable</span><span class="p">,</span> <span class="n">close</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">async</span> <span class="k">for</span> <span class="n">chunk</span> <span class="ow">in</span> <span class="n">iterable</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">chunk</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="n">close</span><span class="p">()</span> <span class="c1"># will fire request_finished</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">conditional_content_removal</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Simulate the behavior of most web servers by removing the content of</span>
<span class="sd"> responses for HEAD requests, 1xx, 204, and 304 responses. Ensure</span>
<span class="sd"> compliance with RFC 9112 Section 6.3.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="mi">100</span> <span class="o">&lt;=</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">&lt;</span> <span class="mi">200</span> <span class="ow">or</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">204</span><span class="p">,</span> <span class="mi">304</span><span class="p">):</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s2">&quot;HEAD&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">&quot;&quot;</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ClientHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> An HTTP Handler that can be used for testing purposes. Use the WSGI</span>
<span class="sd"> interface to compose requests, but return the raw HttpResponse object with</span>
<span class="sd"> the originating WSGIRequest attached to its ``wsgi_request`` attribute.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span> <span class="o">=</span> <span class="n">enforce_csrf_checks</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">):</span>
<span class="c1"># Set up middleware if needed. We couldn&#39;t do this earlier, because</span>
<span class="c1"># settings weren&#39;t available.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_middleware_chain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">load_middleware</span><span class="p">()</span>
<span class="n">request_started</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="n">request_started</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="n">environ</span><span class="o">=</span><span class="n">environ</span><span class="p">)</span>
<span class="n">request_started</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">WSGIRequest</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
<span class="c1"># sneaky little hack so that we can easily get round</span>
<span class="c1"># CsrfViewMiddleware. This makes life easier, and is probably</span>
<span class="c1"># required for backwards compatibility with external tests against</span>
<span class="c1"># admin views.</span>
<span class="n">request</span><span class="o">.</span><span class="n">_dont_enforce_csrf_checks</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span>
<span class="c1"># Request goes through middleware.</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_response</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="c1"># Simulate behaviors of most web servers.</span>
<span class="n">conditional_content_removal</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
<span class="c1"># Attach the originating request to the response so that it could be</span>
<span class="c1"># later retrieved.</span>
<span class="n">response</span><span class="o">.</span><span class="n">wsgi_request</span> <span class="o">=</span> <span class="n">request</span>
<span class="c1"># Emulate a WSGI server by calling the close method on completion.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">is_async</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="n">aclosing_iterator_wrapper</span><span class="p">(</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="n">closing_iterator_wrapper</span><span class="p">(</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># will fire request_finished</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">class</span><span class="w"> </span><span class="nc">AsyncClientHandler</span><span class="p">(</span><span class="n">BaseHandler</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An async version of ClientHandler.&quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span> <span class="o">=</span> <span class="n">enforce_csrf_checks</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">scope</span><span class="p">):</span>
<span class="c1"># Set up middleware if needed. We couldn&#39;t do this earlier, because</span>
<span class="c1"># settings weren&#39;t available.</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_middleware_chain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">load_middleware</span><span class="p">(</span><span class="n">is_async</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Extract body file from the scope, if provided.</span>
<span class="k">if</span> <span class="s2">&quot;_body_file&quot;</span> <span class="ow">in</span> <span class="n">scope</span><span class="p">:</span>
<span class="n">body_file</span> <span class="o">=</span> <span class="n">scope</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;_body_file&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">body_file</span> <span class="o">=</span> <span class="n">FakePayload</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">request_started</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="k">await</span> <span class="n">request_started</span><span class="o">.</span><span class="n">asend</span><span class="p">(</span><span class="n">sender</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="n">scope</span><span class="o">=</span><span class="n">scope</span><span class="p">)</span>
<span class="n">request_started</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="c1"># Wrap FakePayload body_file to allow large read() in test environment.</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">ASGIRequest</span><span class="p">(</span><span class="n">scope</span><span class="p">,</span> <span class="n">LimitedStream</span><span class="p">(</span><span class="n">body_file</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">body_file</span><span class="p">)))</span>
<span class="c1"># Sneaky little hack so that we can easily get round</span>
<span class="c1"># CsrfViewMiddleware. This makes life easier, and is probably required</span>
<span class="c1"># for backwards compatibility with external tests against admin views.</span>
<span class="n">request</span><span class="o">.</span><span class="n">_dont_enforce_csrf_checks</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">enforce_csrf_checks</span>
<span class="c1"># Request goes through middleware.</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_response_async</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="c1"># Simulate behaviors of most web servers.</span>
<span class="n">conditional_content_removal</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
<span class="c1"># Attach the originating ASGI request to the response so that it could</span>
<span class="c1"># be later retrieved.</span>
<span class="n">response</span><span class="o">.</span><span class="n">asgi_request</span> <span class="o">=</span> <span class="n">request</span>
<span class="c1"># Emulate a server by calling the close method on completion.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">streaming</span><span class="p">:</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">is_async</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="n">aclosing_iterator_wrapper</span><span class="p">(</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span> <span class="o">=</span> <span class="n">closing_iterator_wrapper</span><span class="p">(</span>
<span class="n">response</span><span class="o">.</span><span class="n">streaming_content</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="c1"># Will fire request_finished.</span>
<span class="k">await</span> <span class="n">sync_to_async</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">close</span><span class="p">,</span> <span class="n">thread_sensitive</span><span class="o">=</span><span class="kc">False</span><span class="p">)()</span>
<span class="n">request_finished</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">close_old_connections</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">def</span><span class="w"> </span><span class="nf">store_rendered_templates</span><span class="p">(</span><span class="n">store</span><span class="p">,</span> <span class="n">signal</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">template</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Store templates and contexts that are rendered.</span>
<span class="sd"> The context is copied so that it is an accurate representation at the time</span>
<span class="sd"> of rendering.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">store</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s2">&quot;templates&quot;</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">template</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;context&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">store</span><span class="p">:</span>
<span class="n">store</span><span class="p">[</span><span class="s2">&quot;context&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">ContextList</span><span class="p">()</span>
<span class="n">store</span><span class="p">[</span><span class="s2">&quot;context&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">copy</span><span class="p">(</span><span class="n">context</span><span class="p">))</span>
<span class="k">def</span><span class="w"> </span><span class="nf">encode_multipart</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Encode multipart POST data from a dictionary of form values.</span>
<span class="sd"> The key will be used as the form data name; the value will be transmitted</span>
<span class="sd"> as content. If the value is a file, the contents of the file will be sent</span>
<span class="sd"> as an application/octet-stream; otherwise, str(value) will be sent.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>
<span class="c1"># Not by any means perfect, but good enough for our purposes.</span>
<span class="k">def</span><span class="w"> </span><span class="nf">is_file</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="s2">&quot;read&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">callable</span><span class="p">(</span><span class="n">thing</span><span class="o">.</span><span class="n">read</span><span class="p">)</span>
<span class="c1"># Each bit of the multipart form data could be either a form value or a</span>
<span class="c1"># file, or a *list* of form values and/or files. Remember that HTTP field</span>
<span class="c1"># names can be duplicated!</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
<span class="s2">&quot;Cannot encode None for key &#39;</span><span class="si">%s</span><span class="s2">&#39; as POST data. Did you mean &quot;</span>
<span class="s2">&quot;to pass an empty string or omit the value?&quot;</span> <span class="o">%</span> <span class="n">key</span>
<span class="p">)</span>
<span class="k">elif</span> <span class="n">is_file</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
<span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">))</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">):</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">value</span><span class="p">:</span>
<span class="k">if</span> <span class="n">is_file</span><span class="p">(</span><span class="n">item</span><span class="p">):</span>
<span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">item</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
<span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="p">[</span>
<span class="s2">&quot;--</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">,</span>
<span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">key</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">item</span><span class="p">,</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
<span class="k">for</span> <span class="n">val</span> <span class="ow">in</span> <span class="p">[</span>
<span class="s2">&quot;--</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">,</span>
<span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="n">key</span><span class="p">,</span>
<span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">value</span><span class="p">,</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="n">lines</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
<span class="p">[</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="s2">&quot;--</span><span class="si">%s</span><span class="s2">--&quot;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">),</span>
<span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="k">return</span> <span class="sa">b</span><span class="s2">&quot;</span><span class="se">\r\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">encode_file</span><span class="p">(</span><span class="n">boundary</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">file</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="nf">to_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>
<span class="c1"># file.name might not be a string. For example, it&#39;s an int for</span>
<span class="c1"># tempfile.TemporaryFile().</span>
<span class="n">file_has_string_name</span> <span class="o">=</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s2">&quot;name&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">name</span><span class="p">)</span> <span class="k">if</span> <span class="n">file_has_string_name</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s2">&quot;content_type&quot;</span><span class="p">):</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">content_type</span>
<span class="k">elif</span> <span class="n">filename</span><span class="p">:</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="n">mimetypes</span><span class="o">.</span><span class="n">guess_type</span><span class="p">(</span><span class="n">filename</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">content_type</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="s2">&quot;application/octet-stream&quot;</span>
<span class="n">filename</span> <span class="o">=</span> <span class="n">filename</span> <span class="ow">or</span> <span class="n">key</span>
<span class="k">return</span> <span class="p">[</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="s2">&quot;--</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">boundary</span><span class="p">),</span>
<span class="n">to_bytes</span><span class="p">(</span>
<span class="s1">&#39;Content-Disposition: form-data; name=&quot;</span><span class="si">%s</span><span class="s1">&quot;; filename=&quot;</span><span class="si">%s</span><span class="s1">&quot;&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
<span class="p">),</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="s2">&quot;Content-Type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">content_type</span><span class="p">),</span>
<span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">to_bytes</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()),</span>
<span class="p">]</span>
<div class="viewcode-block" id="RequestFactory">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">RequestFactory</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Class that lets you create mock Request objects for use in testing.</span>
<span class="sd"> Usage:</span>
<span class="sd"> rf = RequestFactory()</span>
<span class="sd"> get_request = rf.get(&#39;/hello/&#39;)</span>
<span class="sd"> post_request = rf.post(&#39;/submit/&#39;, {&#39;foo&#39;: &#39;bar&#39;})</span>
<span class="sd"> Once you have a request object you can pass it to any view function,</span>
<span class="sd"> just as if that view had been hooked up using a URLconf.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="RequestFactory.__init__">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.__init__">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">json_encoder</span><span class="o">=</span><span class="n">DjangoJSONEncoder</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">defaults</span><span class="p">,</span>
<span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">json_encoder</span> <span class="o">=</span> <span class="n">json_encoder</span>
<span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="n">defaults</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">errors</span> <span class="o">=</span> <span class="n">BytesIO</span><span class="p">()</span>
<span class="k">if</span> <span class="n">headers</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">HttpHeaders</span><span class="o">.</span><span class="n">to_wsgi_names</span><span class="p">(</span><span class="n">headers</span><span class="p">))</span>
<span class="k">if</span> <span class="n">query_params</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">[</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_params</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">_base_environ</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The base environment for a request.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># This is a minimal valid WSGI environ dictionary, plus:</span>
<span class="c1"># - HTTP_COOKIE: for cookie support,</span>
<span class="c1"># - REMOTE_ADDR: often useful, see #8551.</span>
<span class="c1"># See https://www.python.org/dev/peps/pep-3333/#environ-variables</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">&quot;HTTP_COOKIE&quot;</span><span class="p">:</span> <span class="s2">&quot;; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="nb">sorted</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2">=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">morsel</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">morsel</span><span class="o">.</span><span class="n">coded_value</span><span class="p">)</span>
<span class="k">for</span> <span class="n">morsel</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="p">)</span>
<span class="p">),</span>
<span class="s2">&quot;PATH_INFO&quot;</span><span class="p">:</span> <span class="s2">&quot;/&quot;</span><span class="p">,</span>
<span class="s2">&quot;REMOTE_ADDR&quot;</span><span class="p">:</span> <span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span>
<span class="s2">&quot;REQUEST_METHOD&quot;</span><span class="p">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
<span class="s2">&quot;SCRIPT_NAME&quot;</span><span class="p">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="s2">&quot;SERVER_NAME&quot;</span><span class="p">:</span> <span class="s2">&quot;testserver&quot;</span><span class="p">,</span>
<span class="s2">&quot;SERVER_PORT&quot;</span><span class="p">:</span> <span class="s2">&quot;80&quot;</span><span class="p">,</span>
<span class="s2">&quot;SERVER_PROTOCOL&quot;</span><span class="p">:</span> <span class="s2">&quot;HTTP/1.1&quot;</span><span class="p">,</span>
<span class="s2">&quot;wsgi.version&quot;</span><span class="p">:</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="s2">&quot;wsgi.url_scheme&quot;</span><span class="p">:</span> <span class="s2">&quot;http&quot;</span><span class="p">,</span>
<span class="s2">&quot;wsgi.input&quot;</span><span class="p">:</span> <span class="n">FakePayload</span><span class="p">(</span><span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="p">),</span>
<span class="s2">&quot;wsgi.errors&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">errors</span><span class="p">,</span>
<span class="s2">&quot;wsgi.multiprocess&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
<span class="s2">&quot;wsgi.multithread&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="s2">&quot;wsgi.run_once&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">,</span>
<span class="o">**</span><span class="n">request</span><span class="p">,</span>
<span class="p">}</span>
<div class="viewcode-block" id="RequestFactory.request">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.request">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="s2">&quot;Construct a generic request object.&quot;</span>
<span class="k">return</span> <span class="n">WSGIRequest</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_base_environ</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">))</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">_encode_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">):</span>
<span class="k">if</span> <span class="n">content_type</span> <span class="ow">is</span> <span class="n">MULTIPART_CONTENT</span><span class="p">:</span>
<span class="k">return</span> <span class="n">encode_multipart</span><span class="p">(</span><span class="n">BOUNDARY</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># Encode the content so that the byte representation is correct.</span>
<span class="n">match</span> <span class="o">=</span> <span class="n">CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content_type</span><span class="p">)</span>
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
<span class="n">charset</span> <span class="o">=</span> <span class="n">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">charset</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span>
<span class="k">return</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">charset</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_encode_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return encoded JSON if data is a dict, list, or tuple and content_type</span>
<span class="sd"> is application/json.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">should_encode</span> <span class="o">=</span> <span class="n">JSON_CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">content_type</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span>
<span class="n">data</span><span class="p">,</span> <span class="p">(</span><span class="nb">dict</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">json_encoder</span><span class="p">)</span> <span class="k">if</span> <span class="n">should_encode</span> <span class="k">else</span> <span class="n">data</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_get_path</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parsed</span><span class="p">):</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">parsed</span><span class="o">.</span><span class="n">path</span>
<span class="c1"># If there are parameters, add them</span>
<span class="k">if</span> <span class="n">parsed</span><span class="o">.</span><span class="n">params</span><span class="p">:</span>
<span class="n">path</span> <span class="o">+=</span> <span class="s2">&quot;;&quot;</span> <span class="o">+</span> <span class="n">parsed</span><span class="o">.</span><span class="n">params</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">unquote_to_bytes</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
<span class="c1"># Replace the behavior where non-ASCII values in the WSGI environ are</span>
<span class="c1"># arbitrarily decoded with ISO-8859-1.</span>
<span class="c1"># Refs comment in `get_bytes_from_wsgi()`.</span>
<span class="k">return</span> <span class="n">path</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;iso-8859-1&quot;</span><span class="p">)</span>
<div class="viewcode-block" id="RequestFactory.get">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.get">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a GET request.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">query_params</span> <span class="ow">and</span> <span class="n">data</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;query_params and data arguments are mutually exclusive.&quot;</span><span class="p">)</span>
<span class="n">query_params</span> <span class="o">=</span> <span class="n">data</span> <span class="ow">or</span> <span class="n">query_params</span>
<span class="n">query_params</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">if</span> <span class="n">query_params</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">query_params</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;GET&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.post">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.post">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">post</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">MULTIPART_CONTENT</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a POST request.&quot;&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">({}</span> <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
<span class="n">post_data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_data</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;POST&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">post_data</span><span class="p">,</span>
<span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.head">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.head">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">head</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a HEAD request.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">query_params</span> <span class="ow">and</span> <span class="n">data</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;query_params and data arguments are mutually exclusive.&quot;</span><span class="p">)</span>
<span class="n">query_params</span> <span class="o">=</span> <span class="n">data</span> <span class="ow">or</span> <span class="n">query_params</span>
<span class="n">query_params</span> <span class="o">=</span> <span class="p">{}</span> <span class="k">if</span> <span class="n">query_params</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">query_params</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;HEAD&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.trace">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.trace">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">trace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a TRACE request.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;TRACE&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.options">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.options">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">options</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="s2">&quot;Construct an OPTIONS request.&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;OPTIONS&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.put">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.put">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">put</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a PUT request.&quot;&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;PUT&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.patch">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.patch">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">patch</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a PATCH request.&quot;&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;PATCH&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.delete">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.delete">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">delete</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a DELETE request.&quot;&quot;&quot;</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_encode_json</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">content_type</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">generic</span><span class="p">(</span>
<span class="s2">&quot;DELETE&quot;</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="RequestFactory.generic">
<a class="viewcode-back" href="../../../api/evennia.web.utils.tests.html#evennia.web.utils.tests.RequestFactory.generic">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">generic</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">method</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct an arbitrary HTTP request.&quot;&quot;&quot;</span>
<span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> <span class="c1"># path can be lazy</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>
<span class="n">r</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;PATH_INFO&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_path</span><span class="p">(</span><span class="n">parsed</span><span class="p">),</span>
<span class="s2">&quot;REQUEST_METHOD&quot;</span><span class="p">:</span> <span class="n">method</span><span class="p">,</span>
<span class="s2">&quot;SERVER_PORT&quot;</span><span class="p">:</span> <span class="s2">&quot;443&quot;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s2">&quot;80&quot;</span><span class="p">,</span>
<span class="s2">&quot;wsgi.url_scheme&quot;</span><span class="p">:</span> <span class="s2">&quot;https&quot;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s2">&quot;http&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="n">r</span><span class="o">.</span><span class="n">update</span><span class="p">(</span>
<span class="p">{</span>
<span class="s2">&quot;CONTENT_LENGTH&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)),</span>
<span class="s2">&quot;CONTENT_TYPE&quot;</span><span class="p">:</span> <span class="n">content_type</span><span class="p">,</span>
<span class="s2">&quot;wsgi.input&quot;</span><span class="p">:</span> <span class="n">FakePayload</span><span class="p">(</span><span class="n">data</span><span class="p">),</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">headers</span><span class="p">:</span>
<span class="n">extra</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">HttpHeaders</span><span class="o">.</span><span class="n">to_wsgi_names</span><span class="p">(</span><span class="n">headers</span><span class="p">))</span>
<span class="k">if</span> <span class="n">query_params</span><span class="p">:</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_params</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">r</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">extra</span><span class="p">)</span>
<span class="c1"># If QUERY_STRING is absent or empty, we want to extract it from the URL.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">r</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">):</span>
<span class="c1"># WSGI requires latin-1 encoded strings. See get_path_info().</span>
<span class="n">query_string</span> <span class="o">=</span> <span class="n">parsed</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;iso-8859-1&quot;</span><span class="p">)</span>
<span class="n">r</span><span class="p">[</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">query_string</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="o">**</span><span class="n">r</span><span class="p">)</span></div>
</div>
<span class="k">class</span><span class="w"> </span><span class="nc">AsyncRequestFactory</span><span class="p">(</span><span class="n">RequestFactory</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Class that lets you create mock ASGI-like Request objects for use in</span>
<span class="sd"> testing. Usage:</span>
<span class="sd"> rf = AsyncRequestFactory()</span>
<span class="sd"> get_request = rf.get(&quot;/hello/&quot;)</span>
<span class="sd"> post_request = rf.post(&quot;/submit/&quot;, {&quot;foo&quot;: &quot;bar&quot;})</span>
<span class="sd"> Once you have a request object you can pass it to any view function,</span>
<span class="sd"> including synchronous ones. The reason we have a separate class here is:</span>
<span class="sd"> a) this makes ASGIRequest subclasses, and</span>
<span class="sd"> b) AsyncClient can subclass it.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_base_scope</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;The base scope for a request.&quot;&quot;&quot;</span>
<span class="c1"># This is a minimal valid ASGI scope, plus:</span>
<span class="c1"># - headers[&#39;cookie&#39;] for cookie support,</span>
<span class="c1"># - &#39;client&#39; often useful, see #8551.</span>
<span class="n">scope</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;asgi&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;version&quot;</span><span class="p">:</span> <span class="s2">&quot;3.0&quot;</span><span class="p">},</span>
<span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;http&quot;</span><span class="p">,</span>
<span class="s2">&quot;http_version&quot;</span><span class="p">:</span> <span class="s2">&quot;1.1&quot;</span><span class="p">,</span>
<span class="s2">&quot;client&quot;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">],</span>
<span class="s2">&quot;server&quot;</span><span class="p">:</span> <span class="p">(</span><span class="s2">&quot;testserver&quot;</span><span class="p">,</span> <span class="s2">&quot;80&quot;</span><span class="p">),</span>
<span class="s2">&quot;scheme&quot;</span><span class="p">:</span> <span class="s2">&quot;http&quot;</span><span class="p">,</span>
<span class="s2">&quot;method&quot;</span><span class="p">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
<span class="s2">&quot;headers&quot;</span><span class="p">:</span> <span class="p">[],</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">,</span>
<span class="o">**</span><span class="n">request</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">scope</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="p">(</span>
<span class="sa">b</span><span class="s2">&quot;cookie&quot;</span><span class="p">,</span>
<span class="sa">b</span><span class="s2">&quot;; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="nb">sorted</span><span class="p">(</span>
<span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">morsel</span><span class="o">.</span><span class="n">key</span><span class="p">,</span> <span class="n">morsel</span><span class="o">.</span><span class="n">coded_value</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">morsel</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
<span class="p">)</span>
<span class="p">),</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">scope</span>
<span class="k">def</span><span class="w"> </span><span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct a generic request object.&quot;&quot;&quot;</span>
<span class="c1"># This is synchronous, which means all methods on this class are.</span>
<span class="c1"># AsyncClient, however, has an async request function, which makes all</span>
<span class="c1"># its methods async.</span>
<span class="k">if</span> <span class="s2">&quot;_body_file&quot;</span> <span class="ow">in</span> <span class="n">request</span><span class="p">:</span>
<span class="n">body_file</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;_body_file&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">body_file</span> <span class="o">=</span> <span class="n">FakePayload</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="c1"># Wrap FakePayload body_file to allow large read() in test environment.</span>
<span class="k">return</span> <span class="n">ASGIRequest</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_base_scope</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">),</span> <span class="n">LimitedStream</span><span class="p">(</span><span class="n">body_file</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">body_file</span><span class="p">))</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">generic</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">method</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Construct an arbitrary HTTP request.&quot;&quot;&quot;</span>
<span class="n">parsed</span> <span class="o">=</span> <span class="n">urlparse</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> <span class="c1"># path can be lazy.</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">force_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_CHARSET</span><span class="p">)</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;method&quot;</span><span class="p">:</span> <span class="n">method</span><span class="p">,</span>
<span class="s2">&quot;path&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_path</span><span class="p">(</span><span class="n">parsed</span><span class="p">),</span>
<span class="s2">&quot;server&quot;</span><span class="p">:</span> <span class="p">(</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="s2">&quot;443&quot;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s2">&quot;80&quot;</span><span class="p">),</span>
<span class="s2">&quot;scheme&quot;</span><span class="p">:</span> <span class="s2">&quot;https&quot;</span> <span class="k">if</span> <span class="n">secure</span> <span class="k">else</span> <span class="s2">&quot;http&quot;</span><span class="p">,</span>
<span class="s2">&quot;headers&quot;</span><span class="p">:</span> <span class="p">[(</span><span class="sa">b</span><span class="s2">&quot;host&quot;</span><span class="p">,</span> <span class="sa">b</span><span class="s2">&quot;testserver&quot;</span><span class="p">)],</span>
<span class="p">}</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
<span class="p">[</span>
<span class="p">(</span><span class="sa">b</span><span class="s2">&quot;content-length&quot;</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)),</span>
<span class="p">(</span><span class="sa">b</span><span class="s2">&quot;content-type&quot;</span><span class="p">,</span> <span class="n">content_type</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">)),</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;_body_file&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">FakePayload</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">if</span> <span class="n">query_params</span><span class="p">:</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;query_string&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">urlencode</span><span class="p">(</span><span class="n">query_params</span><span class="p">,</span> <span class="n">doseq</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">query_string</span> <span class="o">:=</span> <span class="n">extra</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;query_string&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">query_string</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># If QUERY_STRING is absent or empty, we want to extract it from</span>
<span class="c1"># the URL.</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;query_string&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">parsed</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span>
<span class="k">if</span> <span class="n">headers</span><span class="p">:</span>
<span class="n">extra</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">HttpHeaders</span><span class="o">.</span><span class="n">to_asgi_names</span><span class="p">(</span><span class="n">headers</span><span class="p">))</span>
<span class="n">s</span><span class="p">[</span><span class="s2">&quot;headers&quot;</span><span class="p">]</span> <span class="o">+=</span> <span class="p">[</span>
<span class="p">(</span><span class="n">key</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;ascii&quot;</span><span class="p">),</span> <span class="n">value</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">&quot;latin1&quot;</span><span class="p">))</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">extra</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="p">]</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="o">**</span><span class="n">s</span><span class="p">)</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ClientMixin</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Mixin with common methods between Client and AsyncClient.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">store_exc_info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Store exceptions when they are generated by a view.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">check_exception</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Look for a signaled exception, clear the current context exception</span>
<span class="sd"> data, re-raise the signaled exception, and clear the signaled exception</span>
<span class="sd"> from the local cache.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">response</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span><span class="p">:</span>
<span class="n">_</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">raise_request_exception</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">exc_value</span>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">session</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return the current session variables.&quot;&quot;&quot;</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">cookie</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cookie</span><span class="p">:</span>
<span class="k">return</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">(</span><span class="n">cookie</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="n">session</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">]</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">session_key</span>
<span class="k">return</span> <span class="n">session</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">asession</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">cookie</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">)</span>
<span class="k">if</span> <span class="n">cookie</span><span class="p">:</span>
<span class="k">return</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">(</span><span class="n">cookie</span><span class="o">.</span><span class="n">value</span><span class="p">)</span>
<span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="k">await</span> <span class="n">session</span><span class="o">.</span><span class="n">asave</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span><span class="p">]</span> <span class="o">=</span> <span class="n">session</span><span class="o">.</span><span class="n">session_key</span>
<span class="k">return</span> <span class="n">session</span>
<span class="k">def</span><span class="w"> </span><span class="nf">login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">credentials</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Set the Factory to appear as if it has successfully logged into a site.</span>
<span class="sd"> Return True if login is possible or False if the provided credentials</span>
<span class="sd"> are incorrect.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">authenticate</span>
<span class="n">user</span> <span class="o">=</span> <span class="n">authenticate</span><span class="p">(</span><span class="o">**</span><span class="n">credentials</span><span class="p">)</span>
<span class="k">if</span> <span class="n">user</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_login</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">alogin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">credentials</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;See login().&quot;&quot;&quot;</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">aauthenticate</span>
<span class="n">user</span> <span class="o">=</span> <span class="k">await</span> <span class="n">aauthenticate</span><span class="p">(</span><span class="o">**</span><span class="n">credentials</span><span class="p">)</span>
<span class="k">if</span> <span class="n">user</span><span class="p">:</span>
<span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alogin</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">def</span><span class="w"> </span><span class="nf">force_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">backend</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">backend</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_backend</span><span class="p">()</span>
<span class="n">user</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="n">backend</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_login</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">aforce_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">backend</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">backend</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_backend</span><span class="p">()</span>
<span class="n">user</span><span class="o">.</span><span class="n">backend</span> <span class="o">=</span> <span class="n">backend</span>
<span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alogin</span><span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_get_backend</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">load_backend</span>
<span class="k">for</span> <span class="n">backend_path</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">AUTHENTICATION_BACKENDS</span><span class="p">:</span>
<span class="n">backend</span> <span class="o">=</span> <span class="n">load_backend</span><span class="p">(</span><span class="n">backend_path</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">backend</span><span class="p">,</span> <span class="s2">&quot;get_user&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">backend_path</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_login</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">login</span>
<span class="c1"># Create a fake request to store login details.</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="n">login</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span>
<span class="c1"># Save the session values.</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_set_login_cookies</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">_alogin</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">alogin</span>
<span class="c1"># Create a fake request to store login details.</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>
<span class="n">session</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">asession</span><span class="p">()</span>
<span class="k">if</span> <span class="n">session</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="k">await</span> <span class="n">alogin</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">user</span><span class="p">,</span> <span class="n">backend</span><span class="p">)</span>
<span class="c1"># Save the session values.</span>
<span class="k">await</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">asave</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_set_login_cookies</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_set_login_cookies</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
<span class="c1"># Set the cookie to represent the session.</span>
<span class="n">session_cookie</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_NAME</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">session_cookie</span><span class="p">]</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">session_key</span>
<span class="n">cookie_data</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;max-age&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;path&quot;</span><span class="p">:</span> <span class="s2">&quot;/&quot;</span><span class="p">,</span>
<span class="s2">&quot;domain&quot;</span><span class="p">:</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_DOMAIN</span><span class="p">,</span>
<span class="s2">&quot;secure&quot;</span><span class="p">:</span> <span class="n">settings</span><span class="o">.</span><span class="n">SESSION_COOKIE_SECURE</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">&quot;expires&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="p">[</span><span class="n">session_cookie</span><span class="p">]</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">cookie_data</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">logout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Log out the user by removing the cookies and session object.&quot;&quot;&quot;</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_user</span><span class="p">,</span> <span class="n">logout</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">session</span>
<span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="n">get_user</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="n">logout</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">alogout</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;See logout().&quot;&quot;&quot;</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">django.contrib.auth</span><span class="w"> </span><span class="kn">import</span> <span class="n">aget_user</span><span class="p">,</span> <span class="n">alogout</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">HttpRequest</span><span class="p">()</span>
<span class="n">session</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">asession</span><span class="p">()</span>
<span class="k">if</span> <span class="n">session</span><span class="p">:</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">session</span>
<span class="n">request</span><span class="o">.</span><span class="n">user</span> <span class="o">=</span> <span class="k">await</span> <span class="n">aget_user</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">engine</span> <span class="o">=</span> <span class="n">import_module</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">SESSION_ENGINE</span><span class="p">)</span>
<span class="n">request</span><span class="o">.</span><span class="n">session</span> <span class="o">=</span> <span class="n">engine</span><span class="o">.</span><span class="n">SessionStore</span><span class="p">()</span>
<span class="k">await</span> <span class="n">alogout</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span> <span class="o">=</span> <span class="n">SimpleCookie</span><span class="p">()</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_parse_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="s2">&quot;_json&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">JSON_CONTENT_TYPE_RE</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">)):</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s1">&#39;Content-Type header is &quot;</span><span class="si">%s</span><span class="s1">&quot;, not &quot;application/json&quot;&#39;</span>
<span class="o">%</span> <span class="n">response</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">_json</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span>
<span class="n">response</span><span class="o">.</span><span class="n">content</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">charset</span><span class="p">),</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span><span class="o">.</span><span class="n">_json</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_follow_redirect</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">response</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Follow a single redirect contained in response using GET.&quot;&quot;&quot;</span>
<span class="n">response_url</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">url</span>
<span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span>
<span class="n">redirect_chain</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">response_url</span><span class="p">,</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="p">))</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">urlsplit</span><span class="p">(</span><span class="n">response_url</span><span class="p">)</span>
<span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span><span class="p">:</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;wsgi.url_scheme&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span>
<span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">hostname</span><span class="p">:</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;SERVER_NAME&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">hostname</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;HTTP_HOST&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">hostname</span>
<span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">port</span><span class="p">:</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;SERVER_PORT&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">path</span>
<span class="c1"># RFC 3986 Section 6.2.3: Empty path should be normalized to &quot;/&quot;.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span> <span class="ow">and</span> <span class="n">url</span><span class="o">.</span><span class="n">netloc</span><span class="p">:</span>
<span class="n">path</span> <span class="o">=</span> <span class="s2">&quot;/&quot;</span>
<span class="c1"># Prepend the request path to handle relative path redirects</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">):</span>
<span class="n">path</span> <span class="o">=</span> <span class="n">urljoin</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s2">&quot;PATH_INFO&quot;</span><span class="p">],</span> <span class="n">path</span><span class="p">)</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="p">(</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">TEMPORARY_REDIRECT</span><span class="p">,</span>
<span class="n">HTTPStatus</span><span class="o">.</span><span class="n">PERMANENT_REDIRECT</span><span class="p">,</span>
<span class="p">):</span>
<span class="c1"># Preserve request method and query string (if needed)</span>
<span class="c1"># post-redirect for 307/308 responses.</span>
<span class="n">request_method</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="p">[</span><span class="s2">&quot;REQUEST_METHOD&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
<span class="k">if</span> <span class="n">request_method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;get&quot;</span><span class="p">,</span> <span class="s2">&quot;head&quot;</span><span class="p">):</span>
<span class="n">extra</span><span class="p">[</span><span class="s2">&quot;QUERY_STRING&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">query</span>
<span class="n">request_method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request_method</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">request_method</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">QueryDict</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">query</span><span class="p">)</span>
<span class="n">content_type</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">request_method</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">_ensure_redirects_not_cyclic</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Raise a RedirectCycleError if response contains too many redirects.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span>
<span class="k">if</span> <span class="n">redirect_chain</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="n">redirect_chain</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
<span class="c1"># Check that we&#39;re not redirecting to somewhere we&#39;ve already been</span>
<span class="c1"># to, to prevent loops.</span>
<span class="k">raise</span> <span class="n">RedirectCycleError</span><span class="p">(</span><span class="s2">&quot;Redirect loop detected.&quot;</span><span class="p">,</span> <span class="n">last_response</span><span class="o">=</span><span class="n">response</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">redirect_chain</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">20</span><span class="p">:</span>
<span class="c1"># Such a lengthy chain likely also means a loop, but one with a</span>
<span class="c1"># growing path, changing view, or changing query argument. 20 is</span>
<span class="c1"># the value of &quot;network.http.redirection-limit&quot; from Firefox.</span>
<span class="k">raise</span> <span class="n">RedirectCycleError</span><span class="p">(</span><span class="s2">&quot;Too many redirects.&quot;</span><span class="p">,</span> <span class="n">last_response</span><span class="o">=</span><span class="n">response</span><span class="p">)</span>
<div class="viewcode-block" id="Client">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">Client</span><span class="p">(</span><span class="n">ClientMixin</span><span class="p">,</span> <span class="n">RequestFactory</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> A class that can act as a client for testing purposes.</span>
<span class="sd"> It allows the user to compose GET and POST requests, and</span>
<span class="sd"> obtain the response that the server gave to those requests.</span>
<span class="sd"> The server Response objects are annotated with the details</span>
<span class="sd"> of the contexts and templates that were rendered during the</span>
<span class="sd"> process of serving the request.</span>
<span class="sd"> Client objects are stateful - they will retain cookie (and</span>
<span class="sd"> thus session) details for the lifetime of the Client instance.</span>
<span class="sd"> This is not intended as a replacement for Twill/Selenium or</span>
<span class="sd"> the like - it is here to allow testing against the</span>
<span class="sd"> contexts and templates produced by a view, rather than the</span>
<span class="sd"> HTML rendered to the end-user.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="Client.__init__">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.__init__">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">raise_request_exception</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">defaults</span><span class="p">,</span>
<span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">defaults</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handler</span> <span class="o">=</span> <span class="n">ClientHandler</span><span class="p">(</span><span class="n">enforce_csrf_checks</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">raise_request_exception</span> <span class="o">=</span> <span class="n">raise_request_exception</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="kc">None</span></div>
<div class="viewcode-block" id="Client.request">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.request">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make a generic request. Compose the environment dictionary and pass</span>
<span class="sd"> to the handler, return the result of the handler. Assume defaults for</span>
<span class="sd"> the query environment, which can be overridden using the arguments to</span>
<span class="sd"> the request.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">environ</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_base_environ</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">)</span>
<span class="c1"># Curry a data dictionary into an instance of the template renderer</span>
<span class="c1"># callback function.</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">on_template_render</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">store_rendered_templates</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="n">signal_uid</span> <span class="o">=</span> <span class="s2">&quot;template-render-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">on_template_render</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
<span class="c1"># Capture exceptions created by the handler.</span>
<span class="n">exception_uid</span> <span class="o">=</span> <span class="s2">&quot;request-exception-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">got_request_exception</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store_exc_info</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
<span class="n">got_request_exception</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>
<span class="c1"># Check for signaled exceptions.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">check_exception</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
<span class="c1"># Save the client and request that stimulated the response.</span>
<span class="n">response</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="bp">self</span>
<span class="n">response</span><span class="o">.</span><span class="n">request</span> <span class="o">=</span> <span class="n">request</span>
<span class="c1"># Add any rendered template detail to the response.</span>
<span class="n">response</span><span class="o">.</span><span class="n">templates</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;templates&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;context&quot;</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">json</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parse_json</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
<span class="c1"># Attach the ResolverMatch instance to the response.</span>
<span class="n">urlconf</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">wsgi_request</span><span class="p">,</span> <span class="s2">&quot;urlconf&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">resolver_match</span> <span class="o">=</span> <span class="n">SimpleLazyObject</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">resolve</span><span class="p">(</span><span class="n">request</span><span class="p">[</span><span class="s2">&quot;PATH_INFO&quot;</span><span class="p">],</span> <span class="n">urlconf</span><span class="o">=</span><span class="n">urlconf</span><span class="p">),</span>
<span class="p">)</span>
<span class="c1"># Flatten a single context. Not really necessary anymore thanks to the</span>
<span class="c1"># __getattr__ flattening in ContextList, but has some edge case</span>
<span class="c1"># backwards compatibility implications.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># Update persistent cookie data.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.get">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.get">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using GET.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.post">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.post">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">post</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">MULTIPART_CONTENT</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using POST.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.head">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.head">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">head</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using HEAD.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">head</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.options">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.options">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">options</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using OPTIONS.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">options</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.put">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.put">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">put</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a resource to the server using PUT.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">put</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.patch">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.patch">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">patch</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a resource to the server using PATCH.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">patch</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.delete">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.delete">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">delete</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a DELETE request to the server.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<div class="viewcode-block" id="Client.trace">
<a class="viewcode-back" href="../../../api/evennia.web.website.tests.html#evennia.web.utils.tests.Client.trace">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">trace</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a TRACE request to the server.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">trace</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">_handle_redirects</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Follow any redirects by requesting responses from the server using GET.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">while</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="n">REDIRECT_STATUS_CODES</span><span class="p">:</span>
<span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span>
<span class="n">response</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_follow_redirect</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">redirect_chain</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_ensure_redirects_not_cyclic</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span></div>
<span class="k">class</span><span class="w"> </span><span class="nc">AsyncClient</span><span class="p">(</span><span class="n">ClientMixin</span><span class="p">,</span> <span class="n">AsyncRequestFactory</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> An async version of Client that creates ASGIRequests and calls through an</span>
<span class="sd"> async request path.</span>
<span class="sd"> Does not currently support &quot;follow&quot; on its methods.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">enforce_csrf_checks</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">raise_request_exception</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">defaults</span><span class="p">,</span>
<span class="p">):</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">defaults</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">handler</span> <span class="o">=</span> <span class="n">AsyncClientHandler</span><span class="p">(</span><span class="n">enforce_csrf_checks</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">raise_request_exception</span> <span class="o">=</span> <span class="n">raise_request_exception</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">request</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Make a generic request. Compose the scope dictionary and pass to the</span>
<span class="sd"> handler, return the result of the handler. Assume defaults for the</span>
<span class="sd"> query environment, which can be overridden using the arguments to the</span>
<span class="sd"> request.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">scope</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_base_scope</span><span class="p">(</span><span class="o">**</span><span class="n">request</span><span class="p">)</span>
<span class="c1"># Curry a data dictionary into an instance of the template renderer</span>
<span class="c1"># callback function.</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">on_template_render</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="n">store_rendered_templates</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
<span class="n">signal_uid</span> <span class="o">=</span> <span class="s2">&quot;template-render-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">on_template_render</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
<span class="c1"># Capture exceptions created by the handler.</span>
<span class="n">exception_uid</span> <span class="o">=</span> <span class="s2">&quot;request-exception-</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">id</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">got_request_exception</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">store_exc_info</span><span class="p">,</span> <span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="p">(</span><span class="n">scope</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">signals</span><span class="o">.</span><span class="n">template_rendered</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">signal_uid</span><span class="p">)</span>
<span class="n">got_request_exception</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">dispatch_uid</span><span class="o">=</span><span class="n">exception_uid</span><span class="p">)</span>
<span class="c1"># Check for signaled exceptions.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">check_exception</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
<span class="c1"># Save the client and request that stimulated the response.</span>
<span class="n">response</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="bp">self</span>
<span class="n">response</span><span class="o">.</span><span class="n">request</span> <span class="o">=</span> <span class="n">request</span>
<span class="c1"># Add any rendered template detail to the response.</span>
<span class="n">response</span><span class="o">.</span><span class="n">templates</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;templates&quot;</span><span class="p">,</span> <span class="p">[])</span>
<span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;context&quot;</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">json</span> <span class="o">=</span> <span class="n">partial</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parse_json</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span>
<span class="c1"># Attach the ResolverMatch instance to the response.</span>
<span class="n">urlconf</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">asgi_request</span><span class="p">,</span> <span class="s2">&quot;urlconf&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">resolver_match</span> <span class="o">=</span> <span class="n">SimpleLazyObject</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">resolve</span><span class="p">(</span><span class="n">request</span><span class="p">[</span><span class="s2">&quot;path&quot;</span><span class="p">],</span> <span class="n">urlconf</span><span class="o">=</span><span class="n">urlconf</span><span class="p">),</span>
<span class="p">)</span>
<span class="c1"># Flatten a single context. Not really necessary anymore thanks to the</span>
<span class="c1"># __getattr__ flattening in ContextList, but has some edge case</span>
<span class="c1"># backwards compatibility implications.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">response</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># Update persistent cookie data.</span>
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">cookies</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using GET.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">post</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">MULTIPART_CONTENT</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using POST.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">head</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using HEAD.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">head</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">options</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Request a response from the server using OPTIONS.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">options</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">put</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a resource to the server using PUT.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">put</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">patch</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a resource to the server using PATCH.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">patch</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">delete</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a DELETE request to the server.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">delete</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">trace</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">follow</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">*</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Send a TRACE request to the server.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>
<span class="bp">self</span><span class="o">.</span><span class="n">headers</span> <span class="o">=</span> <span class="n">headers</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">trace</span><span class="p">(</span>
<span class="n">path</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">secure</span><span class="o">=</span><span class="n">secure</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">follow</span><span class="p">:</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ahandle_redirects</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span> <span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span> <span class="o">**</span><span class="n">extra</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">_ahandle_redirects</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Follow any redirects by requesting responses from the server using GET.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">while</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="ow">in</span> <span class="n">REDIRECT_STATUS_CODES</span><span class="p">:</span>
<span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span>
<span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">_follow_redirect</span><span class="p">(</span>
<span class="n">response</span><span class="p">,</span>
<span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">,</span>
<span class="n">content_type</span><span class="o">=</span><span class="n">content_type</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">query_params</span><span class="o">=</span><span class="n">query_params</span><span class="p">,</span>
<span class="o">**</span><span class="n">extra</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">redirect_chain</span> <span class="o">=</span> <span class="n">redirect_chain</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_ensure_redirects_not_cyclic</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
<span class="k">return</span> <span class="n">response</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">django.test.client</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
</div>
</body>
</html>