Python requests_toolbelt MultipartEncoder 文件名

2024-05-06

使用 requests_toolbelt 以多部分形式上传大文件,我构建了一个方法,可以成功上传文件,但是我无法访问发布的文件名。如何访问服务器上的文件名?

# client-side
file = open('/Volumes/Extra/test/my_video.mpg', 'rb')
payload = MultipartEncoder({file.name: file})
r = requests.post(url, data=payload, headers={'Content-Type': 'application/octet-stream'})

# server-side
@view_config(route_name='remote.agent_upload', renderer='json')
def remote_agent_upload(request):
    r = request.response
    fs = request.body_file
    f = open('/Volumes/Extra/tests2/bar.mpg', 'wb')  # wish to use filename here
    f.write(fs.read())
    fs.close()
    f.close()
    return r

好的,看起来您正在使用文件名作为字段名。另外,您这样做的方式似乎整个帖子内容都被写入文件......这是期望的结果吗?在服务器端写入 mpg 文件后,您是否尝试过实际播放它们?

我目前没有可供测试的 HTTP 服务器,它会自动为我提供一个请求对象,但我假设该请求对象是一个 webob.Request 对象(至少看起来是这样,请更正)如果我错了就是我)

好吧,让我给你展示一下我的测试。 (这适用于 python3.4,不确定您使用的是什么版本的 Python,但我认为它也应该适用于 Python 2.7 - 虽然未经测试)

此测试中的代码有点长,但有大量注释,可以帮助您理解我在每一步中所做的事情。希望它能让您更好地了解 HTTP 请求和响应如何通过您正在使用的工具在 python 中工作

# My Imports
from requests_toolbelt import MultipartEncoder
from webob import Request
import io

# Create a buffer object that can be read by the MultipartEncoder class
# This works just like an open file object
file = io.BytesIO()

# The file content will be simple for my test.
# But you could just as easily have a multi-megabyte mpg file
# Write the contents to the file
file.write(b'test mpg content')

# Then seek to the beginning of the file so that the
# MultipartEncoder can read it from the beginning
file.seek(0)

# Create the payload
payload = MultipartEncoder(
    {

        # The name of the file upload field... Not the file name
        'uploadedFile': (

            # This would be the name of the file
            'This is my file.mpg',

            # The file handle that is ready to be read from
            file,

            # The content type of the file
            'application/octet-stream'
        )
    }
)

# To send the file, you would use the requests.post method
# But the content type is not application-octet-stream
# The content type is multipart/form-data; with a boundary string
# Without the proper header type, your server would not be able to
# figure out where the file begins and ends and would think the
# entire post content is the file, which it is not. The post content
# might even contain multiple files
# So, to send your file, you would use:
#
# response = requests.post(url, data=payload, headers={'Content-Type': payload.content_type})

# Instead of sending the payload to the server,
# I am just going to grab the output as it would be sent
# This is because I don't have a server, but I can easily
# re-create the object using this output
postData = payload.to_string()

# Create an input buffer object
# This will be read by our server (our webob.Request object)
inputBuffer = io.BytesIO()

# Write the post data to the input buffer so that the webob.Request object can read it
inputBuffer.write(postData)

# And, once again, seek to 0
inputBuffer.seek(0)

# Create an error buffer so that errors can be written to it if there are any
errorBuffer = io.BytesIO()

# Setup our wsgi environment just like the server would give us
environment = {
    'HTTP_HOST': 'localhost:80',
    'PATH_INFO': '/index.py',
    'QUERY_STRING': '',
    'REQUEST_METHOD': 'POST',
    'SCRIPT_NAME': '',
    'SERVER_NAME': 'localhost',
    'SERVER_PORT': '80',
    'SERVER_PROTOCOL': 'HTTP/1.0',
    'CONTENT_TYPE': payload.content_type,
    'wsgi.errors': errorBuffer,
    'wsgi.input': inputBuffer,
    'wsgi.multiprocess': False,
    'wsgi.multithread': False,
    'wsgi.run_once': False,
    'wsgi.url_scheme': 'http',
    'wsgi.version': (1, 0)
}

