├── .example.env ├── README.md ├── app.py ├── requirements.txt ├── static ├── dog.png ├── learning.png └── main.css └── templates └── index.html /.example.env: -------------------------------------------------------------------------------- 1 | HUMANLOOP_API_KEY=YourKeyHere 2 | OPENAI_API_KEY=YourKeyHere 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Humanloop API Quickstart - Python example app 2 | 3 | This is an example app that shows you how to use the Humanloop API in a GPT-3 app. It uses the [Flask](https://flask.palletsprojects.com/en/2.2.x/) web framework and [Humanloop](https://humanloop.com) for data logging and model improvement. Check out the tutorial or follow the instructions below to get set up. 4 | 5 | ## Setup 6 | 7 | 1. If you don’t have Python installed, [install it from here](https://www.python.org/downloads/) 8 | 9 | 2. Clone this repository 10 | 11 | 3. Navigate into the project directory 12 | 13 | ```bash 14 | $ cd humanloop-tutorial-python 15 | ``` 16 | 17 | 4. Create a new virtual environment 18 | 19 | ```bash 20 | $ python -m venv venv 21 | $ . venv/bin/activate 22 | ``` 23 | 24 | 5. Install the requirements 25 | 26 | ```bash 27 | $ pip install -r requirements.txt 28 | ``` 29 | 30 | 6. Make a copy of the example environment variables file 31 | 32 | ```bash 33 | $ cp .env.example .env 34 | ``` 35 | 36 | 7. Add your [OpenAI API key](https://beta.openai.com/account/api-keys) and [Humanloop API key](https://app.humanloop.com/llama/settings) to the newly created `.env` file 37 | 38 | 8. Run the app 39 | 40 | ```bash 41 | $ flask --debug run 42 | ``` 43 | 44 | You should now be able to access the app at [http://localhost:5000](http://localhost:5000)! For the full context behind this example app, check out the [tutorial](https://beta.openai.com/docs/quickstart). 45 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from humanloop import Humanloop 4 | from flask import Flask, redirect, render_template, request, url_for 5 | 6 | app = Flask(__name__) 7 | 8 | HUMANLOOP_API_KEY = os.getenv("HUMANLOOP_API_KEY") 9 | OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") 10 | 11 | humanloop = Humanloop( 12 | api_key=HUMANLOOP_API_KEY, 13 | ) 14 | 15 | 16 | @app.route("/", methods=["GET"]) 17 | def index(): 18 | return render_template( 19 | "index.html", 20 | result=request.args.get("result"), 21 | data_id=request.args.get("data_id"), 22 | feedback=request.args.get("feedback"), 23 | copied=request.args.get("copied", False), 24 | ) 25 | 26 | 27 | @app.route("/get-question", methods=["POST"]) 28 | def get_question(): 29 | # Make the request to GPT-3 30 | expert = request.form["Expert"] 31 | topic = request.form["Topic"] 32 | 33 | # hl.complete automatically logs the data to your project. 34 | complete_response = humanloop.complete_deployed( 35 | project="learn-anything", 36 | inputs={"expert": expert, "topic": topic}, 37 | provider_api_keys={"openai": OPENAI_API_KEY}, 38 | ) 39 | data_id = complete_response.body["data"][0]["id"] 40 | result = complete_response.body["data"][0]["output"] 41 | 42 | print("data_id from completion: ", data_id) 43 | return redirect(url_for("index", result=result, data_id=data_id)) 44 | 45 | 46 | @app.route("/actions/thumbs-up", methods=["POST"]) 47 | def thumbs_up(): 48 | data_id = request.args.get("data_id") 49 | 50 | # Send rating feedback to Humanloop 51 | humanloop.feedback(type="rating", value="good", data_id=data_id) 52 | print(f"Recorded 👍 feedback to datapoint: {data_id}") 53 | 54 | return redirect( 55 | url_for( 56 | "index", 57 | result=request.args.get("result"), 58 | data_id=data_id, 59 | feedback="👍", 60 | copied=request.args.get("copied", False), 61 | ) 62 | ) 63 | 64 | 65 | @app.route("/actions/thumbs-down", methods=["POST"]) 66 | def thumbs_down(): 67 | data_id = request.args.get("data_id") 68 | 69 | # Send rating feedback to Humanloop 70 | humanloop.feedback(type="rating", value="bad", data_id=data_id) 71 | print(f"Recorded 👎 feedback to datapoint: {data_id}") 72 | 73 | return redirect( 74 | url_for( 75 | "index", 76 | result=request.args.get("result"), 77 | data_id=data_id, 78 | feedback="👎", 79 | copied=request.args.get("copied", False), 80 | ) 81 | ) 82 | 83 | 84 | @app.route("/actions/copy", methods=["POST"]) 85 | def feedback(): 86 | data_id = request.args.get("data_id") 87 | 88 | # Send implicit feedback to Humanloop 89 | humanloop.feedback(type="action", value="copy", data_id=data_id) 90 | print(f"Recorded implicit feedback that user copied to datapoint: {data_id}") 91 | 92 | return redirect( 93 | url_for( 94 | "index", 95 | result=request.args.get("result"), 96 | data_id=data_id, 97 | feedback=request.args.get("feedback"), 98 | copied=True, 99 | ) 100 | ) 101 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==2.3.3 2 | humanloop==0.5.6 3 | openai==0.27.8 4 | python-dotenv==1.0.0 5 | -------------------------------------------------------------------------------- /static/dog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/humanloop/humanloop-tutorial-python/bdf678d2af5bcf7112238c4b24a6b019c181f45c/static/dog.png -------------------------------------------------------------------------------- /static/learning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/humanloop/humanloop-tutorial-python/bdf678d2af5bcf7112238c4b24a6b019c181f45c/static/learning.png -------------------------------------------------------------------------------- /static/main.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "ColfaxAI"; 3 | src: url(https://cdn.openai.com/API/fonts/ColfaxAIRegular.woff2) 4 | format("woff2"), 5 | url(https://cdn.openai.com/API/fonts/ColfaxAIRegular.woff) format("woff"); 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | @font-face { 10 | font-family: "ColfaxAI"; 11 | src: url(https://cdn.openai.com/API/fonts/ColfaxAIBold.woff2) format("woff2"), 12 | url(https://cdn.openai.com/API/fonts/ColfaxAIBold.woff) format("woff"); 13 | font-weight: bold; 14 | font-style: normal; 15 | } 16 | body, 17 | input { 18 | font-size: 16px; 19 | line-height: 24px; 20 | color: #353740; 21 | font-family: "ColfaxAI", Helvetica, sans-serif; 22 | } 23 | body { 24 | display: flex; 25 | flex-direction: column; 26 | align-items: center; 27 | padding-top: 60px; 28 | } 29 | .icon { 30 | width: 34px; 31 | } 32 | h3 { 33 | font-size: 32px; 34 | line-height: 40px; 35 | font-weight: bold; 36 | color: #202123; 37 | margin: 16px 0 40px; 38 | } 39 | 40 | .input-form { 41 | display: flex; 42 | flex-direction: column; 43 | width: 320px; 44 | } 45 | 46 | input[type="text"] { 47 | padding: 12px 16px; 48 | border: 1px solid #10a37f; 49 | border-radius: 4px; 50 | margin-bottom: 24px; 51 | } 52 | ::placeholder { 53 | color: #8e8ea0; 54 | opacity: 1; 55 | } 56 | input[type="submit"] { 57 | padding: 12px 0; 58 | color: #fff; 59 | background-color: #10a37f; 60 | border: none; 61 | border-radius: 4px; 62 | text-align: center; 63 | cursor: pointer; 64 | } 65 | .result { 66 | font-weight: bold; 67 | } 68 | 69 | .feedback { 70 | margin-top: 24px; 71 | display: flex; 72 | gap: 12px; 73 | } 74 | 75 | button { 76 | width: 80px; 77 | padding: 12px 16px; 78 | border: 1px solid #10a37f; 79 | border-radius: 4px; 80 | margin-bottom: 24px; 81 | padding: 12px 0; 82 | color: #fff; 83 | border: none; 84 | border-radius: 4px; 85 | text-align: center; 86 | cursor: pointer; 87 | } 88 | 89 | .result-wrapper { 90 | display: flex; 91 | align-items: center; 92 | gap: 24px; 93 | margin-top: 40px; 94 | } 95 | 96 | .copy { 97 | width: 36px; 98 | height: 36px; 99 | padding: 0; 100 | margin-bottom: 0; 101 | } 102 | 103 | .submitted { 104 | background-color: #10a37f; 105 | } 106 | 107 | .hover:hover { 108 | filter: brightness(0.9) contrast(1.2); 109 | } 110 | 111 | a { 112 | text-decoration: none; 113 | display: flex; 114 | flex-direction: column; 115 | align-items: center; 116 | } 117 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Humanloop Quickstart 4 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 |

Learn anything from anyone

21 |
22 |
23 | 24 | 25 | 26 |
27 | {% if result %} 28 |
29 |
{{ result }}
30 |
35 | 43 |
44 |
45 |
46 |
50 | 53 |
54 |
58 | 61 |
62 |
63 | {% endif %} 64 | 65 | --------------------------------------------------------------------------------