Skip to content
This repository has been archived by the owner on Jan 5, 2025. It is now read-only.

Commit

Permalink
Adding pydantic validation
Browse files Browse the repository at this point in the history
  • Loading branch information
codebanesr committed Dec 10, 2023
1 parent 291a8f4 commit b7f19c3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 56 deletions.
7 changes: 7 additions & 0 deletions llm-server/entities/action_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@


class ActionDTO(BaseModel):
bot_id: str
name: Optional[str] = ""
description: Optional[str] = ""
api_endpoint: Optional[str] = ""
request_type: Optional[str] = ""
operation_id: Optional[str] = "" # todo let's remove this

# todo
class Config:
# Configuring to allow arbitrary JSON keys
extra = "allow"

# Payload contains Swagger endpoint parameters and request body as JSON.
# Example structure:
# {
Expand Down
92 changes: 36 additions & 56 deletions llm-server/routes/action/action_controller.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
from flask import Blueprint, jsonify, request, abort
from pydantic import BaseModel
from werkzeug.utils import secure_filename

from typing import Any
from entities.action_entity import ActionDTO
from models.repository.action_repo import list_all_actions, action_to_dict, create_action, find_action_by_id, update_action
from models.repository.action_repo import (
list_all_actions,
action_to_dict,
create_action,
find_action_by_id,
update_action,
)
from utils.swagger_parser import SwaggerParser

action = Blueprint('action', __name__)
action = Blueprint("action", __name__)


@action.route('/bot/<string:chatbot_id>', methods=['GET'])
@action.route("/bot/<string:chatbot_id>", methods=["GET"])
def get_actions(chatbot_id):
actions = list_all_actions(chatbot_id)
return jsonify([action_to_dict(action) for action in actions])


@action.route('/bot/<string:chatbot_id>/import-from-swagger', methods=['PUT'])
@action.route("/bot/<string:chatbot_id>/import-from-swagger", methods=["PUT"])
def import_actions_from_swagger_file(chatbot_id):
# Check if the request has the file part
if 'file' not in request.files:
return jsonify({'error': 'No file part in the request'}), 400
if "file" not in request.files:
return jsonify({"error": "No file part in the request"}), 400

file = request.files['file']
file = request.files["file"]

# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
return jsonify({'error': 'No file part in the request'}), 400
if file.filename == "":
return jsonify({"error": "No file part in the request"}), 400

if file:
filename = secure_filename(file.filename)
Expand All @@ -36,54 +43,27 @@ def import_actions_from_swagger_file(chatbot_id):
swagger_parser = SwaggerParser(swagger_content)
actions = swagger_parser.get_all_actions()
except Exception as e:
return jsonify({'error': f'Failed to parse Swagger file: {str(e)}'}), 400
return jsonify({"error": f"Failed to parse Swagger file: {str(e)}"}), 400

# Store actions in the database
for action_data in actions:
try:
create_action(chatbot_id, action_data)
# todo sync with the vector db
except Exception as e:
return jsonify({'error': f'Failed to store action: {str(e)}'}), 500
return jsonify({"error": f"Failed to store action: {str(e)}"}), 500

return jsonify({'message': f'Successfully imported actions from {filename}'}), 201
return (
jsonify({"message": f"Successfully imported actions from {filename}"}),
201,
)

return jsonify({'error': 'Invalid swagger file'}), 400
return jsonify({"error": "Invalid swagger file"}), 400


@action.route('/bot/<string:chatbot_id>', methods=['POST'])
@action.route("/bot/<string:chatbot_id>", methods=["POST"])
def add_action(chatbot_id):
# Ensure request JSON is available
if not request.json:
abort(400, description="No JSON data provided")

# Extract data from the request
request_data = request.get_json()

# Extract individual fields from request_data
name = request_data.get('name', '')
description = request_data.get('description', '')
api_endpoint = request_data.get('api_endpoint', '')
request_type = request_data.get('request_type', '')
operation_id = request_data.get('operation_id', '')
payload = request_data.get('payload', {})

# todo add better validation

try:
# Create ActionDTO explicitly with each field
action_dto = ActionDTO(
name=name,
description=description,
api_endpoint=api_endpoint,
request_type=request_type,
operation_id=operation_id,
payload=payload,
)
except Exception as e:
# Handle validation errors
return jsonify({"error": str(e)}), 201

action_dto = ActionDTO(bot_id=chatbot_id, **request.get_json())
# Save the action using the repository
saved_action = create_action(chatbot_id, action_dto)

Expand All @@ -94,12 +74,12 @@ def add_action(chatbot_id):
return jsonify(action_to_dict(saved_action)), 201


@action.route('/<string:action_id>', methods=['PUT'])
@action.route("/<string:action_id>", methods=["PUT"])
def update_action_api(action_id):
# Find the existing action
existing_action = find_action_by_id(action_id)
if existing_action is None:
return jsonify({'error': 'Action not found'}), 404
return jsonify({"error": "Action not found"}), 404

# Ensure request JSON is available
if not request.json:
Expand All @@ -109,12 +89,12 @@ def update_action_api(action_id):
request_data = request.get_json()

# Extract individual fields from request_data, using existing values as defaults
name = request_data.get('name', existing_action.name)
description = request_data.get('description', existing_action.description)
base_uri = request_data.get('base_uri', existing_action.base_uri)
request_type = request_data.get('request_type', existing_action.request_type)
operation_id = request_data.get('operation_id', existing_action.operation_id)
payload = request_data.get('payload', existing_action.payload)
name = request_data.get("name", existing_action.name)
description = request_data.get("description", existing_action.description)
base_uri = request_data.get("base_uri", existing_action.base_uri)
request_type = request_data.get("request_type", existing_action.request_type)
operation_id = request_data.get("operation_id", existing_action.operation_id)
payload = request_data.get("payload", existing_action.payload)

try:
# Update ActionDTO explicitly with each field
Expand All @@ -139,9 +119,9 @@ def update_action_api(action_id):
return jsonify(action_to_dict(updated_action)), 200


@action.route('/<string:action_id>', methods=['GET'])
@action.route("/<string:action_id>", methods=["GET"])
def get_action(action_id):
action = find_action_by_id(action_id)
if action is None:
return jsonify({'error': 'Action not found'}), 404
return jsonify({"error": "Action not found"}), 404
return jsonify(action_to_dict(action))

0 comments on commit b7f19c3

Please sign in to comment.