# Create our request object
# This is the same as your request object and should have all our info for reading
# the file content as well as the file name
request = Request(environment)

# At this point, the request object is the same as what you get on your server
# So, from this point on, you can use the following code to get
# your actual file content as well as your file name from the object

# Our uploaded file is in the POST. And the POST field name is 'uploadedFile'
# Grab our file so that it can be read
uploadedFile = request.POST['uploadedFile']

# To read our content, you can use uploadedFile.file.read()
print(uploadedFile.file.read())

# And to get the file name, you can use uploadedFile.filename
print(uploadedFile.filename)

所以,我认为这个修改后的代码对你有用。 (希望) 再说一次,没有测试,因为我实际上没有服务器可以测试。而且,我不知道你的“请求”对象在服务器端是什么样的对象......好吧,这里是:

# client-side
import requests
file = open('/Volumes/Extra/test/my_video.mpg', 'rb')
payload = MultipartEncoder({'uploadedFile': (file.name, file, 'application/octet-stream')})
r = requests.post('http://somewhere/somefile.py', data=payload, headers={'Content-Type': payload.content_type})

# server-side
@view_config(route_name='remote.agent_upload', renderer='json')
def remote_agent_upload(request):

    # Write your actual file contents, not the post data which contains multi part boundary
    uploadedFile = request.POST['uploadedFile']
    fs = uploadedFile.file

    # The file name is insecure. What if the file name comes through as '../../../etc/passwd'
    # If you don't secure this, you've just wiped your /etc/passwd file and your server is toast
    # (assuming the web user has write permission to the /etc/passwd file
    # which it shouldn't, but just giving you a worst case scenario)
    fileName = uploadedFile.filename

    # Secure the fileName here... 
    # Make sure it doesn't have any slashes or double dots, or illegal characters, etc.
    # I'll leave that up to you

    # Write the file
    f = open('/Volumes/Extra/tests2/' + fileName, 'wb')
    f.write(fs.read())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python requests_toolbelt MultipartEncoder 文件名 的相关文章

