Misc refactoring
This commit is contained in:
parent
5f2abddd89
commit
6d5e90d278
@ -12,7 +12,8 @@
|
|||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"pomdtr.secrets",
|
"pomdtr.secrets",
|
||||||
"ms-python.python"
|
"ms-python.python",
|
||||||
|
"donjayamanne.python-extension-pack"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
.vscode/launch.json
vendored
Normal file
33
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Start Server",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "src/aidgaf/aidgaf-server/server.py",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "IDGAF",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "src/aidgaf/aidgaf-server/idgaf.py",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": true
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Python: Current File",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
src/aidgaf/aidgaf-server/const.py
Normal file
1
src/aidgaf/aidgaf-server/const.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
UTF8="utf-8"
|
@ -1,23 +1,21 @@
|
|||||||
import json
|
import json
|
||||||
|
import random
|
||||||
|
import security
|
||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
||||||
from time import time
|
from time import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import openai
|
import openai
|
||||||
import random
|
|
||||||
import settings
|
import settings
|
||||||
import hash_calculator
|
|
||||||
|
|
||||||
openai.organization = "org-hNNV1yHjZp7T3pn5pdZWaKLm"
|
openai.organization = "org-hNNV1yHjZp7T3pn5pdZWaKLm"
|
||||||
# print(openai.Model.list())
|
# print(openai.Model.list())
|
||||||
|
|
||||||
|
|
||||||
URL = "https://api.openai.com/v1/completions"
|
URL = "https://api.openai.com/v1/completions"
|
||||||
|
|
||||||
DATA = {"model": settings.OPEN_AI_COMPLETION_MODEL,
|
DATA = {"model": settings.OPEN_AI_COMPLETION_MODEL,
|
||||||
"prompt": settings.PROMPTS[0],
|
"prompt": settings.PROMPTS[0],
|
||||||
"temperature": 0.90,
|
"temperature": settings.TEMPERATURE,
|
||||||
"max_tokens": settings.OPEN_AI_MAX_TOKENS
|
"max_tokens": settings.OPEN_AI_MAX_TOKENS
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,35 +23,6 @@ request_headers = {"Authorization": "Bearer " +
|
|||||||
settings.APIKEY, "Content-Type": "application/json"}
|
settings.APIKEY, "Content-Type": "application/json"}
|
||||||
|
|
||||||
|
|
||||||
class IDGAFServer(BaseHTTPRequestHandler):
|
|
||||||
|
|
||||||
def do_PATCH(self):
|
|
||||||
# print("Request: "+self.request+ " "+webServer.get_request())
|
|
||||||
request_body = self.rfile.read(int(self.headers.get('Content-Length')))
|
|
||||||
str_request=str(request_body,'utf-8')
|
|
||||||
print(request_body)
|
|
||||||
if settings.HASHKEY is not None and get_message_hash(str_request) not in str_request:
|
|
||||||
print("Error: hash not match")
|
|
||||||
self.send_response(403)
|
|
||||||
return
|
|
||||||
if settings.HASHKEY is not None and not verify_message_time(str_request):
|
|
||||||
print("Error: timestamp expired")
|
|
||||||
self.send_response(403)
|
|
||||||
return
|
|
||||||
command = json.loads(request_body)
|
|
||||||
print(command)
|
|
||||||
if command['message']['command'] == 'aidgaf':
|
|
||||||
[responseCode, response_body] = parse_idgaf_request(command)
|
|
||||||
|
|
||||||
self.handle_response(responseCode, response_body)
|
|
||||||
print("sending:"+response_body)
|
|
||||||
|
|
||||||
def handle_response(self, code, body):
|
|
||||||
self.send_response(code)
|
|
||||||
self.send_header("Content-type", "text/html")
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write(bytes(body, "UTF-8"))
|
|
||||||
|
|
||||||
|
|
||||||
def get_response_base_object(text):
|
def get_response_base_object(text):
|
||||||
resultObject = {}
|
resultObject = {}
|
||||||
@ -64,20 +33,19 @@ def get_response_base_object(text):
|
|||||||
resultObject["timestamp"] = datetime.utcnow().timestamp()
|
resultObject["timestamp"] = datetime.utcnow().timestamp()
|
||||||
return resultObject
|
return resultObject
|
||||||
|
|
||||||
|
|
||||||
def parse_idgaf_request(command):
|
def parse_idgaf_request(command):
|
||||||
the_data = get_prompt(command)
|
the_data = get_prompt(command)
|
||||||
gpt_response = requests.post(URL, json=the_data, headers=request_headers)
|
response=get_gpt_response(the_data)
|
||||||
print(gpt_response)
|
|
||||||
try:
|
try:
|
||||||
response_text = gpt_response.json()['choices'][0]['text'].strip()
|
response_text = response.json()['choices'][0]['text'].strip()
|
||||||
except (KeyError):
|
except (KeyError):
|
||||||
response_text = gpt_response.text
|
response_text = gpt_response.text
|
||||||
|
|
||||||
obj = get_response_base_object(response_text)
|
obj = get_response_base_object(response_text)
|
||||||
obj['hash']=get_message_hash(json.dumps(obj))
|
return [response.status_code, obj]
|
||||||
json_result = json.dumps(obj)
|
|
||||||
return [gpt_response.status_code, json_result]
|
def get_gpt_response(data):
|
||||||
|
gpt_response = requests.post(URL, json=data, headers=request_headers)
|
||||||
|
return gpt_response
|
||||||
|
|
||||||
|
|
||||||
def get_prompt(command):
|
def get_prompt(command):
|
||||||
@ -93,41 +61,27 @@ def get_prompt(command):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_message_hash(json_command) -> bytes:
|
|
||||||
"""Get the object named "message", and run a hash over it. """
|
|
||||||
strip1 = re.sub('.*\"message\":', "", json_command, 1)
|
|
||||||
strip2 = re.sub(',\"hash\":.*', '', strip1)
|
|
||||||
json_value = bytes(strip2, "utf-8")
|
|
||||||
if (settings.HASHKEY is not None):
|
|
||||||
hash_value = hash_calculator.calculate_hash(json_value, settings.HASHKEY)
|
|
||||||
return hash_value
|
|
||||||
return ""
|
|
||||||
|
|
||||||
|
def get_prompt(command):
|
||||||
|
my_prompt = random.choice(settings.PROMPTS)
|
||||||
|
my_prompt = my_prompt.replace(
|
||||||
|
"USERNAME", command['message']['data']['username'])
|
||||||
|
|
||||||
def verify_message_time(json_command) -> bool:
|
print("Prompt selected: "+my_prompt)
|
||||||
"""Check message expiration is less than current time + time in settings.
|
the_data = DATA
|
||||||
Before we accept the JSON as valid, and parse it, we must check the timestamp.
|
the_data["prompt"] = my_prompt
|
||||||
The timestamp is a Linux Timestamp. So convert it, add maximum message age, and
|
return the_data
|
||||||
then verify current time is less than expiration time.
|
|
||||||
"""
|
|
||||||
strip_json = re.sub('.*\"timestamp\":', "", json_command, 1)
|
|
||||||
expiration = int(re.sub('}.*', '', strip_json))+settings.MAX_MESSAGE_AGE
|
|
||||||
current_time = int(time())
|
|
||||||
return not current_time > expiration
|
|
||||||
|
|
||||||
|
|
||||||
value = '{"service":"papa","message":{"command":"aidgaf","data":{"username":"AdamOutler"},"timestamp":1675725191},"hash":"1bc73914478835d03f9ebdfb46328321d2bb656647e2876d6f162cc1860607fcfca8d825c48e390a6a254ee0835c8a4fe5f9a25795a3a0880ae5a23e9c132cf2"}'
|
value = '{"service":"papa","message":{"command":"aidgaf","data":{"username":"AdamOutler"},"timestamp":1675725191},"hash":"1bc73914478835d03f9ebdfb46328321d2bb656647e2876d6f162cc1860607fcfca8d825c48e390a6a254ee0835c8a4fe5f9a25795a3a0880ae5a23e9c132cf2"}'
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
if get_message_hash(value) not in value:
|
|
||||||
print("Error: hash not match")
|
|
||||||
if not verify_message_time(value):
|
|
||||||
print("Error: timestamp expired")
|
|
||||||
command = json.loads(value)
|
command = json.loads(value)
|
||||||
[code, result] = parse_idgaf_request(command)
|
[code, result] = parse_idgaf_request(command)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# curl https://api.openai.com/v1/completions \
|
# curl https://api.openai.com/v1/completions \
|
||||||
# -H "Content-Type: application/json" \
|
# -H "Content-Type: application/json" \
|
||||||
# -H "Authorization: Bearer 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" \
|
# -H "Authorization: Bearer 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" \
|
||||||
|
45
src/aidgaf/aidgaf-server/security.py
Normal file
45
src/aidgaf/aidgaf-server/security.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import re
|
||||||
|
import time
|
||||||
|
import hash_calculator
|
||||||
|
|
||||||
|
import settings
|
||||||
|
from const import UTF8
|
||||||
|
|
||||||
|
|
||||||
|
def perform_hash_checks(str_request):
|
||||||
|
hash = get_message_hash(str_request)
|
||||||
|
|
||||||
|
if hash not in str_request:
|
||||||
|
print("Error: hash not match")
|
||||||
|
return False
|
||||||
|
if not verify_message_time(str_request):
|
||||||
|
print("Error: timestamp expired")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_message_hash(json_command) -> str:
|
||||||
|
"""Get the object named "message", and run a hash over it. """
|
||||||
|
strip1 = re.sub(".*\"message\":", "", json_command, 1)
|
||||||
|
if ("\"hash\":" in strip1):
|
||||||
|
strip2 = re.sub(',\"hash\":.*', '', strip1)
|
||||||
|
else:
|
||||||
|
strip2 = strip1[:-1]
|
||||||
|
json_value = bytes(strip2, UTF8)
|
||||||
|
if (settings.HASHKEY is not None):
|
||||||
|
hash_value = hash_calculator.calculate_hash(
|
||||||
|
json_value, settings.HASHKEY)
|
||||||
|
return hash_value
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def verify_message_time(json_command) -> bool:
|
||||||
|
"""Check message expiration is less than current time + time in settings.
|
||||||
|
Before we accept the JSON as valid, and parse it, we must check the timestamp.
|
||||||
|
The timestamp is a Linux Timestamp. So convert it, add maximum message age, and
|
||||||
|
then verify current time is less than expiration time.
|
||||||
|
"""
|
||||||
|
strip_json = re.sub('.*\"timestamp\":', "", json_command, 1)
|
||||||
|
expiration = int(re.sub('}.*', '', strip_json))+settings.MAX_MESSAGE_AGE
|
||||||
|
current_time = int(time.time())
|
||||||
|
return not current_time > expiration
|
@ -1,12 +1,77 @@
|
|||||||
|
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
|
||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
import idgaf
|
import idgaf
|
||||||
from idgaf import IDGAFServer
|
|
||||||
from http.server import HTTPServer
|
|
||||||
import settings
|
import settings
|
||||||
|
import security
|
||||||
|
from const import UTF8
|
||||||
|
|
||||||
|
default_request_body = b'{"message":{"command":"aidgaf","data":{"username":"AdamOutler"}}}'
|
||||||
|
|
||||||
|
|
||||||
|
class IDGAFServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self.send_response(418)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(bytes("", UTF8))
|
||||||
|
|
||||||
|
def do_PATCH(self):
|
||||||
|
body = self.get_body().decode(UTF8)
|
||||||
|
if not perform_sanity_checks(body):
|
||||||
|
self.send_response(403)
|
||||||
|
return
|
||||||
|
command = json.loads(body)
|
||||||
|
self.do_request_handling(command)
|
||||||
|
|
||||||
|
def do_request_handling(self, command):
|
||||||
|
print(command)
|
||||||
|
if command['message']['command'] == 'aidgaf':
|
||||||
|
[responseCode, json_response] = idgaf.parse_idgaf_request(command)
|
||||||
|
json_response['hash'] = security.get_message_hash(json.dumps(response_body))
|
||||||
|
response_body = json.dumps(json_response)
|
||||||
|
self.handle_response(responseCode, response_body)
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
header_length = self.headers.get('Content-Length')
|
||||||
|
request_body = default_request_body
|
||||||
|
if header_length != None and self.headers.get('Content-Length') != None:
|
||||||
|
request_body = self.rfile.read(
|
||||||
|
int(self.headers.get('Content-Length')))
|
||||||
|
str_request = str(request_body, UTF8)
|
||||||
|
print(request_body)
|
||||||
|
return request_body
|
||||||
|
|
||||||
|
|
||||||
|
def handle_response(self, code, body):
|
||||||
|
self.send_response(code)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
print("sending:"+response_body)
|
||||||
|
self.wfile.write(bytes(body, UTF8))
|
||||||
|
|
||||||
|
def perform_sanity_checks(str_request):
|
||||||
|
if settings.HASHKEY is not None:
|
||||||
|
hash = security.get_message_hash(str_request)
|
||||||
|
if hash not in str_request:
|
||||||
|
print("Error: hash not match")
|
||||||
|
return False
|
||||||
|
if not security.verify_message_time(str_request):
|
||||||
|
print("Error: timestamp expired")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
webServer = HTTPServer((settings.HOSTNAME, settings.SERVERPORT), idgaf.IDGAFServer)
|
webServer = HTTPServer(
|
||||||
print("Server started http://%s:%s" % (settings.HOSTNAME, settings.SERVERPORT))
|
(settings.HOSTNAME, settings.SERVERPORT), IDGAFServer)
|
||||||
|
print("Server started http://%s:%s" %
|
||||||
|
(settings.HOSTNAME, settings.SERVERPORT))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
webServer.serve_forever()
|
webServer.serve_forever()
|
||||||
@ -16,5 +81,6 @@ def main():
|
|||||||
webServer.server_close()
|
webServer.server_close()
|
||||||
print("Server stopped.")
|
print("Server stopped.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from const import UTF8
|
||||||
# The hostname used by this app
|
# The hostname used by this app
|
||||||
HOSTNAME: str = os.getenv('HOSTNAME') # localhost or some name
|
HOSTNAME: str = os.getenv('HOSTNAME') # localhost or some name
|
||||||
# The port to broadcast the server
|
# The port to broadcast the server
|
||||||
@ -9,14 +10,16 @@ APIKEY: str = os.getenv('APIKEY') # secret key from OpenAPI website
|
|||||||
if APIKEY is None:
|
if APIKEY is None:
|
||||||
raise Exception("APIKEY Environmental Variable must be set")
|
raise Exception("APIKEY Environmental Variable must be set")
|
||||||
# The hash key
|
# The hash key
|
||||||
HASHKEY: str = None
|
HASHKEY = bytes(os.getenv('HASHKEY'),UTF8) # shared secret for hmac of message
|
||||||
hashKey = os.getenv('HASHKEY') # shared secret for hmac of message
|
|
||||||
if (hashKey is not None and hashKey.replace(" ", "") != ""):
|
|
||||||
HASKHEY = bytes(hashKey, "utf-8")
|
|
||||||
# The prompts used for OpenAI.
|
# The prompts used for OpenAI.
|
||||||
PROMPTS = ["Say \"USERNAME does not give a fuck\" in a thoughtful and clever paragraph of 5 sentences.",
|
PROMPTS = [
|
||||||
"Say \"USERNAME does not give a fuck\" in a Dr Suess poem.",
|
# "Say \"USERNAME does not give a fuck\" as a haiku and mention that it is a haiku.",
|
||||||
"Tell me all about how much \"USERNAME does not give a fuck\" using your most colorful words."]
|
# "Say \"USERNAME does not give a fuck\" in a Dr Suess poem.",
|
||||||
|
# "Tell me a story about how \"USERNAME does not give a fuck\" using an outrageous situation where someone should care but they do not and thats fine.",
|
||||||
|
"Say \"USERNAME is completely apethetic and does not give a fuck\" in a verbose manner, using your most colorful words and one metaphor."
|
||||||
|
]
|
||||||
OPEN_AI_MAX_TOKENS = 500
|
OPEN_AI_MAX_TOKENS = 500
|
||||||
OPEN_AI_COMPLETION_MODEL = "text-davinci-003"
|
OPEN_AI_COMPLETION_MODEL = "text-davinci-003"
|
||||||
MAX_MESSAGE_AGE = 600
|
MAX_MESSAGE_AGE = 600
|
||||||
|
TEMPERATURE = 0.8
|
||||||
|
Loading…
x
Reference in New Issue
Block a user