Browse Source

Support online railway deployment

Pin Fang 3 years ago
parent
commit
2d0935741c
6 changed files with 34 additions and 11 deletions
  1. 8 0
      README.md
  2. 5 1
      app.py
  3. 8 9
      common/expired_dict.py
  4. 8 1
      config.py
  5. 5 0
      main.py
  6. 0 0
      requirements.txt

+ 8 - 0
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.
 
 ## 常见问题
 

+ 5 - 1
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()

+ 8 - 9
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__()

+ 8 - 1
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))
 
 

+ 5 - 0
main.py

@@ -0,0 +1,5 @@
+# entry point for online railway deployment
+from app import run
+
+if __name__ == '__main__':
+	run()

+ 0 - 0
requirement.txt → requirements.txt