mirror of
https://github.com/linkedin/school-of-sre
synced 2026-01-16 13:38:03 +00:00
Deployed 52e7ed5 with MkDocs version: 1.1.2
This commit is contained in:
@@ -1369,87 +1369,87 @@
|
||||
<h3 id="5-other">5. Other</h3>
|
||||
<p>We are not accounting for users into our app and other possible features like rate limiting, customized links etc but it will eventually come up with time. Depending on the requirements, they too might need to get incorporated.</p>
|
||||
<p>The minimal working code is given below for reference but I'd encourage you to come up with your own.</p>
|
||||
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">request</span>
|
||||
<pre><code class="language-python">from flask import Flask, redirect, request
|
||||
|
||||
<span class="kn">from</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="n">md5</span>
|
||||
from hashlib import md5
|
||||
|
||||
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="s2">"url_shortener"</span><span class="p">)</span>
|
||||
app = Flask("url_shortener")
|
||||
|
||||
<span class="n">mapping</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
mapping = {}
|
||||
|
||||
<span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">"/shorten"</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">"POST"</span><span class="p">])</span>
|
||||
<span class="k">def</span> <span class="nf">shorten</span><span class="p">():</span>
|
||||
<span class="k">global</span> <span class="n">mapping</span>
|
||||
<span class="n">payload</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">json</span>
|
||||
@app.route("/shorten", methods=["POST"])
|
||||
def shorten():
|
||||
global mapping
|
||||
payload = request.json
|
||||
|
||||
<span class="k">if</span> <span class="s2">"url"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">payload</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s2">"Missing URL Parameter"</span><span class="p">,</span> <span class="mi">400</span>
|
||||
if "url" not in payload:
|
||||
return "Missing URL Parameter", 400
|
||||
|
||||
<span class="c1"># TODO: check if URL is valid</span>
|
||||
# TODO: check if URL is valid
|
||||
|
||||
<span class="n">hash_</span> <span class="o">=</span> <span class="n">md5</span><span class="p">()</span>
|
||||
<span class="n">hash_</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">payload</span><span class="p">[</span><span class="s2">"url"</span><span class="p">]</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
|
||||
<span class="n">digest</span> <span class="o">=</span> <span class="n">hash_</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()[:</span><span class="mi">5</span><span class="p">]</span> <span class="c1"># limiting to 5 chars. Less the limit more the chances of collission</span>
|
||||
hash_ = md5()
|
||||
hash_.update(payload["url"].encode())
|
||||
digest = hash_.hexdigest()[:5] # limiting to 5 chars. Less the limit more the chances of collission
|
||||
|
||||
<span class="k">if</span> <span class="n">digest</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">mapping</span><span class="p">:</span>
|
||||
<span class="n">mapping</span><span class="p">[</span><span class="n">digest</span><span class="p">]</span> <span class="o">=</span> <span class="n">payload</span><span class="p">[</span><span class="s2">"url"</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"Shortened: r/</span><span class="si">{</span><span class="n">digest</span><span class="si">}</span><span class="se">\n</span><span class="s2">"</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># TODO: check for hash collission</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"Already exists: r/</span><span class="si">{</span><span class="n">digest</span><span class="si">}</span><span class="se">\n</span><span class="s2">"</span>
|
||||
if digest not in mapping:
|
||||
mapping[digest] = payload["url"]
|
||||
return f"Shortened: r/{digest}\n"
|
||||
else:
|
||||
# TODO: check for hash collission
|
||||
return f"Already exists: r/{digest}\n"
|
||||
|
||||
|
||||
<span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">"/r/<hash_>"</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">redirect_</span><span class="p">(</span><span class="n">hash_</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">hash_</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">mapping</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="s2">"URL Not Found"</span><span class="p">,</span> <span class="mi">404</span>
|
||||
<span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">mapping</span><span class="p">[</span><span class="n">hash_</span><span class="p">])</span>
|
||||
@app.route("/r/<hash_>")
|
||||
def redirect_(hash_):
|
||||
if hash_ not in mapping:
|
||||
return "URL Not Found", 404
|
||||
return redirect(mapping[hash_])
|
||||
|
||||
|
||||
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||||
<span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">debug</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
||||
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd">OUTPUT:</span>
|
||||
"""
|
||||
OUTPUT:
|
||||
|
||||
|
||||
<span class="sd">===> SHORTENING</span>
|
||||
===> SHORTENING
|
||||
|
||||
<span class="sd">$ curl localhost:5000/shorten -H "content-type: application/json" --data '{"url":"https://linkedin.com"}'</span>
|
||||
<span class="sd">Shortened: r/a62a4</span>
|
||||
$ curl localhost:5000/shorten -H "content-type: application/json" --data '{"url":"https://linkedin.com"}'
|
||||
Shortened: r/a62a4
|
||||
|
||||
|
||||
<span class="sd">===> REDIRECTING, notice the response code 302 and the location header</span>
|
||||
===> REDIRECTING, notice the response code 302 and the location header
|
||||
|
||||
<span class="sd">$ curl localhost:5000/r/a62a4 -v</span>
|
||||
<span class="sd">* Uses proxy env variable NO_PROXY == '127.0.0.1'</span>
|
||||
<span class="sd">* Trying ::1...</span>
|
||||
<span class="sd">* TCP_NODELAY set</span>
|
||||
<span class="sd">* Connection failed</span>
|
||||
<span class="sd">* connect to ::1 port 5000 failed: Connection refused</span>
|
||||
<span class="sd">* Trying 127.0.0.1...</span>
|
||||
<span class="sd">* TCP_NODELAY set</span>
|
||||
<span class="sd">* Connected to localhost (127.0.0.1) port 5000 (#0)</span>
|
||||
<span class="sd">> GET /r/a62a4 HTTP/1.1</span>
|
||||
<span class="sd">> Host: localhost:5000</span>
|
||||
<span class="sd">> User-Agent: curl/7.64.1</span>
|
||||
<span class="sd">> Accept: */*</span>
|
||||
<span class="sd">></span>
|
||||
<span class="sd">* HTTP 1.0, assume close after body</span>
|
||||
<span class="sd">< HTTP/1.0 302 FOUND</span>
|
||||
<span class="sd">< Content-Type: text/html; charset=utf-8</span>
|
||||
<span class="sd">< Content-Length: 247</span>
|
||||
<span class="sd">< Location: https://linkedin.com</span>
|
||||
<span class="sd">< Server: Werkzeug/0.15.4 Python/3.7.7</span>
|
||||
<span class="sd">< Date: Tue, 27 Oct 2020 09:37:12 GMT</span>
|
||||
<span class="sd"><</span>
|
||||
<span class="sd"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"></span>
|
||||
<span class="sd"><title>Redirecting...</title></span>
|
||||
<span class="sd"><h1>Redirecting...</h1></span>
|
||||
<span class="sd">* Closing connection 0</span>
|
||||
<span class="sd"><p>You should be redirected automatically to target URL: <a href="https://linkedin.com">https://linkedin.com</a>. If not click the link.</span>
|
||||
<span class="sd">"""</span>
|
||||
</code></pre></div>
|
||||
$ curl localhost:5000/r/a62a4 -v
|
||||
* Uses proxy env variable NO_PROXY == '127.0.0.1'
|
||||
* Trying ::1...
|
||||
* TCP_NODELAY set
|
||||
* Connection failed
|
||||
* connect to ::1 port 5000 failed: Connection refused
|
||||
* Trying 127.0.0.1...
|
||||
* TCP_NODELAY set
|
||||
* Connected to localhost (127.0.0.1) port 5000 (#0)
|
||||
> GET /r/a62a4 HTTP/1.1
|
||||
> Host: localhost:5000
|
||||
> User-Agent: curl/7.64.1
|
||||
> Accept: */*
|
||||
>
|
||||
* HTTP 1.0, assume close after body
|
||||
< HTTP/1.0 302 FOUND
|
||||
< Content-Type: text/html; charset=utf-8
|
||||
< Content-Length: 247
|
||||
< Location: https://linkedin.com
|
||||
< Server: Werkzeug/0.15.4 Python/3.7.7
|
||||
< Date: Tue, 27 Oct 2020 09:37:12 GMT
|
||||
<
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<title>Redirecting...</title>
|
||||
<h1>Redirecting...</h1>
|
||||
* Closing connection 0
|
||||
<p>You should be redirected automatically to target URL: <a href="https://linkedin.com">https://linkedin.com</a>. If not click the link.
|
||||
"""
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user