@readme/httpsnippet 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Mashape (https://www.mashape.com)
3
+ Copyright (c) 2022 ReadMe (https://readme.com)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -160,6 +160,7 @@ The main difference between this library and the upstream [httpsnippet](https://
160
160
  * Contains a `harIsAlreadyEncoded` option on the core library to disable [escaping](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) of cookies and query strings in URLs. Helpful if the HAR being supplied already has them escaped.
161
161
  * PHP Guzzle snippets come with `require_once('vendor/autoload.php');` at the top of them.
162
162
  * A full integration suite for testing out snippets the library creates.
163
+ * This library does not ship a Python client for [http.client](https://docs.python.org/3/library/http.client.html) due to its limitations in supporting file uploads.
163
164
 
164
165
  ### Running the integration suite
165
166
 
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.0.3",
2
+ "version": "3.1.0",
3
3
  "name": "@readme/httpsnippet",
4
4
  "description": "HTTP Request snippet generator for *most* languages",
5
5
  "homepage": "https://github.com/readmeio/httpsnippet",
@@ -3,10 +3,9 @@ module.exports = {
3
3
  key: 'python',
4
4
  title: 'Python',
5
5
  extname: '.py',
6
- default: 'python3',
6
+ default: 'requests',
7
7
  cli: 'python3 %s',
8
8
  },
9
9
 
10
- python3: require('./python3'),
11
10
  requests: require('./requests'),
12
11
  };
@@ -11,6 +11,7 @@
11
11
  const { format } = require('util');
12
12
  const CodeBuilder = require('../../helpers/code-builder');
13
13
  const helpers = require('./helpers');
14
+ const headerHelpers = require('../../helpers/headers');
14
15
 
15
16
  module.exports = function (source, options) {
16
17
  const opts = {
@@ -28,28 +29,74 @@ module.exports = function (source, options) {
28
29
  // Set URL
29
30
  code.push('url = "%s"', source.fullUrl).blank();
30
31
 
32
+ const headers = source.allHeaders;
33
+
31
34
  // Construct payload
35
+ let payload;
36
+ let hasFiles = false;
32
37
  let hasPayload = false;
33
38
  let jsonPayload = false;
34
- if (source.postData.mimeType === 'application/json') {
35
- if (source.postData.jsonObj) {
36
- code.push('payload = %s', helpers.literalRepresentation(source.postData.jsonObj, opts));
37
- jsonPayload = true;
38
- hasPayload = true;
39
- }
40
- } else {
41
- const payload = JSON.stringify(source.postData.text);
42
- if (payload) {
43
- code.push('payload = %s', payload);
44
- hasPayload = true;
45
- }
39
+ switch (source.postData.mimeType) {
40
+ case 'application/json':
41
+ if (source.postData.jsonObj) {
42
+ code.push('payload = %s', helpers.literalRepresentation(source.postData.jsonObj, opts));
43
+ jsonPayload = true;
44
+ hasPayload = true;
45
+ }
46
+ break;
47
+
48
+ case 'multipart/form-data':
49
+ if (source.postData.params) {
50
+ const files = {};
51
+ payload = {};
52
+
53
+ source.postData.params.forEach(p => {
54
+ if (p.fileName) {
55
+ files[p.name] = `open('${p.fileName}', 'rb')`;
56
+ hasFiles = true;
57
+ } else {
58
+ payload[p.name] = p.value;
59
+ hasPayload = true;
60
+ }
61
+ });
62
+
63
+ if (hasFiles) {
64
+ code.push('files = %s', helpers.literalRepresentation(files, opts));
65
+
66
+ if (hasPayload) {
67
+ code.push('payload = %s', helpers.literalRepresentation(payload, opts));
68
+ }
69
+
70
+ // The requests library will only automatically add a `multipart/form-data` header if
71
+ // there are files being sent. If we're **only** sending form data we still need to send
72
+ // the boundary ourselves.
73
+ delete headers[headerHelpers.getHeaderName(headers, 'content-type')];
74
+ } else {
75
+ payload = JSON.stringify(source.postData.text);
76
+ if (payload) {
77
+ code.push('payload = %s', payload);
78
+ hasPayload = true;
79
+ }
80
+ }
81
+ }
82
+ break;
83
+
84
+ default:
85
+ payload = JSON.stringify(source.postData.text);
86
+ if (payload) {
87
+ code.push('payload = %s', payload);
88
+ hasPayload = true;
89
+ }
46
90
  }
47
91
 
48
92
  // Construct headers
49
- const headers = source.allHeaders;
50
93
  const headerCount = Object.keys(headers).length;
51
94
 
52
- if (headerCount === 1) {
95
+ if (!headerCount && (hasPayload || hasFiles)) {
96
+ // If we don't have any heads but we do have a payload we should put a blank line here between
97
+ // that payload consturction and our execution of the requests library.
98
+ code.blank();
99
+ } else if (headerCount === 1) {
53
100
  Object.keys(headers).forEach(header => {
54
101
  code.push('headers = {"%s": "%s"}', header, headers[header]).blank();
55
102
  });
@@ -72,7 +119,13 @@ module.exports = function (source, options) {
72
119
 
73
120
  // Construct request
74
121
  const method = source.method;
75
- let request = format('response = requests.request("%s", url', method);
122
+ let request;
123
+ // Method list pulled from their api reference https://docs.python-requests.org/en/latest/api/#requests.head
124
+ if (['HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
125
+ request = format('response = requests.%s(url', method.toLowerCase());
126
+ } else {
127
+ request = format('response = requests.request("%s", url', method);
128
+ }
76
129
 
77
130
  if (hasPayload) {
78
131
  if (jsonPayload) {
@@ -82,6 +135,10 @@ module.exports = function (source, options) {
82
135
  }
83
136
  }
84
137
 
138
+ if (hasFiles) {
139
+ request += ', files=files';
140
+ }
141
+
85
142
  if (headerCount > 0) {
86
143
  request += ', headers=headers';
87
144
  }
@@ -90,7 +147,12 @@ module.exports = function (source, options) {
90
147
 
91
148
  code.push(request).blank().push('print(response.text)');
92
149
 
93
- return code.join();
150
+ return (
151
+ code
152
+ .join()
153
+ // The `open()` call must be a literal in the code snippet.
154
+ .replace(/"open\('(.+)', 'rb'\)"/g, 'open("$1", "rb")')
155
+ );
94
156
  };
95
157
 
96
158
  module.exports.info = {
@@ -1,80 +0,0 @@
1
- /**
2
- * @description
3
- * HTTP code snippet generator for native Python3.
4
- *
5
- * @author
6
- * @montanaflynn
7
- *
8
- * for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
9
- */
10
-
11
- const CodeBuilder = require('../../helpers/code-builder');
12
-
13
- module.exports = function (source) {
14
- const code = new CodeBuilder();
15
- // Start Request
16
- code.push('import http.client').blank();
17
-
18
- // Check which protocol to be used for the client connection
19
- const protocol = source.uriObj.protocol;
20
- if (protocol === 'https:') {
21
- code.push('conn = http.client.HTTPSConnection("%s")', source.uriObj.host).blank();
22
- } else {
23
- code.push('conn = http.client.HTTPConnection("%s")', source.uriObj.host).blank();
24
- }
25
-
26
- // Create payload string if it exists
27
- const payload = JSON.stringify(source.postData.text);
28
- if (payload) {
29
- code.push('payload = %s', payload).blank();
30
- }
31
-
32
- // Create Headers
33
- const headers = source.allHeaders;
34
- const headerCount = Object.keys(headers).length;
35
- if (headerCount === 1) {
36
- Object.keys(headers).forEach(header => {
37
- code.push('headers = { \'%s\': "%s" }', header, headers[header]).blank();
38
- });
39
- } else if (headerCount > 1) {
40
- let count = 1;
41
-
42
- code.push('headers = {');
43
-
44
- Object.keys(headers).forEach(header => {
45
- // eslint-disable-next-line no-plusplus
46
- if (count++ !== headerCount) {
47
- code.push(' \'%s\': "%s",', header, headers[header]);
48
- } else {
49
- code.push(' \'%s\': "%s"', header, headers[header]);
50
- }
51
- });
52
-
53
- code.push(' }').blank();
54
- }
55
-
56
- // Make Request
57
- const method = source.method;
58
- const path = source.uriObj.path;
59
- if (payload && headerCount) {
60
- code.push('conn.request("%s", "%s", payload, headers)', method, path);
61
- } else if (payload && !headerCount) {
62
- code.push('conn.request("%s", "%s", payload)', method, path);
63
- } else if (!payload && headerCount) {
64
- code.push('conn.request("%s", "%s", headers=headers)', method, path);
65
- } else {
66
- code.push('conn.request("%s", "%s")', method, path);
67
- }
68
-
69
- // Get Response
70
- code.blank().push('res = conn.getresponse()').push('data = res.read()').blank().push('print(data.decode("utf-8"))');
71
-
72
- return code.join();
73
- };
74
-
75
- module.exports.info = {
76
- key: 'python3',
77
- title: 'http.client',
78
- link: 'https://docs.python.org/3/library/http.client.html',
79
- description: 'Python3 HTTP Client',
80
- };