Возврат данных о загрузке HTTP на сервер Sanic - PullRequest
0 голосов
/ 22 октября 2018

Я экспериментирую с загрузкой данных на sanic веб-сервер.Для этого я выдаю запрос POST с помощью curl.Я пытаюсь вернуть некоторые данные после запроса POST.Основанием для этого является возвращение некоторого идентификатора, представляющего загрузку на стороне сервера.Но это не похоже на работу.Теперь я задаюсь вопросом: моя программа неверна?curl не записывает вывод?Или это ошибка в sanic?Может ли кто-нибудь помочь мне здесь?Спасибо!

Вот программа Python:

import signal
import asyncio
import uvloop

import sanic

app = sanic.Sanic(__name__)
loop = asyncio.get_event_loop()
server = app.create_server(host="localhost", port=3002)
task = asyncio.ensure_future(server)

@app.post("/testUpload", stream=True)
async def api_testUpload(request):

    async def doStream(response):
        while True:
            body = await request.stream.get()
            if body is None:
                break

            sanic.response.json({
                "result": "good!"
            })

    return sanic.response.stream(doStream)

signal.signal(signal.SIGINT, lambda s, f: loop.stop())
try:
    loop.run_forever()
except:
    loop.stop()

Вы можете вызвать curl следующим образом:

curl -v --data-binary "@somefile.data" http://localhost:3002/testUpload

А вот что curl пишет в STDOUT:

*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3002 (#0)
> POST /testUpload HTTP/1.1
> Host: localhost:3002
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Length: 334504
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
> 
< HTTP/1.1 200 OK
< Keep-Alive: 5
< Transfer-Encoding: chunked
< Content-Type: text/plain; charset=utf-8
< 
* Done waiting for 100-continue
* We are completely uploaded and fine
* Connection #0 to host localhost left intact

Как видите, генерируется ответ text/plain.Это должно быть application/json с моими данными, не так ли?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Если я понимаю ваш вопрос, то вам вообще не нужна трансляция.Мне кажется, что вы пытаетесь сделать следующее:

  • загрузить файл
  • обработать файл и что-то сделать
  • вернуть ответ, чтобы сказать, что что-тобыло сделано

Если это так, то вам вообще не нужна потоковая передача.

import sanic

app = sanic.Sanic(__name__)

def do_something(file):
    print(f'doing something to {file.name}')

@app.post("/testUpload")
async def api_testUpload(request):
    myfile = request.files.get('myfile')

    do_something(myfile)

    return sanic.response.json({
        'body': myfile.body,
        'name': myfile.name,
        'type': myfile.type,
    })

app.run(host='localhost', port=3002, auto_reload=True)

Затем вы можете поразить вашу конечную точку файлом ...

curl -i -F "myfile=@/tmp/somefile.txt" http://localhost:3002/testUpload

И вы должны увидеть в своих журналах:

[2018-10-25 10:09:56 +0300] [16051] [INFO] Goin' Fast @ http://localhost:3002
[2018-10-25 10:09:56 +0300] [16055] [INFO] Starting worker [16055]
doing something to somefile.txt
[2018-10-25 10:09:59 +0300] - (sanic.access)[INFO][127.0.0.1:39306]: POST http://localhost:3002/testUpload  200 62

И ваше возвращение

HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
Content-Length: 62
Content-Type: application/json

{"body":"FOOBAR\n","name":"somefile.txt","type":"text\/plain"}

Теперь, я полагаю, если вы загружаете файл, и вы хотелидля потоковой передачи ответа этой загрузки, как это происходит на тот или иной запрос, это будет другой проблемой.

Надеюсь, это поможет.

0 голосов
/ 22 октября 2018

Это не правильный способ сделать это.sanic API не работает здесь интуитивно.Чтобы записать данные после получения отправленных байтов, вы должны сделать это в функции потоковой передачи doStream():

await response.write(json.dumps({
    "result": "good!"
}))
...