diff --git a/README.md b/README.md index 28a08ea..19b3af1 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,14 @@ nohup python3 app.py & tail -f nohup.out # 在后台运行程序并通 参考文档 [Docker部署](https://github.com/limccn/chatgpt-on-wechat/wiki/Docker%E9%83%A8%E7%BD%B2) (Contributed by [limccn](https://github.com/limccn))。 +### 4. Railway部署 +[Use with Railway](#use-with-railway)(PaaS, Free, Stable, ✅Recommended) +> Railway offers $5 (500 hours) of runtime per month +1. Click the [Railway](https://railway.app/) button to go to the Railway homepage +2. Click the `Start New Project` button. +3. Click the `Deploy from Github repo` button. +4. Choose your repo (you can fork this repo firstly) +5. Set environment variable to override settings in config-template.json, such as: model, open_ai_api_base, open_ai_api_key, use_azure_chatgpt etc. ## 常见问题 diff --git a/app.py b/app.py index f07b275..7d42b9d 100644 --- a/app.py +++ b/app.py @@ -5,7 +5,8 @@ from channel import channel_factory from common.log import logger from plugins import * -if __name__ == '__main__': + +def run(): try: # load config config.load_config() @@ -21,3 +22,6 @@ if __name__ == '__main__': except Exception as e: logger.error("App startup failed!") logger.exception(e) + +if __name__ == '__main__': + run() \ No newline at end of file diff --git a/common/expired_dict.py b/common/expired_dict.py index bd70e99..a86923b 100644 --- a/common/expired_dict.py +++ b/common/expired_dict.py @@ -1,4 +1,4 @@ -import time +from datetime import datetime, timedelta class ExpiredDict(dict): @@ -8,8 +8,7 @@ class ExpiredDict(dict): def __getitem__(self, key): value, expiry_time = super().__getitem__(key) - # 如果元素已过期,则从字典中删除该元素并抛出 KeyError 异常 - if time.monotonic() > expiry_time: + if datetime.now() > expiry_time: del self[key] raise KeyError("expired {}".format(key)) self.__setitem__(key, value) @@ -24,20 +23,20 @@ class ExpiredDict(dict): return self[key] except KeyError: return default - + def __contains__(self, key): try: self[key] return True except KeyError: return False - + def keys(self): - keys=list(super().keys()) + keys = list(super().keys()) return [key for key in keys if key in self] - + def items(self): return [(key, self[key]) for key in self.keys()] - + def __iter__(self): - return self.keys().__iter__() + return self.keys().__iter__() \ No newline at end of file diff --git a/config.py b/config.py index 1a5a1f2..7dd921e 100644 --- a/config.py +++ b/config.py @@ -10,11 +10,18 @@ def load_config(): global config config_path = "./config.json" if not os.path.exists(config_path): - raise Exception('配置文件不存在,请根据config-template.json模板创建config.json文件') + logger.info('配置文件不存在,将使用config-template.json模板') + config_path = "./config-template.json" config_str = read_file(config_path) # 将json字符串反序列化为dict类型 config = json.loads(config_str) + + # override config with environment variables. + # Some online deployment platforms (e.g. Railway) deploy project from github directly. So you shouldn't put your secrets like api key in a config file, instead use environment variables to override the default config. + for name, value in os.environ.items(): + config[name] = value + logger.info("[INIT] load config: {}".format(config)) diff --git a/main.py b/main.py new file mode 100644 index 0000000..b22ebf2 --- /dev/null +++ b/main.py @@ -0,0 +1,5 @@ +# entry point for online railway deployment +from app import run + +if __name__ == '__main__': + run() \ No newline at end of file diff --git a/requirement.txt b/requirements.txt similarity index 100% rename from requirement.txt rename to requirements.txt