commandchat 0.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 cxoto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.1
2
+ Name: commandchat
3
+ Version: 0.0.4
4
+ Summary: use command to chat with openai models
5
+ Home-page: https://github.com/
6
+ Author: xoto
7
+ Author-email: xxx.tao.c@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ [English](README.md) | [中文](README-zh.md)
15
+
16
+ # openai-commandchat
17
+
18
+ ## Quick start
19
+
20
+ Use this command line to install the python packages:
21
+
22
+ ```bash
23
+ pip3 install commandchat
24
+ ```
25
+ Or use the following command line to guide you to a specific python version, if you have multiple versions of python locally
26
+ ```bash
27
+ python3.x -m pip3 install commandchat
28
+ ```
29
+
30
+
31
+
32
+ ## Features
33
+ - You can set the api_key for openai with a simple command, and you can distinguish the key for your multiple accounts with a profile (default `default` if you don't specify it): `occ configure -profile`
34
+ - You can use the command `occ chat` to chat with the chat-GPT model `gpt-3.5-turbo`.
35
+ ### To be implemented
36
+ - You can use the `occ image -desc` command with chat-GPT's model to describe the image you want to generate, giving you back a link to the image.
37
+ - You can use the `occ xxx -yyy` command to chat with a specified model of chat-GPT to complete a task you specify or give you advice.
38
+ - Others not yet thought of
39
+
40
+
41
+ ## Requirements
42
+
43
+ A terminal with Python and pip installed:
44
+
45
+ - Installed python environment and python version >= 3.9
46
+ - Install the openai package
47
+
48
+ ## Installing
49
+
50
+ ```bash
51
+ pip3 install commandchat
52
+ ```
53
+
54
+ ## Uninstall
55
+
56
+ ```bash
57
+ pip3 uninstall commandchat
58
+ ```
59
+
60
+ ## Feedback or questions
61
+ - You can send an email to: ``xxx.tao.c@gmail.com`` or ``xoto@outlook.be``
62
+
63
+ ## License
64
+ MIT
65
+
@@ -0,0 +1,52 @@
1
+ [English](README.md) | [中文](README-zh.md)
2
+
3
+ # openai-commandchat
4
+
5
+ ## Quick start
6
+
7
+ Use this command line to install the python packages:
8
+
9
+ ```bash
10
+ pip3 install commandchat
11
+ ```
12
+ Or use the following command line to guide you to a specific python version, if you have multiple versions of python locally
13
+ ```bash
14
+ python3.x -m pip3 install commandchat
15
+ ```
16
+
17
+
18
+
19
+ ## Features
20
+ - You can set the api_key for openai with a simple command, and you can distinguish the key for your multiple accounts with a profile (default `default` if you don't specify it): `occ configure -profile`
21
+ - You can use the command `occ chat` to chat with the chat-GPT model `gpt-3.5-turbo`.
22
+ ### To be implemented
23
+ - You can use the `occ image -desc` command with chat-GPT's model to describe the image you want to generate, giving you back a link to the image.
24
+ - You can use the `occ xxx -yyy` command to chat with a specified model of chat-GPT to complete a task you specify or give you advice.
25
+ - Others not yet thought of
26
+
27
+
28
+ ## Requirements
29
+
30
+ A terminal with Python and pip installed:
31
+
32
+ - Installed python environment and python version >= 3.9
33
+ - Install the openai package
34
+
35
+ ## Installing
36
+
37
+ ```bash
38
+ pip3 install commandchat
39
+ ```
40
+
41
+ ## Uninstall
42
+
43
+ ```bash
44
+ pip3 uninstall commandchat
45
+ ```
46
+
47
+ ## Feedback or questions
48
+ - You can send an email to: ``xxx.tao.c@gmail.com`` or ``xoto@outlook.be``
49
+
50
+ ## License
51
+ MIT
52
+
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.1
2
+ Name: commandchat
3
+ Version: 0.0.4
4
+ Summary: use command to chat with openai models
5
+ Home-page: https://github.com/
6
+ Author: xoto
7
+ Author-email: xxx.tao.c@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+
14
+ [English](README.md) | [中文](README-zh.md)
15
+
16
+ # openai-commandchat
17
+
18
+ ## Quick start
19
+
20
+ Use this command line to install the python packages:
21
+
22
+ ```bash
23
+ pip3 install commandchat
24
+ ```
25
+ Or use the following command line to guide you to a specific python version, if you have multiple versions of python locally
26
+ ```bash
27
+ python3.x -m pip3 install commandchat
28
+ ```
29
+
30
+
31
+
32
+ ## Features
33
+ - You can set the api_key for openai with a simple command, and you can distinguish the key for your multiple accounts with a profile (default `default` if you don't specify it): `occ configure -profile`
34
+ - You can use the command `occ chat` to chat with the chat-GPT model `gpt-3.5-turbo`.
35
+ ### To be implemented
36
+ - You can use the `occ image -desc` command with chat-GPT's model to describe the image you want to generate, giving you back a link to the image.
37
+ - You can use the `occ xxx -yyy` command to chat with a specified model of chat-GPT to complete a task you specify or give you advice.
38
+ - Others not yet thought of
39
+
40
+
41
+ ## Requirements
42
+
43
+ A terminal with Python and pip installed:
44
+
45
+ - Installed python environment and python version >= 3.9
46
+ - Install the openai package
47
+
48
+ ## Installing
49
+
50
+ ```bash
51
+ pip3 install commandchat
52
+ ```
53
+
54
+ ## Uninstall
55
+
56
+ ```bash
57
+ pip3 uninstall commandchat
58
+ ```
59
+
60
+ ## Feedback or questions
61
+ - You can send an email to: ``xxx.tao.c@gmail.com`` or ``xoto@outlook.be``
62
+
63
+ ## License
64
+ MIT
65
+
@@ -0,0 +1,20 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ commandchat.egg-info/PKG-INFO
5
+ commandchat.egg-info/SOURCES.txt
6
+ commandchat.egg-info/dependency_links.txt
7
+ commandchat.egg-info/entry_points.txt
8
+ commandchat.egg-info/requires.txt
9
+ commandchat.egg-info/top_level.txt
10
+ occ/CommandChat.py
11
+ occ/__init__.py
12
+ occ/command/__init__.py
13
+ occ/command/__main__.py
14
+ occ/commons/__init__.py
15
+ occ/commons/config.py
16
+ occ/configuration/__init__.py
17
+ occ/configuration/profile_config.py
18
+ occ/utils/CommonUtil.py
19
+ occ/utils/__init__.py
20
+ occ/utils/logger.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ occ = occ.command.__main__:main
@@ -0,0 +1,3 @@
1
+ click
2
+ Image
3
+ openai
@@ -0,0 +1,116 @@
1
+ import json
2
+ import openai
3
+ import os
4
+
5
+ from occ.commons.config import get_env
6
+ from occ.utils import logger
7
+ from occ.utils.CommonUtil import save_and_copy_image, waiting_start, waiting_stop
8
+
9
+
10
+ def get_home_path():
11
+ homedir = os.environ.get('HOME', None)
12
+ if os.name == 'nt':
13
+ homedir = os.path.expanduser('~')
14
+ return homedir
15
+
16
+
17
+ class CommandChat:
18
+ DEFAULT_PROFILE = "default"
19
+ DEFAULT_CHAT_LOG_ID = "chat-1"
20
+
21
+ def __init__(self, profile=None, chat_log_id=None):
22
+ self.api_key = get_env(profile or self.DEFAULT_PROFILE, "api_key")
23
+ self.api_base = get_env(profile or self.DEFAULT_PROFILE, "api_base_url")
24
+ self.limit_history = int(get_env(profile or self.DEFAULT_PROFILE, "limit_history") or 4)
25
+ self.chat_log_id = chat_log_id or self.DEFAULT_CHAT_LOG_ID
26
+ self.folder_path = os.path.join(get_home_path(), ".occ", profile or self.DEFAULT_PROFILE)
27
+ self.image_folder_path = os.path.join(self.folder_path, "images")
28
+ self.file_name = os.path.join(self.folder_path, f"{self.chat_log_id}.log")
29
+ os.makedirs(self.folder_path, exist_ok=True)
30
+ os.makedirs(self.image_folder_path, exist_ok=True)
31
+ if not os.path.exists(self.file_name):
32
+ open(self.file_name, 'w').close()
33
+ self.messages = [json.loads(line) for line in (line.strip() for line in open(self.file_name)) if line.strip()]
34
+
35
+ def image_create(self, description, size, num):
36
+ openai.api_key = self.api_key
37
+ openai.api_base = self.api_base
38
+ try:
39
+ response = openai.Image.create(
40
+ prompt=description,
41
+ n=num,
42
+ size=size
43
+ )
44
+ for index in range(num):
45
+ image_url = response['data'][index]['url']
46
+ save_and_copy_image(image_url, self.image_folder_path)
47
+ except openai.error.OpenAIError as e:
48
+ print(e.http_status)
49
+ print(e.error)
50
+
51
+ def image_create_variation(self, img_file, size):
52
+ openai.api_key = self.api_key
53
+ openai.api_base = self.api_base
54
+ try:
55
+ response = openai.Image.create_variation(
56
+ open(img_file, "rb"),
57
+ n=1,
58
+ size=size
59
+ )
60
+ save_and_copy_image(response['data'][0]['url'], self.image_folder_path)
61
+ except openai.error.OpenAIError as e:
62
+ print(e.http_status)
63
+ print(e.error)
64
+
65
+ def chat(self, message):
66
+ openai.api_key = self.api_key
67
+ openai.api_base = self.api_base
68
+ message = {"role": "user", "content": message}
69
+ self.messages.append(message)
70
+ waiting_start()
71
+ response = openai.ChatCompletion.create(
72
+ model="gpt-3.5-turbo",
73
+ messages=self.messages,
74
+ temperature=0.2,
75
+ top_p=1,
76
+ frequency_penalty=0.0,
77
+ presence_penalty=0.5,
78
+ stream=True
79
+ )
80
+ waiting_stop()
81
+ completion_text = ''
82
+ content = ''
83
+ role = None
84
+ for event in response:
85
+ if event['choices'][0]["finish_reason"] == "stop":
86
+ break
87
+ if role is None:
88
+ try:
89
+ role = event['choices'][0]["delta"]["role"]
90
+ except Exception:
91
+ content = event['choices'][0]["delta"]["content"]
92
+ else:
93
+ content = event['choices'][0]["delta"]["content"]
94
+ completion_text += content
95
+ print(content, end="")
96
+ print("\n")
97
+ self.record_chat_logs(message, {"role": role, "content": completion_text.replace("\n\n", "")})
98
+
99
+ def record_chat_logs(self, content, completion_text):
100
+ with open(self.file_name, 'r+') as f:
101
+ lines = f.readlines()
102
+ if len(lines) >= self.limit_history:
103
+ limit_history_ = (len(lines) + 2 - self.limit_history)
104
+ with open(os.path.join(self.folder_path, self.chat_log_id + '_history.log'), 'a+') as hf:
105
+ hf.writelines("\n")
106
+ hf.writelines(lines[:limit_history_])
107
+ lines = lines[limit_history_:]
108
+ if len(lines) == 0:
109
+ lines.append('{}\n{}'.format(json.dumps(content, ensure_ascii=False),
110
+ json.dumps(completion_text, ensure_ascii=False)))
111
+ else:
112
+ lines.append('\n{}\n{}'.format(json.dumps(content, ensure_ascii=False),
113
+ json.dumps(completion_text, ensure_ascii=False)))
114
+ f.seek(0)
115
+ f.truncate()
116
+ f.writelines(lines)
File without changes
File without changes
@@ -0,0 +1,70 @@
1
+ from __future__ import absolute_import
2
+
3
+ import click
4
+ import pkg_resources
5
+
6
+ import occ.utils.logger as logger
7
+ from occ.configuration.profile_config import add_profile, add_default_profile
8
+ from occ.CommandChat import CommandChat
9
+ from occ.utils.CommonUtil import waiting_stop
10
+
11
+ VERSION = pkg_resources.require("commandchat")[0].version
12
+
13
+
14
+ @click.group()
15
+ @click.version_option(version=VERSION, prog_name='openai-commandchat')
16
+ def commandchat_operator():
17
+ pass
18
+
19
+
20
+ @click.command()
21
+ @click.option('-profile', help='Enable profile name')
22
+ def configure(profile):
23
+ if profile is not None:
24
+ add_profile(profile)
25
+ else:
26
+ add_default_profile()
27
+
28
+
29
+ @click.command()
30
+ @click.argument('message')
31
+ @click.option('-id', help=' enter chat id, something like context')
32
+ @click.option('-profile', help='Enable profile name')
33
+ def chat(message, id, profile):
34
+ try:
35
+ CommandChat(profile=profile, chat_log_id=id).chat(message)
36
+ except Exception as e:
37
+ logger.log_g(str(e))
38
+ waiting_stop()
39
+
40
+
41
+ size_map = {
42
+ "s": "256x256",
43
+ "S": "256x256",
44
+ "m": "512x512",
45
+ "M": "512x512",
46
+ "l": "1024x1024",
47
+ "L": "1024x1024"
48
+ }
49
+
50
+
51
+ @click.command()
52
+ @click.option('-desc', help=' Enter the description of the images you want')
53
+ @click.option('-size',
54
+ help=' Enter the size(S/s,M/m,L/l): \n small - 256x256 \n middle - 512x512 \n large - 1024x1024')
55
+ @click.option('-num', count=True, help=' Enter the number to generate the specified number of images')
56
+ @click.option('-profile', help='Enable profile name')
57
+ def image(desc, size, num, profile):
58
+ number = num if num > 0 else 1
59
+ size = size_map.get(size)
60
+ size_value = size if size is not None else "512x512"
61
+ CommandChat(profile=profile).image_create(desc, size_value, number if number < 5 else 4)
62
+
63
+
64
+ commandchat_operator.add_command(configure)
65
+ commandchat_operator.add_command(chat)
66
+ commandchat_operator.add_command(image)
67
+
68
+
69
+ def main():
70
+ commandchat_operator()
File without changes
@@ -0,0 +1,99 @@
1
+ import configparser
2
+ import logging
3
+ import os
4
+
5
+ import pkg_resources
6
+
7
+ import occ.utils.logger as logger
8
+
9
+ config = configparser.SafeConfigParser()
10
+
11
+
12
+ def get_home_path():
13
+ homedir = os.environ.get('HOME', None)
14
+ if os.name == 'nt':
15
+ homedir = os.path.expanduser('~')
16
+ return homedir
17
+
18
+
19
+ def get_config_path():
20
+ homedir = get_home_path()
21
+ if not homedir:
22
+ logger.log_r("Home Directory Not found!! Set Envirnoment `HOME` ")
23
+ exit()
24
+ logger.debug("Home Directory : " + homedir)
25
+ config_file_temp = os.path.join(homedir + "/.occ/config")
26
+ logger.debug("Config File Location : " + config_file_temp)
27
+ if not os.path.exists(config_file_temp):
28
+ logger.log_r("ERROR: No Config file present")
29
+ try:
30
+ os.makedirs(os.path.dirname(config_file_temp))
31
+ except OSError as exc: # Guard against race condition
32
+ logger.log_r("Directory found! but not config file")
33
+
34
+ logger.debug("Creating config file")
35
+ file = open(config_file_temp, "w")
36
+ file.write("[default]")
37
+ file.close()
38
+
39
+ logger.debug(config.read(config_file_temp))
40
+ return config_file_temp
41
+
42
+
43
+ config_file = get_config_path()
44
+
45
+
46
+ def set_env(profile, key, value):
47
+ config.set(profile, key, value)
48
+ write_config()
49
+
50
+
51
+ def add_profile(profile):
52
+ if config.has_section(profile):
53
+ logger.log_r(profile + " Section already exists!!")
54
+ return
55
+
56
+ config.add_section(profile)
57
+ write_config()
58
+
59
+
60
+ def write_config():
61
+ with open(config_file, 'w') as configfile:
62
+ config.write(configfile)
63
+
64
+
65
+ def get_env(profile, key):
66
+ logger.debug("Searching in profile : " + profile)
67
+ logger.debug("Searching in key" + key)
68
+ if config.has_option(profile, key):
69
+ return config.get(profile, key)
70
+ logger.debug("Not found in current profile")
71
+ if config.has_option('default', key):
72
+ return config.get('default', key)
73
+
74
+ logger.debug("No Value Found in DEAFULT SECTION as well")
75
+ logger.log_r(
76
+ 'Value not found in [Default Profile] use `occ configure`comamnd')
77
+ exit()
78
+
79
+
80
+ def get_default_env(key):
81
+ if config.has_option('default', key):
82
+ return config.get('default', key)
83
+ return None
84
+
85
+
86
+ def get_profiles():
87
+ return config.sections()
88
+
89
+
90
+ def log_config():
91
+ level_input = 'DEBUG'
92
+ if level_input == 'DEBUG':
93
+ print(level_input)
94
+ logging.basicConfig(level=logging.DEBUG)
95
+
96
+
97
+ def find_version():
98
+ version = pkg_resources.require("recordset")[0].version
99
+ print(version)
File without changes
@@ -0,0 +1,36 @@
1
+ import click
2
+
3
+ import occ.commons.config as config
4
+ import occ.utils.logger as logger
5
+
6
+
7
+ def add_default_profile():
8
+ api_key = click.prompt(logger.style('\n[default] Your default api_key '),
9
+ default=config.get_default_env("api_key"), type=str)
10
+ config.set_env('default', 'api_key', api_key)
11
+
12
+ api_key = click.prompt(logger.style('\n[default] Your api_base_url(Optional) '),
13
+ default=config.get_default_env("api_base_url"), type=str)
14
+ config.set_env('default', 'api_base_url', api_key)
15
+
16
+ limit_history = click.prompt(logger.style('\n[default] Your default limit_history '),
17
+ default=config.get_default_env("limit_history"), type=str)
18
+ config.set_env('default', 'limit_history', limit_history)
19
+
20
+
21
+ def input_config_vars(profile_name, key_name, is_default_exist):
22
+ if is_default_exist:
23
+ default_value = config.get_env('default', key_name)
24
+ user_input = click.prompt(logger.style('\ndefault value ' + key_name), default=default_value, type=str)
25
+ else:
26
+ user_input = click.prompt(logger.style('\nYour ' + key_name), type=str)
27
+
28
+ config.set_env(profile_name, key_name, user_input)
29
+
30
+
31
+ def add_profile(profile_name):
32
+ config.add_profile(profile_name)
33
+ config.set_env(profile_name, 'profile_name', profile_name)
34
+ input_config_vars(profile_name, 'api_key', False)
35
+ input_config_vars(profile_name, 'api_base_url', False)
36
+ input_config_vars(profile_name, 'limit_history', False)
@@ -0,0 +1,53 @@
1
+ import os
2
+ import requests
3
+ from urllib.parse import urlparse
4
+ from PIL import Image
5
+
6
+ import time
7
+ import sys
8
+ import threading
9
+
10
+
11
+ class WaitingThread(threading.Thread):
12
+ def __init__(self):
13
+ super().__init__()
14
+ self._stop_event = threading.Event()
15
+
16
+ def run(self):
17
+ while not self._stop_event.is_set():
18
+ for i in range(4):
19
+ sys.stdout.write('\r' + ' ' * 60 + '\r') # 清空当前行
20
+ sys.stdout.write('Waiting' + '.' * i + ' ' * (3 - i))
21
+ sys.stdout.flush()
22
+ time.sleep(0.5)
23
+
24
+ def stop(self):
25
+ self._stop_event.set()
26
+
27
+
28
+ def save_and_copy_image(url, image_path):
29
+ response = requests.get(url)
30
+ image_file = os.path.join(image_path, os.path.basename(urlparse(url).path))
31
+ with open(image_file, 'wb') as f:
32
+ f.write(response.content)
33
+ print("image download path: " + image_file)
34
+ show_image(image_file)
35
+
36
+
37
+ def show_image(image):
38
+ img = Image.open(image)
39
+ img.show()
40
+
41
+
42
+ waiting_thread = WaitingThread()
43
+
44
+
45
+ def waiting_start():
46
+ waiting_thread.start()
47
+
48
+
49
+ def waiting_stop():
50
+ waiting_thread.stop()
51
+ waiting_thread.join()
52
+ sys.stdout.write('\r' + ' ' * 60 + '\r')
53
+ sys.stdout.flush()
File without changes
@@ -0,0 +1,72 @@
1
+ import click
2
+
3
+ debug_logging = False;
4
+
5
+ all_colors = 'black', 'red', 'green', 'yellow', 'blue', 'magenta', \
6
+ 'cyan', 'white', 'bright_black', 'bright_red', \
7
+ 'bright_green', 'bright_yellow', 'bright_blue', \
8
+ 'bright_magenta', 'bright_cyan', 'bright_white'
9
+
10
+
11
+ def log_c(*argv):
12
+ if len(argv) == 1:
13
+ click.echo(click.style(argv[0], fg='magenta', bold=True))
14
+ if len(argv) == 2:
15
+ click.secho(argv[0], nl=False)
16
+ click.echo(click.style(argv[1], fg='green', bold=True))
17
+
18
+
19
+ def log_r(str2):
20
+ click.echo(click.style(str2, fg='red', bold=True))
21
+
22
+
23
+ def style(str):
24
+ return click.style(str, fg='cyan', bold=True)
25
+
26
+
27
+ def log_cy(str):
28
+ click.echo(click.style(str, fg='cyan', bold=True))
29
+
30
+
31
+ def log_cyb(str):
32
+ click.echo(click.style(str, fg='cyan', bold=True, blink=True))
33
+
34
+
35
+ def log_g(str2):
36
+ click.echo(click.style(str2, fg='green', bold=True))
37
+
38
+
39
+ def log_y(str2):
40
+ click.echo(click.style(str2, fg='yellow', bold=True))
41
+
42
+
43
+ def log_bl(str2):
44
+ click.echo(click.style(str2, fg='blue', bold=True))
45
+
46
+
47
+ # Colored logging
48
+ def debug(str):
49
+ if debug_logging:
50
+ click.secho((str))
51
+
52
+
53
+ # Colored logging
54
+ def debug_c(str):
55
+ if debug_logging:
56
+ click.echo(click.style(str, fg='blue', bold=True))
57
+
58
+
59
+ # Colored logging
60
+ def enable_debug():
61
+ global debug_logging
62
+ debug_logging = True
63
+
64
+
65
+ # Simple logging
66
+ def log(str):
67
+ click.echo(click.style(str, fg='green', bold=True))
68
+
69
+
70
+ # blinking logging
71
+ def log_b(str):
72
+ click.echo(click.style(str, blink=True))
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,31 @@
1
+ import setuptools
2
+
3
+ with open("README.md", "r", encoding='utf-8') as fh:
4
+ long_description = fh.read()
5
+
6
+ setuptools.setup(
7
+ name='commandchat',
8
+ version='0.0.4',
9
+ entry_points={
10
+ 'console_scripts': [
11
+ 'occ = occ.command.__main__:main'
12
+ ]
13
+ },
14
+ author="xoto",
15
+ author_email="xxx.tao.c@gmail.com",
16
+ description="use command to chat with openai models",
17
+ long_description=long_description,
18
+ long_description_content_type="text/markdown",
19
+ url="https://github.com/",
20
+ packages=setuptools.find_packages(),
21
+ install_requires=[
22
+ 'click',
23
+ 'Image',
24
+ 'openai'
25
+ ],
26
+ classifiers=[
27
+ "Programming Language :: Python :: 3",
28
+ "License :: OSI Approved :: MIT License",
29
+ "Operating System :: OS Independent",
30
+ ],
31
+ )