【问题标题】:Unable to use '#' as broker url in celery django无法在 celery django 中使用“#”作为代理 url
【发布时间】:2018-06-11 13:26:45
【问题描述】:
app = Celery('myapp',
             broker='amqp://user:pass#1@localhost:5672//',
             backend='rpc://',
             include=['myapp.tasks'])

我收到此错误

ValueError: int() 以 10 为底的无效文字:'pass'

此代码不起作用,我是 python 新手,Django 是否有它的转义序列?

我试过 u"", r"" ,'#' , '##' 和 '#' ,希望它能逃脱它,但它没有。

Traceback (most recent call last):
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\user\source\repos\BtcApi\BtcApi\btcapienv\Scripts\celery.exe\__main__.py", line 9, in <module>
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\__main__.py", line 14, in main
    _main()
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\celery.py", line 326, in main
    cmd.execute_from_commandline(argv)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\celery.py", line 488, in execute_from_commandline
    super(CeleryCommand, self).execute_from_commandline(argv)))
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\base.py", line 281, in execute_from_commandline
    return self.handle_argv(self.prog_name, argv[1:])
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\celery.py", line 480, in handle_argv
    return self.execute(command, argv)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\celery.py", line 412, in execute
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0])
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\worker.py", line 221, in run_from_argv
    return self(*args, **options)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\base.py", line 244, in __call__
    ret = self.run(*args, **kwargs)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\bin\worker.py", line 255, in run
    **kwargs)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\worker\worker.py", line 99, in __init__
    self.setup_instance(**self.prepare_args(**kwargs))
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\worker\worker.py", line 120, in setup_instance
    self._conninfo = self.app.connection_for_read()
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\app\base.py", line 752, in connection_for_read
    return self._connection(url or self.conf.broker_read_url, **kwargs)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\celery\app\base.py", line 828, in _connection
    'broker_connection_timeout', connect_timeout
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\kombu\connection.py", line 181, in __init__
    url_params = parse_url(hostname)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\kombu\utils\url.py", line 34, in parse_url
    scheme, host, port, user, password, path, query = _parse_url(url)
  File "c:\users\user\source\repos\btcapi\btcapi\btcapienv\lib\site-packages\kombu\utils\url.py", line 52, in url_to_parts
    parts.port,
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\urllib\parse.py", line 167, in port
    port = int(port, 10)
ValueError: invalid literal for int() with base 10: 'pass

我知道 # 是个问题,因为很明显,如果我从密码中删除该字符,它就可以正常工作

【问题讨论】:

  • 你能显示完整的堆栈跟踪吗?
  • 顺便说一句,问题与转义无关。在 Python 中,# 可以像字符串中的任何其他字符一样使用。

标签: django url celery broker


【解决方案1】:

uri 的rabbitmq documentation 指的是RFC3986。他们有一个关于保留字符的部分,# 就是其中之一。

如果 URI 组件的数据与保留的组件发生冲突 字符作为分隔符的目的,那么冲突的数据必须是 在形成 URI 之前进行百分比编码。

根据规范,您可以将 # 替换为 %23 - 或者只使用不包含保留字符的密码。

更新

您是对的,但那里也遵循相同的 RFC。 Celery (or kombu) uses urlliburllib tells they want to match the RFC 也是。

它在this line 中崩溃,您的密码被解释为端口。似乎密码中的# 强制库将密码解释为端口(失败,因为它不能转换为int)。请注意,域和端口由相同的字符 : 分隔,作为用户名和密码。

以下说明了正在发生的事情。请注意,# 之后的所有内容都被解释为您的 url 的片段。

>>> from urllib.parse import urlparse
>>> url = 'amqp://user:pass#1@localhost:5672//'
>>> urlparse(url)
ParseResult(scheme='amqp', netloc='user:pass', path='', params='', query='', fragment='1@localhost:5672//')

看看我们删除#后会发生什么

>>> url = 'amqp://user:pass%231@localhost:5672//'
>>> urlparse(url)
ParseResult(scheme='amqp', netloc='user:pass%231@localhost:5672', path='//', params='', query='', fragment='')
>>> urlparse(url).port
5672
>>> urlparse(url).password
'pass%231'

可以正确解析 url - 但我猜现在密码是错误的。遗憾的是,我找不到任何描述如何在 URI 密码中转义某些内容的资源。但老实说 - 这听起来很奇怪。密码中的转义字符?我建议只选择一个不带# 的密码,因为这会混淆python URL 解析器和很可能的其他实现。

【讨论】:

  • 替换不起作用,问题不在于rabbitmq,它是用芹菜解析url
  • 你是对的 - 但问题似乎是一样的。我已经更新了答案。
猜你喜欢
  • 2021-01-15
  • 2016-01-01
  • 2020-06-24
  • 1970-01-01
  • 2013-03-03
  • 2015-08-19
  • 1970-01-01
  • 2016-04-05
  • 2021-04-08
相关资源
最近更新 更多