refactor: api access bug for duplicate payload values. (#8377)
* feat: add formatPayloadTweaks utility and integrate into API code generation * feat: integrate formatPayloadTweaks utility for centralized payload processing in API code generation * refactor: clean up formatPayloadTweaks import and improve curl command formatting * refactor: remove commented code and streamline payload processing in APITabsComponent * fix: uncomment TextInput in INPUT_TYPES constant * fix: uncomment TextInput in INPUT_TYPES and update filter-tweaks to include it
This commit is contained in:
parent
a412fce939
commit
0acfd8e5e9
5 changed files with 88 additions and 102 deletions
|
|
@ -14,6 +14,7 @@ import {
|
||||||
} from "react-syntax-highlighter/dist/cjs/styles/prism";
|
} from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||||
import { useShallow } from "zustand/react/shallow";
|
import { useShallow } from "zustand/react/shallow";
|
||||||
import { useDarkStore } from "../../../stores/darkStore";
|
import { useDarkStore } from "../../../stores/darkStore";
|
||||||
|
import { formatPayloadTweaks } from "../utils/filter-tweaks";
|
||||||
import { getNewCurlCode } from "../utils/get-curl-code";
|
import { getNewCurlCode } from "../utils/get-curl-code";
|
||||||
import { getNewJsApiCode } from "../utils/get-js-api-code";
|
import { getNewJsApiCode } from "../utils/get-js-api-code";
|
||||||
import { getNewPythonApiCode } from "../utils/get-python-api-code";
|
import { getNewPythonApiCode } from "../utils/get-python-api-code";
|
||||||
|
|
@ -41,18 +42,30 @@ export default function APITabsComponent() {
|
||||||
}
|
}
|
||||||
const streaming = hasStreaming(nodes);
|
const streaming = hasStreaming(nodes);
|
||||||
const tweaks = useTweaksStore((state) => state.tweaks);
|
const tweaks = useTweaksStore((state) => state.tweaks);
|
||||||
|
const activeTweaks = Object.values(tweaks).some(
|
||||||
|
(tweak) => Object.keys(tweak).length > 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
const includeTopLevelInputValue = formatPayloadTweaks(tweaks);
|
||||||
|
const processedPayload: any = {
|
||||||
|
output_type: hasChatOutput ? "chat" : "text",
|
||||||
|
input_type: hasChatInput ? "chat" : "text",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (includeTopLevelInputValue) {
|
||||||
|
processedPayload.input_value = input_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTweaks && tweaks && Object.keys(tweaks).length > 0) {
|
||||||
|
processedPayload.tweaks = tweaks;
|
||||||
|
}
|
||||||
|
|
||||||
const codeOptions = {
|
const codeOptions = {
|
||||||
endpointName: endpointName || "",
|
endpointName: endpointName || "",
|
||||||
streaming: streaming,
|
streaming: streaming,
|
||||||
flowId: flowId || "",
|
flowId: flowId || "",
|
||||||
isAuthenticated: !autologin || false,
|
isAuthenticated: !autologin || false,
|
||||||
input_value: input_value,
|
processedPayload: processedPayload,
|
||||||
input_type: hasChatInput ? "chat" : "text",
|
|
||||||
output_type: hasChatOutput ? "chat" : "text",
|
|
||||||
tweaksObject: tweaks,
|
|
||||||
activeTweaks: Object.values(tweaks).some(
|
|
||||||
(tweak) => Object.keys(tweak).length > 0,
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
const tabsList: tabsArrayType = [
|
const tabsList: tabsArrayType = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
24
src/frontend/src/modals/apiModal/utils/filter-tweaks.ts
Normal file
24
src/frontend/src/modals/apiModal/utils/filter-tweaks.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { INPUT_TYPES } from "@/constants/constants";
|
||||||
|
|
||||||
|
export function formatPayloadTweaks(tweaksObject: any): boolean {
|
||||||
|
if (!tweaksObject || typeof tweaksObject !== "object") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputTypes = [...Array.from(INPUT_TYPES), "TextInput"];
|
||||||
|
|
||||||
|
const hasInputValueInTweaks = Object.keys(tweaksObject).some((key) => {
|
||||||
|
const isInputNode = Array.from(InputTypes).some((inputType) =>
|
||||||
|
key.startsWith(inputType),
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
isInputNode &&
|
||||||
|
tweaksObject[key] &&
|
||||||
|
typeof tweaksObject[key] === "object" &&
|
||||||
|
"input_value" in tweaksObject[key]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return !hasInputValueInTweaks;
|
||||||
|
}
|
||||||
|
|
@ -11,8 +11,6 @@ import { GetCodeType } from "@/types/tweaks";
|
||||||
* @param {string} options.endpointName - The name of the webhook endpoint.
|
* @param {string} options.endpointName - The name of the webhook endpoint.
|
||||||
* @returns {string} The cURL command.
|
* @returns {string} The cURL command.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// KEEP THIS FOR LFOSS
|
|
||||||
export function getCurlWebhookCode({
|
export function getCurlWebhookCode({
|
||||||
flowId,
|
flowId,
|
||||||
isAuth,
|
isAuth,
|
||||||
|
|
@ -43,53 +41,39 @@ export function getCurlWebhookCode({
|
||||||
export function getNewCurlCode({
|
export function getNewCurlCode({
|
||||||
flowId,
|
flowId,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
input_value,
|
|
||||||
input_type,
|
|
||||||
output_type,
|
|
||||||
tweaksObject,
|
|
||||||
activeTweaks,
|
|
||||||
endpointName,
|
endpointName,
|
||||||
|
processedPayload,
|
||||||
}: {
|
}: {
|
||||||
flowId: string;
|
flowId: string;
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
input_value: string;
|
|
||||||
input_type: string;
|
|
||||||
output_type: string;
|
|
||||||
tweaksObject: any;
|
|
||||||
activeTweaks: boolean;
|
|
||||||
endpointName: string;
|
endpointName: string;
|
||||||
|
processedPayload: any;
|
||||||
}): string {
|
}): string {
|
||||||
const { protocol, host } = customGetHostProtocol();
|
const { protocol, host } = customGetHostProtocol();
|
||||||
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
||||||
|
|
||||||
const tweaksString =
|
const formattedJsonPayload = JSON.stringify(processedPayload, null, 2)
|
||||||
tweaksObject && activeTweaks ? JSON.stringify(tweaksObject, null, 2) : "{}";
|
.split("\n")
|
||||||
|
.map((line, index) => (index === 0 ? line : " " + line))
|
||||||
// Construct the payload
|
.join("\n\t\t");
|
||||||
const payload = {
|
|
||||||
input_value: input_value,
|
|
||||||
output_type: output_type,
|
|
||||||
input_type: input_type,
|
|
||||||
...(activeTweaks && tweaksObject
|
|
||||||
? { tweaks: JSON.parse(tweaksString) }
|
|
||||||
: {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
return `${
|
return `${
|
||||||
isAuthenticated
|
isAuthenticated
|
||||||
? `# Get API key from environment variable
|
? `# Get API key from environment variable
|
||||||
if [ -z "$LANGFLOW_API_KEY" ]; then
|
if [ -z "$LANGFLOW_API_KEY" ]; then
|
||||||
echo "Error: LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables."
|
echo "Error: LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables."
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
`
|
`
|
||||||
: ""
|
: ""
|
||||||
}curl --request POST \\
|
}curl --request POST \\
|
||||||
--url '${apiUrl}?stream=false' \\
|
--url '${apiUrl}?stream=false' \\
|
||||||
--header 'Content-Type: application/json' \\${
|
--header 'Content-Type: application/json' \\${
|
||||||
isAuthenticated
|
isAuthenticated
|
||||||
? `
|
? `
|
||||||
--header "x-api-key: $LANGFLOW_API_KEY" \\`
|
--header "x-api-key: $LANGFLOW_API_KEY" \\`
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
--data '${JSON.stringify(payload, null, 2)}'`;
|
--data '${formattedJsonPayload}'`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,37 +6,31 @@ import { customGetHostProtocol } from "@/customization/utils/custom-get-host-pro
|
||||||
* @param {Object} params - The parameters for generating the API code
|
* @param {Object} params - The parameters for generating the API code
|
||||||
* @param {string} params.flowId - The ID of the flow to run
|
* @param {string} params.flowId - The ID of the flow to run
|
||||||
* @param {boolean} params.isAuthenticated - Whether authentication is required
|
* @param {boolean} params.isAuthenticated - Whether authentication is required
|
||||||
* @param {string} params.input_value - The input value to send to the flow
|
* @param {string} params.endpointName - The endpoint name for the flow
|
||||||
* @param {string} params.input_type - The type of input (e.g. "text", "chat")
|
* @param {Object} params.processedPayload - The pre-processed payload object
|
||||||
* @param {string} params.output_type - The type of output (e.g. "text", "chat")
|
|
||||||
* @param {Object} params.tweaksObject - Optional tweaks to customize flow behavior
|
|
||||||
* @param {boolean} params.activeTweaks - Whether tweaks should be included
|
|
||||||
* @returns {string} Generated JavaScript code as a string
|
* @returns {string} Generated JavaScript code as a string
|
||||||
*/
|
*/
|
||||||
export function getNewJsApiCode({
|
export function getNewJsApiCode({
|
||||||
flowId,
|
flowId,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
input_value,
|
|
||||||
input_type,
|
|
||||||
output_type,
|
|
||||||
tweaksObject,
|
|
||||||
activeTweaks,
|
|
||||||
endpointName,
|
endpointName,
|
||||||
|
processedPayload,
|
||||||
}: {
|
}: {
|
||||||
flowId: string;
|
flowId: string;
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
input_value: string;
|
|
||||||
input_type: string;
|
|
||||||
output_type: string;
|
|
||||||
tweaksObject: any;
|
|
||||||
activeTweaks: boolean;
|
|
||||||
endpointName: string;
|
endpointName: string;
|
||||||
|
processedPayload: any;
|
||||||
}): string {
|
}): string {
|
||||||
const { protocol, host } = customGetHostProtocol();
|
const { protocol, host } = customGetHostProtocol();
|
||||||
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
||||||
|
|
||||||
const tweaksString =
|
// Add session_id to payload
|
||||||
tweaksObject && activeTweaks ? JSON.stringify(tweaksObject, null, 2) : "{}";
|
const payloadWithSession = {
|
||||||
|
...processedPayload,
|
||||||
|
session_id: "user_1", // Optional: Use session tracking if needed
|
||||||
|
};
|
||||||
|
|
||||||
|
const payloadString = JSON.stringify(payloadWithSession, null, 4);
|
||||||
|
|
||||||
return `${
|
return `${
|
||||||
isAuthenticated
|
isAuthenticated
|
||||||
|
|
@ -44,20 +38,10 @@ export function getNewJsApiCode({
|
||||||
if (!process.env.LANGFLOW_API_KEY) {
|
if (!process.env.LANGFLOW_API_KEY) {
|
||||||
throw new Error('LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables.');
|
throw new Error('LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables.');
|
||||||
}
|
}
|
||||||
|
|
||||||
`
|
`
|
||||||
: ""
|
: ""
|
||||||
}const payload = {
|
}const payload = ${payloadString};
|
||||||
"input_value": "${input_value}",
|
|
||||||
"output_type": "${output_type}",
|
|
||||||
"input_type": "${input_type}",
|
|
||||||
// Optional: Use session tracking if needed
|
|
||||||
"session_id": "user_1"${
|
|
||||||
activeTweaks && tweaksObject
|
|
||||||
? `,
|
|
||||||
"tweaks": ${tweaksString}`
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -70,6 +54,5 @@ const options = {
|
||||||
fetch('${apiUrl}', options)
|
fetch('${apiUrl}', options)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(response => console.log(response))
|
.then(response => console.log(response))
|
||||||
.catch(err => console.error(err));
|
.catch(err => console.error(err));`;
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,56 +3,39 @@ import { customGetHostProtocol } from "@/customization/utils/custom-get-host-pro
|
||||||
export function getNewPythonApiCode({
|
export function getNewPythonApiCode({
|
||||||
flowId,
|
flowId,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
input_value,
|
|
||||||
input_type,
|
|
||||||
output_type,
|
|
||||||
tweaksObject,
|
|
||||||
activeTweaks,
|
|
||||||
endpointName,
|
endpointName,
|
||||||
|
processedPayload,
|
||||||
}: {
|
}: {
|
||||||
flowId: string;
|
flowId: string;
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
input_value: string;
|
|
||||||
input_type: string;
|
|
||||||
output_type: string;
|
|
||||||
tweaksObject: any;
|
|
||||||
activeTweaks: boolean;
|
|
||||||
endpointName: string;
|
endpointName: string;
|
||||||
|
processedPayload: any;
|
||||||
}): string {
|
}): string {
|
||||||
const { protocol, host } = customGetHostProtocol();
|
const { protocol, host } = customGetHostProtocol();
|
||||||
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
const apiUrl = `${protocol}//${host}/api/v1/run/${endpointName || flowId}`;
|
||||||
|
|
||||||
const tweaksString =
|
const payloadString = JSON.stringify(processedPayload, null, 4)
|
||||||
tweaksObject && activeTweaks
|
.replace(/true/g, "True")
|
||||||
? JSON.stringify(tweaksObject, null, 4)
|
.replace(/false/g, "False")
|
||||||
.replace(/true/g, "True")
|
.replace(/null/g, "None");
|
||||||
.replace(/false/g, "False")
|
|
||||||
.replace(/null/g, "None")
|
|
||||||
: "{}";
|
|
||||||
|
|
||||||
return `import requests
|
return `import requests
|
||||||
${
|
${
|
||||||
isAuthenticated
|
isAuthenticated
|
||||||
? `import os
|
? `import os
|
||||||
|
|
||||||
# API Configuration
|
# API Configuration
|
||||||
try:
|
try:
|
||||||
api_key = os.environ["LANGFLOW_API_KEY"]
|
api_key = os.environ["LANGFLOW_API_KEY"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError("LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables.")\n`
|
raise ValueError("LANGFLOW_API_KEY environment variable not found. Please set your API key in the environment variables.")
|
||||||
|
`
|
||||||
: ""
|
: ""
|
||||||
}url = "${apiUrl}" # The complete API endpoint URL for this flow
|
}
|
||||||
|
url = "${apiUrl}" # The complete API endpoint URL for this flow
|
||||||
|
|
||||||
# Request payload configuration
|
# Request payload configuration
|
||||||
payload = {
|
payload = ${payloadString}
|
||||||
"input_value": "${input_value}", # The input value to be processed by the flow
|
|
||||||
"output_type": "${output_type}", # Specifies the expected output format
|
|
||||||
"input_type": "${input_type}" # Specifies the input format${
|
|
||||||
activeTweaks && tweaksObject
|
|
||||||
? `,
|
|
||||||
"tweaks": ${tweaksString} # Custom tweaks to modify flow behavior`
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Request headers
|
# Request headers
|
||||||
headers = {
|
headers = {
|
||||||
|
|
@ -70,6 +53,5 @@ try:
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
print(f"Error making API request: {e}")
|
print(f"Error making API request: {e}")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(f"Error parsing response: {e}")
|
print(f"Error parsing response: {e}")`;
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue