diff --git a/codegen.go b/codegen.go index 69585ea..bb22db0 100755 --- a/codegen.go +++ b/codegen.go @@ -839,6 +839,265 @@ func MakePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet return functionname, data } +func NewEndPointPythonCode () string{ + pythonCode := ` + def fix_url(self, url): + if "hhttp" in url: + url = url.replace("hhttp", "http") + + if "http:/" in url and not "http://" in url: + url = url.replace("http:/", "http://", -1) + if "https:/" in url and not "https://" in url: + url = url.replace("https:/", "https://", -1) + if "http:///" in url: + url = url.replace("http:///", "http://", -1) + if "https:///" in url: + url = url.replace("https:///", "https://", -1) + if not "http://" in url and not "http" in url: + url = f"http://{url}" + + return url + + def checkverify(self, verify): + if str(verify).lower().strip() == "false": + return False + elif verify == None: + return False + elif verify: + return True + elif not verify: + return False + else: + return True + + def is_valid_method(self, method): + valid_methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"] + method = method.upper() + + if method in valid_methods: + return method + else: + raise ValueError(f"Invalid HTTP method: {method}") + + def parse_headers(self, headers): + parsed_headers = {} + if headers: + split_headers = headers.split("\n") + self.logger.info(split_headers) + for header in split_headers: + if ":" in header: + splititem = ":" + elif "=" in header: + splititem = "=" + else: + self.logger.info("Skipping header %s as its invalid" % header) + continue + + splitheader = header.split(splititem) + if len(splitheader) >= 2: + parsed_headers[splitheader[0].strip()] = splititem.join(splitheader[1:]).strip() + else: + self.logger.info("Skipping header %s with split %s cus only one item" % (header, splititem)) + continue + + return parsed_headers + + def parse_queries(self, queries): + parsed_queries = {} + + if not queries: + return parsed_queries + + cleaned_queries = queries.strip() + + if not cleaned_queries: + return parsed_queries + + cleaned_queries = " ".join(cleaned_queries.split()) + splitted_queries = cleaned_queries.split("&") + self.logger.info(splitted_queries) + for query in splitted_queries: + + if "=" not in query: + self.logger.info("Skipping as there is no = in the query") + continue + key, value = query.split("=") + if not key.strip() or not value.strip(): + self.logger.info( + "Skipping because either key or value is not present in query" + ) + continue + parsed_queries[key.strip()] = value.strip() + + return parsed_queries + + def new_endpoint(self, method="", base_url="", headers="", queries="", path="", username="", password="", verify=False, req_body=""): + url = self.fix_url(base_url) + + try: + method = self.is_valid_method(method) + except ValueError as e: + self.logger.error(e) + return {"error": str(e)} + + if path and not path.startswith('/'): + path = '/' + path + + url += path + + parsed_headers = self.parse_headers(headers) + parsed_queries = self.parse_queries(queries) + + verify = self.checkverify(verify) + + if isinstance(req_body, dict): + try: + req_body = json.dumps(req_body) + except json.JSONDecodeError as e: + self.logger.error(f"error : {e}") + return {"error: Invalid JSON format for request body"} + + auth = None + if username or password: + if "Authorization" in headers: + pass + else: + auth = requests.auth.HTTPBasicAuth(username, password) + + try: + response = requests.request(method, url, headers=parsed_headers, params=parsed_queries, data=req_body, auth=auth, verify=verify) + response.raise_for_status() + return response.json() + + except requests.RequestException as e: + self.logger.error(f"Request failed: {e}") + return {"error": f"Request failed: {e}"} + ` + return pythonCode + +} + +func AddNewEndPoint () (WorkflowAppAction , string) { + + parameters := []WorkflowAppActionParameter{} + pyCode := NewEndPointPythonCode() + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "method", + Description: "The http method to use", + Multiline: false, + Required: true, + Configuration: true, + Example: "GET , POST PUT ...", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "base_url", + Description: "the base part of your url ", + Multiline: false , + Required: true , + Configuration: true, + Example: "https://api.example.com", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "headers", + Description: "Headers to use", + Multiline: true, + Required: false, + Example: "Content-Type:application/json\nAccept:application/json", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "queries", + Description: "queries to be included in the url", + Multiline: true, + Required: false, + Example: "user_id=123&category=tech", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "path", + Description: "the path to add to the base url", + Multiline: false, + Required: false, + Example: "users/profile/settings", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "username", + Description: "username for basic auth", + Multiline: false, + Required: false, + Example: "example_99", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "password", + Description: "password for the basic auth", + Multiline: false, + Required: false, + Example: "******", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "verify", + Description: "", + Multiline: false, + Required: false, + Example: "True", + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + parameters = append(parameters, WorkflowAppActionParameter{ + Name: "req_body", + Description: "the path to add to the base url", + Multiline: true, + Required: false, + Example: `{"username": "example_user", "email": "user@example.com"}`, + Schema: SchemaDefinition{ + Type: "string", + }, + }) + + action := WorkflowAppAction{ + Description: "add a new endpoint for your app", + Name: "new_endpoint", + NodeType: "action", + Environment: "Shuffle", + Parameters: parameters, + } + + action.Returns.Schema.Type = "string" + + return action , pyCode + +} + + func GenerateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, WorkflowApp, []string, error) { api := WorkflowApp{} //log.Printf("%#v", swagger.Info) @@ -1319,7 +1578,8 @@ func GenerateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, Type: "string", }, }) - + + //Verified bool `json:"verified" yaml:"verified" required:false datastore:"verified"` for actualPath, path := range swagger.Paths { //actualPath = strings.Replace(actualPath, ".", "", -1) @@ -1368,6 +1628,7 @@ func GenerateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, pythonFunctions = append(pythonFunctions, curCode) } + // Has to be here because its used differently above. // FIXING this is done during export instead? //log.Printf("OLDPATH: %s", actualPath) @@ -1379,6 +1640,10 @@ func GenerateYaml(swagger *openapi3.Swagger, newmd5 string) (*openapi3.Swagger, //newPaths[actualPath] = path } + action, curCode := AddNewEndPoint() + api.Actions = append(api.Actions, action) + pythonFunctions = append(pythonFunctions, curCode) + return swagger, api, pythonFunctions, nil }