随机推荐

  • Sense 手机上的 Android 应用程序主题

    我在有关感应手机上的应用程序的 UI 项目上遇到了障碍 我无法在谷歌或SO上制作搜索查询来找到我所追求的任何参考 有没有办法让我的应用程序主题的 UI 样式与手机当前应用的样式相匹配 我基本上追求不同 UI 小部件 复选框 微调器 按钮等
  • Python 中的 Flask 错误:“无法导入 webapp”

    我正在尝试运行 Flask 但是 每当我输入 flask run 时 都会出现错误 Could not import webapp 作为参考 我正在使用 Visual Studio Code 并运行以下代码 from flask impor
  • Laravel:将变量传递给多个视图

    我想动态地制作菜单 因此显示 本月电影 而不是 十二月电影 参见图片 十二月是每月更新的当前月份 我的问题是菜单不属于特定的路由 控制器 因此我无法像其他路由一样传递变量 例子 month Carbon now gt format F re
  • 选择容器中的最后一个单词

    我只是想知道是否有办法选择 DIV 中的最后一个单词 我认为没有任何明显的方法可以做到这一点 那么有什么解决方法吗 我不介意使用 CSS 或 Javascript 来实现这一点 提前致谢 div or no div 它归结为基本的字符串操作
  • 返回动态列集

    我创建了以下函数来根据该函数的参数返回列集 CREATE OR REPLACE FUNCTION getColumns IN column1 text IN column2 text IN column3 text IN column4 t
  • Zend,Application.ini 中的全局变量?

    我有一个问题 因为我需要一个全局静态变量 并且我有一个问题是否有可能将其添加到 application ini 文件中 该怎么做 或者我必须 使用静态变量创建抽象类 在 Zend Registry 中注册它 以便从所有应用程序访问该变量 在
  • 如何使用 R 从 github 存储库文件夹中获取列表文件

    我想知道是否存在一个函数或链接或任何可以像这样工作的方法list files R 中的函数 但位于存储在 github 存储库上的文件夹上 示例 github 存储库文件夹 https github com KZPS Spotkania t
  • 从另一个项目调用项目脚本

    我正在构建一个 RStudio 项目 项目 2 我想在其中访问另一个已构建的 RStudio 项目 项目 1 中包含的某些脚本 项目 1 包含各种脚本 其中一些脚本通过source 来电 有什么办法可以实现这一点吗 我最初认为在项目 1 中
  • 为 Json 对象生成的 C# 类的优点和缺点

    我有示例 Json 我需要将其序列化为 C 对象 我决定为此目的利用杠杆Json Net http json codeplex com 图书馆 我还需要有 C 类来表示这个 Json 可以使用创建类Json C 类生成器 http json
  • C#代表,参考解析时间

    我有一个关于 net 代表的简单问题 假设我有这样的事情 public void Invoke Action
  • Silverlight Web 服务“远程服务器返回错误:NotFound”

    我有一个 Silverlight 应用程序 它检索可序列化类的列表 在这些类中还有其他可序列化的类 其中一些也在列表中 问题是一切工作正常 直到我填充可序列化类列表之一 导致 silverlight 应用程序抛出异常 远程服务器返回错误 N
  • 如何接受同一个 Serde 字段的多个反序列化名称?

    我正在尝试使用 Serde 反序列化 JSON serde json 和 XML serde xml rs 基于以下结构的文件 use serde derive Deserialize derive Debug Clone PartialE
  • 异步设计中如何知道哪个QNetworkReply属于QNetworkRequest?

    我可以轻松地用 C 进行异步设计 HttpResponseMessage response await httpClient GetAsync InputAddress Text run when request finished And
  • Terraform - 如果在 for_each 内。我可以过滤 for_each 吗?

    通过以下内容 我可以循环遍历资源块 轻松地将路由表关联添加到 所有 子网 但是 我只需要为我的公共子网创建关联 我怎样才能使这个 if 语句起作用 或者任何其他方式来过滤each value class pub 对于这个问题 resourc
  • 部署使用 fileInput 上传数据的闪亮应用程序时出错

    部署我的第一个闪亮应用程序 简单的 html 解析器 让用户上传 html 文件 然后解析它以获取 LinkedIn 上的分享 提及 喜欢的信息 该应用程序在本地运行良好 在部署之前进行了测试 并且 Rstudio 没有显示任何部署错误 但
  • 对于固定的 960px 布局,我应该在 twitter bootstrap 中设置哪些值?

    我正在使用 twitter bootstrap 并且从 github 克隆了 less 我想设置网格宽度变量 因为我需要 960px 固定布局 940px 宽度的默认值为 gridColumns 12 gridColumnWidth 60p
  • Laravel,2 个域中的 2 个项目同一会话

    我正在 2 个不同的域 domain1 tld 和域 2 tld 中创建 2 个项目 domain1 tld 是主要事件生成器页面 domain2 tld 是其事件之一 我想共享相同的会话 它们实际上共享相同的数据库和相同的 apache
  • CSS3的:root伪类和html有什么区别?

    我似乎找不到太多关于这方面的信息 粉碎杂志 http coding smashingmagazine com 2011 03 30 how to use css3 pseudo classes 似乎是在说html and root是同一件事
  • 为什么我们不在 main 中使用 (void) 呢?

    人们使用void main empty parens 我被教导写作void main void 任何想法有什么区别 我不确定现在的标准是什么 但在传统的 ANSI C 中 使用空括号表示该函数可以采用any参数数量 声明一个void另一方面
  • Python requests_toolbelt MultipartEncoder 文件名

    使用 requests toolbelt 以多部分形式上传大文件 我构建了一个方法 可以成功上传文件 但是我无法访问发布的文件名 如何访问服务器上的文件名 client side file open Volumes Extra test m