⠛⠥⠝⠑⠽⠎⠥⠎ /home/asguneysu

File Upload with Tornado

by Ahmed Şeref Güneysu

<details class="ba bw2 mv2 pa2 b--light-gray">
    <summary class="fira mv1 dim fw7">Tornado Application</summary>
    <span><a download="main.py" class="link black bg-animate hover-bg-light-yellow pv3 ph3" href="./src/main.py"><i
        class="icon icon-download"> </i> download</a> </span>        
    <div class="highlight"><pre class="chroma"><code class="language-python" data-lang="python"><span class="ch">#!/usr/bin/env python</span>

# coding:utf-8

import os import uuid

from fs import open_fs from tornado.web import Application, RequestHandler, url, StaticFileHandler

from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop

fs = open_fs('osfs://uploads/')

class Userform(RequestHandler):

<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s2">&#34;upload.html&#34;</span><span class="p">)</span>

# noinspection PyAbstractClass class AsyncFileUploadHandler(RequestHandler): """ Uploader """

<span class="k">def</span> <span class="nf">upload_async</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filepart</span><span class="p">):</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">filepart</span><span class="p">[</span><span class="s1">&#39;filename&#39;</span><span class="p">]</span>
    <span class="n">extension</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">splitext</span><span class="p">(</span><span class="n">filename</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">unique_name</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())</span> <span class="o">+</span> <span class="n">extension</span>
    <span class="n">fs</span><span class="o">.</span><span class="n">setbytes</span><span class="p">(</span><span class="n">unique_name</span><span class="p">,</span> <span class="n">filepart</span><span class="p">[</span><span class="s1">&#39;body&#39;</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">unique_name</span>

<span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="n">files</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">upload_async</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">files</span><span class="p">[</span><span class="s1">&#39;file&#39;</span><span class="p">]))</span>
    <span class="n">urls</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">name</span><span class="p">:</span> <span class="n">f</span><span class="s1">&#39;/uploads/{name}&#39;</span><span class="p">,</span> <span class="n">files</span><span class="p">))</span>
    <span class="n">data</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">files</span><span class="o">=</span><span class="n">files</span><span class="p">,</span> <span class="n">urls</span><span class="o">=</span><span class="n">urls</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">finish</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>

handlers = [ (r"/", Userform), url(pattern=r'/upload', handler=AsyncFileUploadHandler, name='upload'), (r"/uploads/(.*)", StaticFileHandler, {"path": "uploads"}) ]

App = Application(handlers=handlers, **dict(debug=False, autoreload=False, logging='debug')) if __name__ == "main": server = HTTPServer(App) server.bind(port=8000) server.start(num_processes=1) IOLoop.current().start()

<details class="ba bw2 mv2 pa2 b--light-gray">
    <summary class="fira mv1 dim fw7">Docker Compose</summary>
    <span><a download="docker-compose.yml" class="link black bg-animate hover-bg-light-yellow pv3 ph3" href="./src/docker-compose.yml"><i
        class="icon icon-download"> </i> download</a> </span>        
    <div class="highlight"><pre class="chroma"><code class="language-yml" data-lang="yml"><span class="k">version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;3&#34;</span><span class="w">

services: app: build: . volumes: - ./uploads:/uploads ports: - "8000:8000"

<details class="ba bw2 mv2 pa2 b--light-gray">
    <summary class="fira mv1 dim fw7">Dockerfile</summary>
    <span><a download="docker-compose.yml" class="link black bg-animate hover-bg-light-yellow pv3 ph3" href="./src/Dockerfile"><i
        class="icon icon-download"> </i> download</a> </span>        
    <div class="highlight"><pre class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="k">FROM</span><span class="s"> guneysu/python:3-onbuild</span><span class="err">

VOLUME ["/uploads"] ADD app /app WORKDIR / CMD python -m app

<details class="ba bw2 mv2 pa2 b--light-gray">
    <summary class="fira mv1 dim fw7">Requirements</summary>
    <span><a download="requirements.txt" class="link black bg-animate hover-bg-light-yellow pv3 ph3" href="./src/requirements.txt"><i
        class="icon icon-download"> </i> download</a> </span>        
    <div class="highlight"><pre class="chroma"><code class="language-txt" data-lang="txt">fs==2.0.4

tornado==4.5.1

<details class="ba bw2 mv2 pa2 b--light-gray">
    <summary class="fira mv1 dim fw7">Makefile</summary>
    <span><a download="Makefile" class="link black bg-animate hover-bg-light-yellow pv3 ph3" href="./src/Makefile"><i
        class="icon icon-download"> </i> download</a> </span>        
    <div class="highlight"><pre class="chroma"><code class="language-Makefile" data-lang="Makefile"><span class="nf">default</span><span class="o">:</span> <span class="n">run</span>

build: @docker-compose build

run: build @docker-compose up

test: @http -f POST :8000/upload file@requirements.txt file@requirements.txt

down: @docker-compose down

develop: @docker-compose up –build

.PHONY: default build run test down develop

Running

docker-compose up -d

Testing

http -f POST :8000/ file@requirements.txt
HTTP/1.1 200 OK
Content-Length: 215
Content-Type: application/json; charset=UTF-8
Date: Sat, 02 May 2020 14:36:36 GMT
Server: TornadoServer/4.5.1

{
    "files": [
        "6936cd27-01dc-4af6-adf9-970ad168ed6b.txt",
        "1c7052d7-0e29-4eb4-a914-f58d78289add.txt"
    ],
    "urls": [
        "/uploads/6936cd27-01dc-4af6-adf9-970ad168ed6b.txt",
        "/uploads/1c7052d7-0e29-4eb4-a914-f58d78289add.txt"
    ]
}
DMCA.com Protection Status