Git-HandClup / plugin_midjourney

一个Midjourneyd插件,支持imagine、upscale、variation、blend、describe五个基本命令
25 stars 5 forks source link

报错 'NoneType' object is not subscriptable #5

Open zhaoxitao opened 1 year ago

zhaoxitao commented 1 year ago

运行环境: 正常可以使用chatgpt-on-wechat的环境,其他插件工作正常,MJ插件可以被正常识别,也可以初始化成功。

配置情况: 在mj.py中配置了redis server地址,配置midjoureny-proxy api接口地址,没有在config.json中配置回调地址(不知道要回调什么东西,从哪里回调,但是看其他issue里讨论说这个不是必须配置)

错误描述: 插件正常开启后,使用 mj imagine prompt 开始画图,但是报错如下,请问这是个啥问题?

[ERROR][2023-06-13 10:45:14][chat_channel.py:268] - Worker return exception: 'NoneType' object is not subscriptable Traceback (most recent call last): File "/usr/local/python38/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, *self.kwargs) File "/home/pi/Applications/chatgpt-on-wechat/channel/chat_channel.py", line 146, in _handle reply = self._generate_reply(context) File "/home/pi/Applications/chatgpt-on-wechat/channel/chat_channel.py", line 156, in _generate_reply e_context = PluginManager().emit_event( File "/home/pi/Applications/chatgpt-on-wechat/plugins/plugin_manager.py", line 165, in emit_event instance.handlers[e_context.event](e_context, args, **kwargs) File "/home/pi/Applications/chatgpt-on-wechat/plugins/midjourney/mj.py", line 78, in on_handle_context image = self._get_redis_url(imagine["result"]) TypeError: 'NoneType' object is not subscriptable

Git-HandClup commented 1 year ago

建议弄个回调,目的是为了midjourney画完以后会自动调用你这个回调接口然后将结果存入redis中,这样的话在你mj.py调用完midjourney以后进行redis轮询的时候,就能查到在回调接口中存入的结果

PS:回调接口是另起一个服务专门用来处理midjourney画完以后的结果。

如果不用回调接口的话,midjourney-proxy提供了查询任务进度的接口,任务进度如果达到100就可以获取其中的图片链接和ID了,但是我没去调用(因为我当初在使用这个项目的时候还没有提供这个接口

Git-HandClup commented 1 year ago

建议弄个回调,目的是为了midjourney画完以后会自动调用你这个回调接口然后将结果存入redis中,这样的话在你mj.py调用完midjourney以后进行redis轮询的时候,就能查到在回调接口中存入的结果

PS:回调接口是另起一个服务专门用来处理midjourney画完以后的结果。

如果不用回调接口的话,midjourney-proxy提供了查询任务进度的接口,任务进度如果达到100就可以获取其中的图片链接和ID了,但是我没去调用(因为我当初在使用这个项目的时候还没有提供这个接口

可以将redis轮询改成请求查询任务进度的接口,按照midjourney平均10s左右的速度更新进度,让程序睡眠80s后再进行请求查询进度的接口。 接口返回的结果处理可能有以下三种:

  1. 如果进度失败就直接返回画图失败的错误提示
  2. 如果进度完成就直接取图片地址以及ID,然后按照正常的逻辑走就可以了
  3. 4.如果进度还在进行中就根据当前进度得出多少秒后再请求一次。
Git-HandClup commented 1 year ago

建议弄个回调,目的是为了midjourney画完以后会自动调用你这个回调接口然后将结果存入redis中,这样的话在你mj.py调用完midjourney以后进行redis轮询的时候,就能查到在回调接口中存入的结果 PS:回调接口是另起一个服务专门用来处理midjourney画完以后的结果。 如果不用回调接口的话,midjourney-proxy提供了查询任务进度的接口,任务进度如果达到100就可以获取其中的图片链接和ID了,但是我没去调用(因为我当初在使用这个项目的时候还没有提供这个接口

可以将redis轮询改成请求查询任务进度的接口,按照midjourney平均10s左右的速度更新进度,让程序睡眠80s后再进行请求查询进度的接口。 接口返回的结果处理可能有以下三种:

  1. 如果进度失败就直接返回画图失败的错误提示
  2. 如果进度完成就直接取图片地址以及ID,然后按照正常的逻辑走就可以了
  3. 4.如果进度还在进行中就根据当前进度得出多少秒后再请求一次。

我会考虑找个时间把这个程序的配置给优化一下,并提供如果没有回调地址就自动请求查询任务进度接口的方法。

zhaoxitao commented 1 year ago

建议弄个回调,目的是为了midjourney画完以后会自动调用你这个回调接口然后将结果存入redis中,这样的话在你mj.py调用完midjourney以后进行redis轮询的时候,就能查到在回调接口中存入的结果

PS:回调接口是另起一个服务专门用来处理midjourney画完以后的结果。

如果不用回调接口的话,midjourney-proxy提供了查询任务进度的接口,任务进度如果达到100就可以获取其中的图片链接和ID了,但是我没去调用(因为我当初在使用这个项目的时候还没有提供这个接口

感谢耐心解答,这个回调需要起一个什么样的服务?有什么资料可以参考吗?

Git-HandClup commented 1 year ago

我这边直接用PHP语言的webman框架起了个服务,顺便再用composer安装一下redis的依赖,只需要修改config文件夹下面的route.php文件指定路由

Route::options('[{path:.+}]', function (){
    return response('');
});
// MJ回调地址
Route::post('/midjourney/notify', 'app\controller\MidjourneyController@notify');
Route::disableDefaultRoute();

然后在app文件夹中的controller文件夹下创建MidjourneyController的php文件,代码很简单:

<?php

namespace App\controller;

use support\Redis;
use support\Request;

class MidjourneyController
{
    public function notify(Request $request)
    {
        $param = $request->all();
        // 成功就获取图片地址和ID
        if($param["status"] == "SUCCESS") {
            if ($param["action"] != "DESCRIBE") {
               Redis::set($param["id"], $param['imageUrl']);
               return true;
            } else if ($param["action"] == "DESCRIBE") {
               Redis::set($param["id"], $param['prompt']);
               return true;
            }
        }

        return false;
    }
}
Git-HandClup commented 1 year ago

你看一下webman框架的文档,启动webman以后会返回给你端口号,然后直接用你的服务器ip地址+服务端口替换配置文件中的ip+端口就可以了

zhaoxitao commented 1 year ago

我这边直接用PHP语言的webman框架起了个服务,顺便再用composer安装一下redis的依赖,只需要修改config文件夹下面的route.php文件指定路由

Route::options('[{path:.+}]', function (){
    return response('');
});
// MJ回调地址
Route::post('/midjourney/notify', 'app\controller\MidjourneyController@notify');
Route::disableDefaultRoute();

然后在app文件夹中的controller文件夹下创建MidjourneyController的php文件,代码很简单:

<?php

namespace App\controller;

use support\Redis;
use support\Request;

class MidjourneyController
{
    public function notify(Request $request)
    {
        $param = $request->all();
        // 成功就获取图片地址和ID
        if($param["status"] == "SUCCESS") {
            if ($param["action"] != "DESCRIBE") {
               Redis::set($param["id"], $param['imageUrl']);
               return true;
            } else if ($param["action"] == "DESCRIBE") {
               Redis::set($param["id"], $param['prompt']);
               return true;
            }
        }

        return false;
    }
}

非常感谢!

Git-HandClup commented 1 year ago

目前能够支持在没有提供回调地址的情况下也可以正常获取图片