mirror of
https://github.com/foss42/apidash.git
synced 2025-05-31 14:23:45 +08:00
Merge remote-tracking branch 'upstream/main' into add-rust-reqwest-codegen
- Merged upstream - Made required changes with respect to upstream - Fixed tests
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import 'package:apidash/models/models.dart' show RequestModel;
|
||||
import 'package:apidash/consts.dart';
|
||||
import 'package:apidash/utils/utils.dart' show getNewUuid;
|
||||
import 'dart/http.dart';
|
||||
import 'dart/dio.dart';
|
||||
import 'kotlin/okhttp.dart';
|
||||
@ -15,36 +16,45 @@ class Codegen {
|
||||
String? getCode(
|
||||
CodegenLanguage codegenLanguage,
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
String defaultUriScheme, {
|
||||
String? boundary,
|
||||
}) {
|
||||
String url = requestModel.url;
|
||||
|
||||
if (url.isEmpty) {
|
||||
url = kDefaultUri;
|
||||
}
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
var rM = requestModel.copyWith(url: url);
|
||||
|
||||
switch (codegenLanguage) {
|
||||
case CodegenLanguage.curl:
|
||||
return cURLCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return cURLCodeGen().getCode(rM);
|
||||
case CodegenLanguage.har:
|
||||
return HARCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return HARCodeGen().getCode(rM, defaultUriScheme, boundary: boundary);
|
||||
case CodegenLanguage.dartHttp:
|
||||
return DartHttpCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return DartHttpCodeGen().getCode(rM);
|
||||
case CodegenLanguage.dartDio:
|
||||
return DartDioCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return DartDioCodeGen().getCode(rM);
|
||||
case CodegenLanguage.jsAxios:
|
||||
return AxiosCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return AxiosCodeGen().getCode(rM);
|
||||
case CodegenLanguage.jsFetch:
|
||||
return FetchCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return FetchCodeGen().getCode(rM);
|
||||
case CodegenLanguage.nodejsAxios:
|
||||
return AxiosCodeGen(isNodeJs: true)
|
||||
.getCode(requestModel, defaultUriScheme);
|
||||
return AxiosCodeGen(isNodeJs: true).getCode(rM);
|
||||
case CodegenLanguage.nodejsFetch:
|
||||
return FetchCodeGen(isNodeJs: true)
|
||||
.getCode(requestModel, defaultUriScheme);
|
||||
return FetchCodeGen(isNodeJs: true).getCode(rM);
|
||||
case CodegenLanguage.kotlinOkHttp:
|
||||
return KotlinOkHttpCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return KotlinOkHttpCodeGen().getCode(rM);
|
||||
case CodegenLanguage.pythonHttpClient:
|
||||
return PythonHttpClientCodeGen()
|
||||
.getCode(requestModel, defaultUriScheme);
|
||||
.getCode(rM, boundary: boundary ?? getNewUuid());
|
||||
case CodegenLanguage.pythonRequests:
|
||||
return PythonRequestsCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return PythonRequestsCodeGen().getCode(rM, boundary: boundary);
|
||||
case CodegenLanguage.rustReqwest:
|
||||
return RustReqwestCodeGen().getCode(requestModel, defaultUriScheme);
|
||||
return RustReqwestCodeGen().getCode(rM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
lib/codegen/codegen_utils.dart
Normal file
15
lib/codegen/codegen_utils.dart
Normal file
@ -0,0 +1,15 @@
|
||||
String jsonToPyDict(String jsonString) {
|
||||
Map<String, String> replaceWithMap = {
|
||||
"null": "None",
|
||||
"true": "True",
|
||||
"false": "False"
|
||||
};
|
||||
String pyDict = jsonString;
|
||||
for (var k in replaceWithMap.keys) {
|
||||
RegExp regExp = RegExp(k + r'(?=([^"]*"[^"]*")*[^"]*$)');
|
||||
pyDict = pyDict.replaceAllMapped(regExp, (match) {
|
||||
return replaceWithMap[match.group(0)] ?? match.group(0)!;
|
||||
});
|
||||
}
|
||||
return pyDict;
|
||||
}
|
@ -8,15 +8,10 @@ import 'shared.dart';
|
||||
class DartDioCodeGen {
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
final next = generatedDartCode(
|
||||
url: url,
|
||||
url: requestModel.url,
|
||||
method: requestModel.method,
|
||||
queryParams: requestModel.enabledParamsMap,
|
||||
headers: requestModel.enabledHeadersMap,
|
||||
|
@ -9,15 +9,10 @@ import 'shared.dart';
|
||||
class DartHttpCodeGen {
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
final next = generatedDartCode(
|
||||
url: url,
|
||||
url: requestModel.url,
|
||||
method: requestModel.method,
|
||||
queryParams: requestModel.enabledParamsMap,
|
||||
headers: {...requestModel.enabledHeadersMap},
|
||||
@ -53,7 +48,9 @@ class DartHttpCodeGen {
|
||||
declareVar('uri').assign(refer('Uri.parse').call([literalString(url)]));
|
||||
|
||||
Expression? dataExp;
|
||||
if (kMethodsWithBody.contains(method) && (body?.isNotEmpty ?? false)) {
|
||||
if (kMethodsWithBody.contains(method) &&
|
||||
(body?.isNotEmpty ?? false) &&
|
||||
contentType != ContentType.formdata) {
|
||||
final strContent = CodeExpression(Code('r\'\'\'$body\'\'\''));
|
||||
dataExp = declareVar('body', type: refer('String')).assign(strContent);
|
||||
if (!hasContentTypeHeader) {
|
||||
|
@ -12,7 +12,7 @@ class AxiosCodeGen {
|
||||
|
||||
String kStringImportNode = """{% if isNodeJs %}import axios from 'axios';
|
||||
|
||||
{% endif %}{% if isFormDataRequest and isNodeJs %}const fs = require('fs');{% endif %}
|
||||
{% endif %}{% if hasFormData and isNodeJs %}const fs = require('fs');{% endif %}
|
||||
""";
|
||||
|
||||
String kTemplateStart = """let config = {
|
||||
@ -73,18 +73,16 @@ async function buildFormData(fields) {
|
||||
''';
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode);
|
||||
String importsData = kNodejsImportTemplate.render({
|
||||
"isFormDataRequest": requestModel.isFormDataRequest,
|
||||
"hasFormData": requestModel.hasFormData,
|
||||
"isNodeJs": isNodeJs,
|
||||
});
|
||||
|
||||
String result = importsData;
|
||||
if (requestModel.isFormDataRequest &&
|
||||
requestModel.formDataMapList.isNotEmpty) {
|
||||
if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) {
|
||||
var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate);
|
||||
var renderedMultiPartBody = templateMultiPartBody.render({
|
||||
"isNodeJs": isNodeJs,
|
||||
@ -92,17 +90,14 @@ async function buildFormData(fields) {
|
||||
result += renderedMultiPartBody;
|
||||
}
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
var rM = requestModel.copyWith(url: url);
|
||||
|
||||
var harJson = requestModelToHARJsonRequest(rM, useEnabled: true);
|
||||
var harJson = requestModelToHARJsonRequest(
|
||||
requestModel,
|
||||
useEnabled: true,
|
||||
);
|
||||
|
||||
var templateStart = jj.Template(kTemplateStart);
|
||||
result += templateStart.render({
|
||||
"url": stripUrlParams(url),
|
||||
"url": stripUrlParams(requestModel.url),
|
||||
"method": harJson["method"].toLowerCase(),
|
||||
});
|
||||
|
||||
@ -118,22 +113,21 @@ async function buildFormData(fields) {
|
||||
}
|
||||
|
||||
var headers = harJson["headers"];
|
||||
if (headers.isNotEmpty || requestModel.isFormDataRequest) {
|
||||
if (headers.isNotEmpty || requestModel.hasFormData) {
|
||||
var templateHeader = jj.Template(kTemplateHeader);
|
||||
var m = {};
|
||||
for (var i in headers) {
|
||||
m[i["name"]] = i["value"];
|
||||
}
|
||||
if (requestModel.isFormDataRequest) {
|
||||
m['Content-Type'] = 'multipart/form-data';
|
||||
if (requestModel.hasFormData) {
|
||||
m[kHeaderContentType] = 'multipart/form-data';
|
||||
}
|
||||
result += templateHeader
|
||||
.render({"headers": padMultilineString(kEncoder.convert(m), 2)});
|
||||
}
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
|
||||
if (requestModel.isFormDataRequest &&
|
||||
requestModel.formDataMapList.isNotEmpty) {
|
||||
if (requestModel.hasFormData && requestModel.formDataMapList.isNotEmpty) {
|
||||
var getFieldDataTemplate = jj.Template(kGetFormDataTemplate);
|
||||
|
||||
result += templateBody.render({
|
||||
|
@ -12,7 +12,7 @@ class FetchCodeGen {
|
||||
|
||||
String kStringImportNode = """
|
||||
import fetch from 'node-fetch';
|
||||
{% if isFormDataRequest %}const fs = require('fs');{% endif %}
|
||||
{% if hasFormData %}const fs = require('fs');{% endif %}
|
||||
|
||||
""";
|
||||
|
||||
@ -73,29 +73,26 @@ fetch(url, options)
|
||||
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
jj.Template kNodejsImportTemplate = jj.Template(kStringImportNode);
|
||||
String importsData = kNodejsImportTemplate.render({
|
||||
"isFormDataRequest": requestModel.isFormDataRequest,
|
||||
"hasFormData": requestModel.hasFormData,
|
||||
});
|
||||
|
||||
String result = isNodeJs ? importsData : "";
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
var templateMultiPartBody = jj.Template(kMultiPartBodyTemplate);
|
||||
result += templateMultiPartBody.render({
|
||||
"isNodeJs": isNodeJs,
|
||||
"fields_list": json.encode(requestModel.formDataMapList),
|
||||
});
|
||||
}
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
var rM = requestModel.copyWith(url: url);
|
||||
|
||||
var harJson = requestModelToHARJsonRequest(rM, useEnabled: true);
|
||||
var harJson = requestModelToHARJsonRequest(
|
||||
requestModel,
|
||||
useEnabled: true,
|
||||
);
|
||||
|
||||
var templateStart = jj.Template(kTemplateStart);
|
||||
result += templateStart.render({
|
||||
@ -108,8 +105,8 @@ fetch(url, options)
|
||||
if (headers.isNotEmpty) {
|
||||
var templateHeader = jj.Template(kTemplateHeader);
|
||||
var m = {};
|
||||
if (requestModel.isFormDataRequest) {
|
||||
m["Content-Type"] = "multipart/form-data";
|
||||
if (requestModel.hasFormData) {
|
||||
m[kHeaderContentType] = "multipart/form-data";
|
||||
}
|
||||
for (var i in headers) {
|
||||
m[i["name"]] = i["value"];
|
||||
@ -124,7 +121,7 @@ fetch(url, options)
|
||||
result += templateBody.render({
|
||||
"body": kEncoder.convert(harJson["postData"]["text"]),
|
||||
});
|
||||
} else if (requestModel.isFormDataRequest) {
|
||||
} else if (requestModel.hasFormData) {
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({
|
||||
"body": 'payload',
|
||||
|
@ -7,7 +7,7 @@ import 'package:apidash/consts.dart';
|
||||
|
||||
class KotlinOkHttpCodeGen {
|
||||
final String kTemplateStart = """import okhttp3.OkHttpClient
|
||||
import okhttp3.Request{{importForQuery}}{{importForBody}}
|
||||
import okhttp3.Request{{importForQuery}}{{importForBody}}{{importForFormData}}
|
||||
|
||||
fun main() {
|
||||
val client = OkHttpClient()
|
||||
@ -23,6 +23,10 @@ import okhttp3.HttpUrl.Companion.toHttpUrl""";
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import okhttp3.MediaType.Companion.toMediaType""";
|
||||
|
||||
final String kStringImportForFormData = """
|
||||
|
||||
import okhttp3.MultipartBody""";
|
||||
|
||||
final String kTemplateUrl = '''
|
||||
|
||||
val url = "{{url}}"
|
||||
@ -71,20 +75,15 @@ import okhttp3.MediaType.Companion.toMediaType""";
|
||||
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
String result = "";
|
||||
bool hasQuery = false;
|
||||
bool hasBody = false;
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
bool hasFormData = false;
|
||||
|
||||
var rec = getValidRequestUri(
|
||||
url,
|
||||
requestModel.url,
|
||||
requestModel.enabledRequestParams,
|
||||
);
|
||||
Uri? uri = rec.$1;
|
||||
@ -108,7 +107,8 @@ import okhttp3.MediaType.Companion.toMediaType""";
|
||||
|
||||
var method = requestModel.method;
|
||||
var requestBody = requestModel.requestBody;
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
hasFormData = true;
|
||||
var formDataTemplate = jj.Template(kFormDataBody);
|
||||
|
||||
result += formDataTemplate.render({
|
||||
@ -128,7 +128,8 @@ import okhttp3.MediaType.Companion.toMediaType""";
|
||||
var templateStart = jj.Template(kTemplateStart);
|
||||
var stringStart = templateStart.render({
|
||||
"importForQuery": hasQuery ? kStringImportForQuery : "",
|
||||
"importForBody": hasBody ? kStringImportForBody : ""
|
||||
"importForBody": hasBody ? kStringImportForBody : "",
|
||||
"importForFormData": hasFormData ? kStringImportForFormData : ""
|
||||
});
|
||||
|
||||
result = stringStart + result;
|
||||
@ -145,7 +146,7 @@ import okhttp3.MediaType.Companion.toMediaType""";
|
||||
var templateRequestEnd = jj.Template(kTemplateRequestEnd);
|
||||
result += templateRequestEnd.render({
|
||||
"method": method.name.toLowerCase(),
|
||||
"hasBody": (hasBody || requestModel.isFormDataRequest) ? "body" : "",
|
||||
"hasBody": (hasBody || requestModel.hasFormData) ? "body" : "",
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:jinja/jinja.dart' as jj;
|
||||
import 'package:apidash/utils/utils.dart' show requestModelToHARJsonRequest;
|
||||
import 'package:apidash/models/models.dart' show RequestModel;
|
||||
import 'package:apidash/consts.dart';
|
||||
|
||||
// ignore: camel_case_types
|
||||
class cURLCodeGen {
|
||||
@ -11,7 +12,7 @@ class cURLCodeGen {
|
||||
--header '{{name}}: {{value}}'
|
||||
""";
|
||||
String kTemplateFormData = """ \\
|
||||
--form '{{name}}: {{value}}'
|
||||
--form '{{name}}={{value}}'
|
||||
""";
|
||||
|
||||
String kTemplateBody = """ \\
|
||||
@ -20,25 +21,21 @@ class cURLCodeGen {
|
||||
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
String result = "";
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
var rM = requestModel.copyWith(url: url);
|
||||
|
||||
var harJson = requestModelToHARJsonRequest(rM, useEnabled: true);
|
||||
var harJson = requestModelToHARJsonRequest(
|
||||
requestModel,
|
||||
useEnabled: true,
|
||||
);
|
||||
|
||||
var templateStart = jj.Template(kTemplateStart);
|
||||
result += templateStart.render({
|
||||
"method": switch (harJson["method"]) {
|
||||
"GET" => "",
|
||||
"HEAD" => " --head",
|
||||
_ => " --request ${harJson["method"]} \\\n"
|
||||
_ => " --request ${harJson["method"]} \\\n "
|
||||
},
|
||||
"url": harJson["url"],
|
||||
});
|
||||
@ -46,33 +43,31 @@ class cURLCodeGen {
|
||||
var headers = harJson["headers"];
|
||||
if (headers.isNotEmpty) {
|
||||
for (var item in headers) {
|
||||
if (requestModel.hasFormData && item["name"] == kHeaderContentType) {
|
||||
continue;
|
||||
}
|
||||
var templateHeader = jj.Template(kTemplateHeader);
|
||||
result += templateHeader
|
||||
.render({"name": item["name"], "value": item["value"]});
|
||||
}
|
||||
}
|
||||
if (harJson['formData'] != null) {
|
||||
var formDataList = harJson['formData'] as List<Map<String, dynamic>>;
|
||||
for (var formData in formDataList) {
|
||||
|
||||
if (requestModel.hasJsonData || requestModel.hasTextData) {
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({"body": requestModel.requestBody});
|
||||
} else if (requestModel.hasFormData) {
|
||||
for (var formData in requestModel.formDataList) {
|
||||
var templateFormData = jj.Template(kTemplateFormData);
|
||||
if (formData['type'] != null &&
|
||||
formData['name'] != null &&
|
||||
formData['value'] != null &&
|
||||
formData['name']!.isNotEmpty &&
|
||||
formData['value']!.isNotEmpty) {
|
||||
if (formData.name.isNotEmpty && formData.value.isNotEmpty) {
|
||||
result += templateFormData.render({
|
||||
"name": formData["name"],
|
||||
"name": formData.name,
|
||||
"value":
|
||||
"${formData['type'] == 'file' ? '@' : ''}${formData["value"]}",
|
||||
"${formData.type == FormDataType.file ? '@' : ''}${formData.value}",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (harJson["postData"]?["text"] != null) {
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({"body": harJson["postData"]["text"]});
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
return null;
|
||||
|
@ -5,13 +5,15 @@ import 'package:apidash/models/models.dart' show RequestModel;
|
||||
class HARCodeGen {
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
String defaultUriScheme, {
|
||||
String? boundary,
|
||||
}) {
|
||||
try {
|
||||
var harString = kEncoder.convert(requestModelToHARJsonRequest(
|
||||
requestModel,
|
||||
defaultUriScheme: defaultUriScheme,
|
||||
useEnabled: true,
|
||||
boundary: boundary,
|
||||
));
|
||||
return harString;
|
||||
} catch (e) {
|
||||
|
@ -2,13 +2,13 @@ import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:jinja/jinja.dart' as jj;
|
||||
import 'package:apidash/utils/utils.dart'
|
||||
show getNewUuid, getValidRequestUri, padMultilineString;
|
||||
show getValidRequestUri, padMultilineString;
|
||||
import 'package:apidash/models/models.dart' show RequestModel;
|
||||
import 'package:apidash/consts.dart';
|
||||
|
||||
class PythonHttpClientCodeGen {
|
||||
final String kTemplateStart = """import http.client
|
||||
{% if isFormDataRequest %}import mimetypes
|
||||
{% if hasFormData %}import mimetypes
|
||||
from codecs import encode
|
||||
{% endif %}
|
||||
""";
|
||||
@ -87,30 +87,23 @@ dataList = build_data_list({{fields_list}})
|
||||
body = b'\r\n'.join(dataList)
|
||||
''';
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
String uuid = getNewUuid();
|
||||
|
||||
RequestModel requestModel, {
|
||||
String? boundary,
|
||||
}) {
|
||||
try {
|
||||
String result = "";
|
||||
bool hasHeaders = false;
|
||||
bool hasQuery = false;
|
||||
bool hasBody = false;
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
|
||||
var templateStartUrl = jj.Template(kTemplateStart);
|
||||
result += templateStartUrl.render(
|
||||
{
|
||||
"isFormDataRequest": requestModel.isFormDataRequest,
|
||||
"hasFormData": requestModel.hasFormData,
|
||||
},
|
||||
);
|
||||
var rec = getValidRequestUri(
|
||||
url,
|
||||
requestModel.url,
|
||||
requestModel.enabledRequestParams,
|
||||
);
|
||||
|
||||
@ -130,7 +123,9 @@ body = b'\r\n'.join(dataList)
|
||||
|
||||
var method = requestModel.method;
|
||||
var requestBody = requestModel.requestBody;
|
||||
if (kMethodsWithBody.contains(method) && requestBody != null) {
|
||||
if (kMethodsWithBody.contains(method) &&
|
||||
requestBody != null &&
|
||||
!requestModel.hasFormData) {
|
||||
var contentLength = utf8.encode(requestBody).length;
|
||||
if (contentLength > 0) {
|
||||
hasBody = true;
|
||||
@ -142,11 +137,11 @@ body = b'\r\n'.join(dataList)
|
||||
var headersList = requestModel.enabledRequestHeaders;
|
||||
if (headersList != null || hasBody) {
|
||||
var headers = requestModel.enabledHeadersMap;
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
var formHeaderTemplate =
|
||||
jj.Template(kTemplateFormHeaderContentType);
|
||||
headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({
|
||||
"boundary": uuid,
|
||||
"boundary": boundary,
|
||||
});
|
||||
}
|
||||
|
||||
@ -162,12 +157,12 @@ body = b'\r\n'.join(dataList)
|
||||
result += templateHeaders.render({"headers": headersString});
|
||||
}
|
||||
}
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
var formDataBodyData = jj.Template(kStringFormDataBody);
|
||||
result += formDataBodyData.render(
|
||||
{
|
||||
"fields_list": json.encode(requestModel.formDataMapList),
|
||||
"boundary": uuid,
|
||||
"boundary": boundary,
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -184,11 +179,11 @@ body = b'\r\n'.join(dataList)
|
||||
"queryParamsStr": hasQuery ? " + queryParamsStr" : "",
|
||||
});
|
||||
|
||||
if (hasBody || requestModel.isFormDataRequest) {
|
||||
if (hasBody || requestModel.hasFormData) {
|
||||
result += kStringRequestBody;
|
||||
}
|
||||
|
||||
if (hasHeaders || requestModel.isFormDataRequest) {
|
||||
if (hasHeaders || requestModel.hasFormData) {
|
||||
result += kStringRequestHeaders;
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:jinja/jinja.dart' as jj;
|
||||
import 'package:apidash/consts.dart';
|
||||
import 'package:apidash/utils/utils.dart'
|
||||
show getNewUuid, getValidRequestUri, padMultilineString, stripUriParams;
|
||||
show getValidRequestUri, stripUriParams, getFilenameFromPath;
|
||||
import 'package:apidash/models/models.dart' show RequestModel;
|
||||
import '../codegen_utils.dart';
|
||||
|
||||
class PythonRequestsCodeGen {
|
||||
final String kTemplateStart = """import requests
|
||||
{% if isFormDataRequest %}import mimetypes
|
||||
from codecs import encode
|
||||
{% if hasFormData %}from requests_toolbelt.multipart.encoder import MultipartEncoder
|
||||
{% endif %}
|
||||
url = '{{url}}'
|
||||
|
||||
@ -20,7 +19,6 @@ url = '{{url}}'
|
||||
params = {{params}}
|
||||
|
||||
""";
|
||||
int kParamsPadding = 9;
|
||||
|
||||
String kTemplateBody = """
|
||||
|
||||
@ -39,44 +37,27 @@ payload = {{body}}
|
||||
headers = {{headers}}
|
||||
|
||||
""";
|
||||
String kTemplateFormHeaderContentType = '''
|
||||
multipart/form-data; boundary={{boundary}}''';
|
||||
|
||||
int kHeadersPadding = 10;
|
||||
|
||||
String kTemplateRequest = """
|
||||
|
||||
response = requests.{{method}}(url
|
||||
""";
|
||||
|
||||
final String kStringFormDataBody = r'''
|
||||
final String kTemplateFormDataBody = r'''
|
||||
|
||||
def build_data_list(fields):
|
||||
dataList = []
|
||||
for field in fields:
|
||||
name = field.get('name', '')
|
||||
value = field.get('value', '')
|
||||
type_ = field.get('type', 'text')
|
||||
payload = MultipartEncoder({
|
||||
{{formdata_payload}}
|
||||
}{% if boundary != '' %},
|
||||
boundary="{{boundary}}"
|
||||
{% endif %})
|
||||
|
||||
dataList.append(encode('--{{boundary}}'))
|
||||
if type_ == 'text':
|
||||
dataList.append(encode(f'Content-Disposition: form-data; name="{name}"'))
|
||||
dataList.append(encode('Content-Type: text/plain'))
|
||||
dataList.append(encode(''))
|
||||
dataList.append(encode(value))
|
||||
elif type_ == 'file':
|
||||
dataList.append(encode(f'Content-Disposition: form-data; name="{name}"; filename="{value}"'))
|
||||
dataList.append(encode(f'Content-Type: {mimetypes.guess_type(value)[0] or "application/octet-stream"}'))
|
||||
dataList.append(encode(''))
|
||||
dataList.append(open(value, 'rb').read())
|
||||
dataList.append(encode('--{{boundary}}--'))
|
||||
dataList.append(encode(''))
|
||||
return dataList
|
||||
|
||||
dataList = build_data_list({{fields_list}})
|
||||
payload = b'\r\n'.join(dataList)
|
||||
''';
|
||||
|
||||
String kTemplateFormDataRowText = r""" "{{name}}": "{{value}}",""";
|
||||
|
||||
String kTemplateFormDataRowFile =
|
||||
r""" "{{name}}": ("{{filename}}", open("{{path}}", "rb")),""";
|
||||
|
||||
String kStringRequestParams = """, params=params""";
|
||||
|
||||
String kStringRequestBody = """, data=payload""";
|
||||
@ -91,25 +72,26 @@ print('Status Code:', response.status_code)
|
||||
print('Response Body:', response.text)
|
||||
""";
|
||||
|
||||
String kStringFormDataContentType = "payload.content_type";
|
||||
|
||||
String refactorHeaderString(String headerString) {
|
||||
return headerString.replaceAll(
|
||||
'"$kStringFormDataContentType"', kStringFormDataContentType);
|
||||
}
|
||||
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
RequestModel requestModel, {
|
||||
String? boundary,
|
||||
}) {
|
||||
try {
|
||||
String result = "";
|
||||
bool hasQuery = false;
|
||||
bool hasHeaders = false;
|
||||
bool hasBody = false;
|
||||
bool hasJsonBody = false;
|
||||
String uuid = getNewUuid();
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
|
||||
var rec = getValidRequestUri(
|
||||
url,
|
||||
requestModel.url,
|
||||
requestModel.enabledRequestParams,
|
||||
);
|
||||
Uri? uri = rec.$1;
|
||||
@ -117,7 +99,7 @@ print('Response Body:', response.text)
|
||||
var templateStartUrl = jj.Template(kTemplateStart);
|
||||
result += templateStartUrl.render({
|
||||
"url": stripUriParams(uri),
|
||||
'isFormDataRequest': requestModel.isFormDataRequest
|
||||
'hasFormData': requestModel.hasFormData
|
||||
});
|
||||
|
||||
if (uri.hasQuery) {
|
||||
@ -126,77 +108,85 @@ print('Response Body:', response.text)
|
||||
hasQuery = true;
|
||||
var templateParams = jj.Template(kTemplateParams);
|
||||
var paramsString = kEncoder.convert(params);
|
||||
paramsString = padMultilineString(paramsString, kParamsPadding);
|
||||
result += templateParams.render({"params": paramsString});
|
||||
}
|
||||
}
|
||||
|
||||
var method = requestModel.method;
|
||||
var requestBody = requestModel.requestBody;
|
||||
if (kMethodsWithBody.contains(method) && requestBody != null) {
|
||||
var contentLength = utf8.encode(requestBody).length;
|
||||
if (contentLength > 0) {
|
||||
if (requestModel.requestBodyContentType == ContentType.json) {
|
||||
hasJsonBody = true;
|
||||
var templateBody = jj.Template(kTemplateJson);
|
||||
result += templateBody.render({"body": requestBody});
|
||||
} else {
|
||||
hasBody = true;
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({"body": requestBody});
|
||||
if (requestModel.hasFormData) {
|
||||
hasBody = true;
|
||||
List<String> formdataPayload = [];
|
||||
for (var item in requestModel.formDataList) {
|
||||
if (item.type == FormDataType.text) {
|
||||
formdataPayload.add(jj.Template(kTemplateFormDataRowText).render({
|
||||
"name": item.name,
|
||||
"value": item.value,
|
||||
}));
|
||||
}
|
||||
if (item.type == FormDataType.file) {
|
||||
formdataPayload.add(jj.Template(kTemplateFormDataRowFile).render({
|
||||
"name": item.name,
|
||||
"filename": getFilenameFromPath(item.value),
|
||||
"path": item.value,
|
||||
}));
|
||||
}
|
||||
}
|
||||
var formDataBodyData = jj.Template(kTemplateFormDataBody);
|
||||
result += formDataBodyData.render(
|
||||
{
|
||||
"formdata_payload": formdataPayload.join("\n"),
|
||||
"boundary": boundary ?? '',
|
||||
},
|
||||
);
|
||||
} else if (requestModel.hasJsonData) {
|
||||
hasJsonBody = true;
|
||||
var templateBody = jj.Template(kTemplateJson);
|
||||
var pyDict = jsonToPyDict(requestModel.requestBody ?? "");
|
||||
result += templateBody.render({"body": pyDict});
|
||||
} else if (requestModel.hasTextData) {
|
||||
hasBody = true;
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({"body": requestModel.requestBody});
|
||||
}
|
||||
|
||||
var headersList = requestModel.enabledRequestHeaders;
|
||||
if (headersList != null || hasBody) {
|
||||
var headers = requestModel.enabledHeadersMap;
|
||||
if (requestModel.isFormDataRequest) {
|
||||
var formHeaderTemplate =
|
||||
jj.Template(kTemplateFormHeaderContentType);
|
||||
headers[HttpHeaders.contentTypeHeader] = formHeaderTemplate.render({
|
||||
"boundary": uuid,
|
||||
});
|
||||
}
|
||||
if (headers.isNotEmpty || hasBody) {
|
||||
hasHeaders = true;
|
||||
if (hasBody) {
|
||||
if (hasBody) {
|
||||
if (requestModel.hasFormData) {
|
||||
headers[HttpHeaders.contentTypeHeader] =
|
||||
kStringFormDataContentType;
|
||||
} else {
|
||||
headers[HttpHeaders.contentTypeHeader] =
|
||||
requestModel.requestBodyContentType.header;
|
||||
}
|
||||
}
|
||||
if (headers.isNotEmpty) {
|
||||
hasHeaders = true;
|
||||
var headersString = kEncoder.convert(headers);
|
||||
headersString = padMultilineString(headersString, kHeadersPadding);
|
||||
headersString = refactorHeaderString(headersString);
|
||||
var templateHeaders = jj.Template(kTemplateHeaders);
|
||||
result += templateHeaders.render({"headers": headersString});
|
||||
}
|
||||
}
|
||||
if (requestModel.isFormDataRequest) {
|
||||
var formDataBodyData = jj.Template(kStringFormDataBody);
|
||||
result += formDataBodyData.render(
|
||||
{
|
||||
"fields_list": json.encode(requestModel.formDataMapList),
|
||||
"boundary": uuid,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
var templateRequest = jj.Template(kTemplateRequest);
|
||||
result += templateRequest.render({
|
||||
"method": method.name.toLowerCase(),
|
||||
"method": requestModel.method.name.toLowerCase(),
|
||||
});
|
||||
|
||||
if (hasQuery) {
|
||||
result += kStringRequestParams;
|
||||
}
|
||||
|
||||
if (hasBody || requestModel.isFormDataRequest) {
|
||||
if (hasBody) {
|
||||
result += kStringRequestBody;
|
||||
}
|
||||
|
||||
if (hasJsonBody || requestModel.isFormDataRequest) {
|
||||
if (hasJsonBody) {
|
||||
result += kStringRequestJson;
|
||||
}
|
||||
|
||||
if (hasHeaders || requestModel.isFormDataRequest) {
|
||||
if (hasHeaders) {
|
||||
result += kStringRequestHeaders;
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,6 @@ class RustReqwestCodeGen {
|
||||
|
||||
String? getCode(
|
||||
RequestModel requestModel,
|
||||
String defaultUriScheme,
|
||||
) {
|
||||
try {
|
||||
String result = "";
|
||||
@ -90,9 +89,6 @@ class RustReqwestCodeGen {
|
||||
bool hasJsonBody = false;
|
||||
|
||||
String url = requestModel.url;
|
||||
if (!url.contains("://") && url.isNotEmpty) {
|
||||
url = "$defaultUriScheme://$url";
|
||||
}
|
||||
|
||||
var rec = getValidRequestUri(
|
||||
url,
|
||||
@ -103,7 +99,7 @@ class RustReqwestCodeGen {
|
||||
var templateStartUrl = jj.Template(kTemplateStart);
|
||||
result += templateStartUrl.render({
|
||||
"url": stripUriParams(uri),
|
||||
'isFormDataRequest': requestModel.isFormDataRequest,
|
||||
'isFormDataRequest': requestModel.hasFormData,
|
||||
'isJson': requestModel.requestBodyContentType == ContentType.json
|
||||
});
|
||||
|
||||
@ -116,7 +112,7 @@ class RustReqwestCodeGen {
|
||||
hasJsonBody = true;
|
||||
var templateBody = jj.Template(kTemplateJson);
|
||||
result += templateBody.render({"body": requestBody});
|
||||
} else if (!requestModel.isFormDataRequest) {
|
||||
} else if (!requestModel.hasFormData) {
|
||||
hasBody = true;
|
||||
var templateBody = jj.Template(kTemplateBody);
|
||||
result += templateBody.render({"body": requestBody});
|
||||
@ -124,7 +120,7 @@ class RustReqwestCodeGen {
|
||||
}
|
||||
}
|
||||
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
var formDataBodyData = jj.Template(kStringFormDataBody);
|
||||
result += formDataBodyData.render(
|
||||
{
|
||||
@ -162,7 +158,7 @@ class RustReqwestCodeGen {
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBody && !requestModel.isFormDataRequest) {
|
||||
if (hasBody && !requestModel.hasFormData) {
|
||||
result += kStringRequestBody;
|
||||
}
|
||||
|
||||
@ -170,7 +166,7 @@ class RustReqwestCodeGen {
|
||||
result += kStringRequestJson;
|
||||
}
|
||||
|
||||
if (requestModel.isFormDataRequest) {
|
||||
if (requestModel.hasFormData) {
|
||||
result += kStringRequestForm;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user