Browse Source

Initial test of config for routes

pull/5/head
Zander Mackie 1 year ago
parent
commit
6264726013
  1. 1
      .env-example
  2. 12
      .gitignore
  3. 2
      infrastructure/server/fabric_api_keys.json
  4. 142
      infrastructure/server/fabric_api_server_config.py
  5. 2
      infrastructure/server/requirements.txt
  6. 4
      infrastructure/server/routes_config.yml

1
.env-example

@ -0,0 +1 @@
OPENAI_API_KEY=this-isnt-my-real-key

12
.gitignore vendored

@ -0,0 +1,12 @@
.conda/
__pycache__/
*.pyc
*.pyo
*.pyd
*.swp
.DS_Store
*.egg-info
dist/
build/
.env

2
infrastructure/server/fabric_api_keys.json

@ -1,5 +1,5 @@
{
"/extwis": {
"/extract_wis": {
"eJ4f1e0b-25wO-47f9-97ec-6b5335b2": "Daniel Miessler"
}
}

142
infrastructure/server/fabric_api_server_config.py

@ -0,0 +1,142 @@
# Imports
import openai
import json
import yaml
from flask import Flask, request, jsonify
from functools import wraps
import re
import requests
from dotenv import load_dotenv
load_dotenv()
## Define Flask app
app = Flask(__name__)
##################################################
##################################################
#
# ⚠ CAUTION: This is an HTTP-only server!
#
# If you don't know what you're doing, don't run
#
##################################################
##################################################
## Setup
## Did I mention this is HTTP only? Don't run this on the public internet.
## Set authentication on your APIs
## Let's at least have some kind of auth
# Load your OpenAI API key from a file
# with open("./openai.key", "r") as key_file:
# openai.api_key = key_file.read().strip()
## Define our own client
# client = openai.OpenAI(api_key = api_key)
# Read API tokens from the apikeys.json file
with open("./fabric_api_keys.json", "r") as tokens_file:
valid_tokens = json.load(tokens_file)
# Read route configurations from a YAML file
with open("./routes_config.yml", "r") as routes_file:
routes_config = yaml.safe_load(routes_file)
# The function to check if the token is valid
def auth_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
# Get the authentication token from request header
auth_token = request.headers.get("Authorization", "")
# Remove any bearer token prefix if present
if auth_token.lower().startswith("bearer "):
auth_token = auth_token[7:]
# Get API endpoint from request
endpoint = request.path
# Check if token is valid
user = check_auth_token(auth_token, endpoint)
if user == "Unauthorized: You are not authorized for this API":
return jsonify({"error": user}), 401
return f(*args, **kwargs)
return decorated_function
# Check for a valid token/user for the given route
def check_auth_token(token, route):
# Check if token is valid for the given route and return corresponding user
if route in valid_tokens and token in valid_tokens[route]:
return valid_tokens[route][token]
else:
return "Unauthorized: You are not authorized for this API"
# Define the allowlist of characters
ALLOWLIST_PATTERN = re.compile(r"^[a-zA-Z0-9\s.,;:!?\-]+$")
# Sanitize the content, sort of. Prompt injection is the main threat so this isn't a huge deal
def sanitize_content(content):
return "".join(char for char in content if ALLOWLIST_PATTERN.match(char))
# Pull the URL content's from the GitHub repo
def fetch_content_from_url(url):
try:
response = requests.get(url)
response.raise_for_status()
sanitized_content = sanitize_content(response.text)
return sanitized_content
except requests.RequestException as e:
return str(e)
## APIs
# Define routes based on the external YAML configuration
@app.route('/<route>', methods=["POST"])
# @auth_required # Require authentication
def handle_route(route):
if route not in routes_config['prompts']:
return jsonify({"error": "Route not found"}), 404
data = request.get_json()
# Warn if there's no input
if "input" not in data:
return jsonify({"error": "Missing input parameter"}), 400
# Get data from client
input_data = data["input"]
# Fetch the prompt content
system_url = f"https://raw.githubusercontent.com/danielmiessler/fabric/main/patterns/{route}/system.md"
user_url = f"https://raw.githubusercontent.com/danielmiessler/fabric/main/patterns/{route}/user.md"
system_content = fetch_content_from_url(system_url)
user_file_content = fetch_content_from_url(user_url)
# Build the API call
system_message = {"role": "system", "content": system_content}
user_message = {"role": "user", "content": user_file_content + "\n" + input_data}
messages = [system_message, user_message]
try:
response = openai.chat.completions.create(
model="gpt-4-1106-preview",
messages=messages,
temperature=0.0,
top_p=1,
frequency_penalty=0.1,
presence_penalty=0.1,
)
assistant_message = response.choices[0].message.content
return jsonify({"response": assistant_message})
except Exception as e:
return jsonify({"error": str(e)}), 500
# Run the application
if __name__ == "__main__":
app.run(host="localhost", port=8080, debug=True)

2
infrastructure/server/requirements.txt

@ -1,2 +1,4 @@
openai
requests
flask
python-dotenv==1.0.0

4
infrastructure/server/routes_config.yml

@ -0,0 +1,4 @@
prompts:
- extract_wisdom
- create_toc
- philocapsulate
Loading…
Cancel
Save