[python] 파이썬 요청 파일 업로드

Python 요청 라이브러리를 사용하여 파일을 업로드하는 간단한 작업을 수행하고 있습니다. Stack Overflow를 검색했는데 아무도 같은 문제가없는 것 같았습니다. 즉, 파일이 서버에서 수신되지 않는다는 것입니다.

import requests
url='http://nesssi.cacr.caltech.edu/cgi-bin/getmulticonedb_release2.cgi/post'
files={'files': open('file.txt','rb')}
values={'upload_file' : 'file.txt' , 'DB':'photcat' , 'OUT':'csv' , 'SHORT':'short'}
r=requests.post(url,files=files,data=values)

‘upload_file’키워드의 값을 내 파일 이름으로 채 웁니다. 비워두면

Error - You must select a file to upload!

그리고 이제 나는

File  file.txt  of size    bytes is  uploaded successfully!
Query service results:  There were 0 lines.

파일이 비어있는 경우에만 나타납니다. 그래서 내 파일을 성공적으로 보내는 방법에 대해 고민했습니다. 이 웹 사이트로 이동하여 양식을 수동으로 채우면 일치하는 개체의 멋진 목록이 반환되므로 파일이 작동한다는 것을 알고 있습니다. 모든 힌트에 감사드립니다.

관련된 다른 스레드 (그러나 내 문제에 대답하지 않음) :



답변

경우 upload_file파일 사용으로 의미 :

files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}

r = requests.post(url, files=files, data=values)

requests으로 여러 부분으로 형성 POST 본체 보낼 upload_file의 내용에 필드 세트file.txt 파일.

파일 이름은 특정 필드의 MIME 헤더에 포함됩니다.

>>> import requests
>>> open('file.txt', 'wb')  # create an empty demo file
<_io.BufferedWriter name='file.txt'>
>>> files = {'upload_file': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--c226ce13d09842658ffbd31e0563c6bd
Content-Disposition: form-data; name="upload_file"; filename="file.txt"


--c226ce13d09842658ffbd31e0563c6bd--

참고 filename="file.txt"매개 변수에 .

files더 많은 제어가 필요한 경우 2-4 개의 요소가 있는 매핑 값에 튜플을 사용할 수 있습니다 . 첫 번째 요소는 파일 이름, 그 뒤에 콘텐츠, 선택적 콘텐츠 유형 헤더 값 및 추가 헤더의 선택적 매핑입니다.

files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}

이것은 선택적 헤더를 제외하고 대체 파일 이름과 콘텐츠 유형을 설정합니다.

다른 필드가 지정되지 않은 파일에서 전체 POST 본문 을 가져 오는 것을 의미하는 경우 files매개 변수를 사용하지 말고 파일을 data. 그런 다음 설정할 수 있습니다 Content-Type아무 것도 그렇지 않으면 설정되지 않습니다으로 너무 헤더를. Python 요청-파일의 POST 데이터를 참조하십시오 .


답변

(2018) 새로운 파이썬 요청 라이브러리는이 프로세스를 단순화했습니다. ‘files’변수를 사용하여 멀티 파트 인코딩 파일을 업로드하고 싶다는 신호를 보낼 수 있습니다.

url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}

r = requests.post(url, files=files)
r.text


답변

클라이언트 업로드

Python requests라이브러리를 사용 하여 단일 파일을 업로드하려는 경우 requests lib 는 스트리밍 업로드를 지원하므로 메모리를 읽지 않고도 대용량 파일 이나 스트림 을 보낼 수 있습니다 .

with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f)

서버 측

그런 다음 server.py메모리에로드하지 않고 스트림을 파일에 저장하도록 파일을 측면에 저장합니다. 다음은 Flask 파일 업로드 를 사용하는 예입니다 .

@app.route("/upload", methods=['POST'])
def upload_file():
    from werkzeug.datastructures import FileStorage
    FileStorage(request.stream).save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
    return 'OK', 200

또는 사용 양식 데이터 구문 분석을 WERKZEUG “의 문제에 대한 수정에 언급 한 바와 같이 대용량 파일 업로드가 메모리를 먹는 하기 위해” 대용량 파일 업로드에 비효율적으로 메모리를 사용하지 않도록 ~ 60 초 (일 22 지브 파일을. 메모리 사용량이 일정 정도에있다 13MiB.).

@app.route("/upload", methods=['POST'])
def upload_file():
    def custom_stream_factory(total_content_length, filename, content_type, content_length=None):
        import tempfile
        tmpfile = tempfile.NamedTemporaryFile('wb+', prefix='flaskapp', suffix='.nc')
        app.logger.info("start receiving file ... filename => " + str(tmpfile.name))
        return tmpfile

    import werkzeug, flask
    stream, form, files = werkzeug.formparser.parse_form_data(flask.request.environ, stream_factory=custom_stream_factory)
    for fil in files.values():
        app.logger.info(" ".join(["saved form name", fil.name, "submitted as", fil.filename, "to temporary file", fil.stream.name]))
        # Do whatever with stored file at `fil.stream.name`
    return 'OK', 200


답변

우분투에서는 이런 식으로 적용 할 수 있습니다.

특정 위치 (임시)에 파일을 저장 한 다음 열어서 API로 보내기

      path = default_storage.save('static/tmp/' + f1.name, ContentFile(f1.read()))
      path12 = os.path.join(os.getcwd(), "static/tmp/" + f1.name)
      data={} #can be anything u want to pass along with File
      file1 = open(path12, 'rb')
      header = {"Content-Disposition": "attachment; filename=" + f1.name, "Authorization": "JWT " + token}
       res= requests.post(url,data,header)


답변