googleapis / gaxios Goto Github PK
View Code? Open in Web Editor NEWAn HTTP request client that provides an axios like interface over top of node-fetch. Super lightweight. Supports proxies and all sorts of other stuff.
License: Apache License 2.0
An HTTP request client that provides an axios like interface over top of node-fetch. Super lightweight. Supports proxies and all sorts of other stuff.
License: Apache License 2.0
The release PR #146 is still in a pending state after several hours
I'm coming to gaxios
from request
. In the latter I'm used to specifying gzip: true
in my request options, to ensure compression is used in the response (if available). This does not appear to be available in gaxios
so I'm wondering if it is effectively enabled by default? Not that I'd ever want to, but is it possible in gaxios
to disable compression?
And it seems to me that the following drop-in replacements can also be made when transitioning from request
to gaxios
... please correct me if I'm wrong!
json: true
becomes responseType: 'json'
(though this is the default anyway so could be omitted)body: { a: x, b: y }
becomes data: { a: x, b: y }
qs: { a: x, b: y }
becomes params: { a: x, b: y }
What about an equivalent for auth: { bearer: bearerToken }
? See here.
And an equivalent to resolveWithFullResponse
? See here.
Saw this while investigating "Error: Cannot find module 'gaxios'"
error that started happening for my program today. See below, it seems version 1.0.2 has "build" directory but version 1.0.6 that was released today does not.
@azina:node_modules$
@azina:test$ npm install [email protected]
...
+ [email protected]
updated 1 package and audited 524 packages in 0.638s
found 0 vulnerabilities
@azina:test$ ls node_modules/gaxios/
LICENSE README.md build package.json
@azina:test$ npm install [email protected]
...
+ [email protected]
updated 1 package and audited 524 packages in 0.76s
found 0 vulnerabilities
@azina:test$ ls node_modules/gaxios/
LICENSE README.md package.json
I am attempting to build my Node.js and typescript project, and am running into a couple of issues.
node_modules/gaxios/build/src/index.d.ts(22,12): error TS1005: '>' expected.
node_modules/gaxios/build/src/index.d.ts(22,49): error TS1109: Expression expected.
gaxios is being used as a dependency of Google-Auth-Library and it's using version 1.2.1.
Is there a fix I can make myself for this?
There is no way to know what real URL was fetched if maxRedirects/follow is setted.
Is your feature request related to a problem? Please describe.
When we try to parse relative links (it's a bad but real) in the crawled page we can not say how turn it out in absolute links.
Describe the solution you'd like
Most we need real response URL after some redirects chain happens.
node-fetch Response have url
property with final page URL.
axios response have request
property as XMLHttpRequest object with final page URL in responseURL
property.
So it can be done with limited and incomplete interface of XMLHttpRequest. Something like this marapper@836fca1
Describe alternatives you've considered
Full and comlete implementation of axios response? But it's not neccessary in most cases.
Additional context
It could solve linkinator' issues JustinBeckwith/linkinator#108
We need to have the CI configured for this repo on the backend. It has browser tests, so should look similar to google-auth-library.
๐ With the move from axios to gaxios, the googleapis module lost the ability to specify maxContentLength
for requests. We've previously been using this option and googleapis itself used it until migrating to using googleapis-common which relied on gaxios. It'd be nice to have the option to set a max content length for situations when you'd like to limit response size.
Currently gaxios not support https_proxy
environment variable like socks5://127.0.0.1:8080
. I did a litte hack on the code, just change the file https://github.com/googleapis/gaxios/blob/v2.2.0/src/gaxios.ts#L60
HttpsProxyAgent = require('https-proxy-agent');
to
HttpsProxyAgent = require('proxy-agent');
Then it work fine.
proxy-agent also write by the https-proxy-agent author.
gaxios
version: 2.2.0submitAction = async (action: SubmitAction):
GaxiosPromise<sheets_v4.Schema$BatchUpdateSpreadsheetResponse> => { ... }
Error: TS1055: Type 'GaxiosPromise' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
Adding export const GaxiosPromise = Promise;
in common.d.ts
fixes the problem, but I'm not sure how to achieve this during the build process, hence no PR.
Got solution from here: microsoft/TypeScript#12776 (comment)
Hi @JustinBeckwith,
In your PR for googleapis
googleapis/google-api-nodejs-client#1558, it's written that gaxios
supports encoding
option. But I don't see it anywhere in gaxios
. Am I misunderstanding something here?
Thanks
Looking here:
#174
It looks like 2.1.0
never went out, despite the GitHub Release getting created. This bug is to unstick this release.
To track the overall problem:
googleapis/releasetool#229
From this:
Lines 76 to 78 in 7137a2d
To this:
if (config.onRetryAttempt) {
await config.onRetryAttempt(err);
}
Only really useful if you're trying to migrate from axios to the fetch
It might be helpful to indicate why someone would be inclined to make this migration. At least, as a sample of 1, count me as curious.
Hello! I'm currently encountering issues using this lib with IE11 (Nextjs, Apollo, GraphQL). Basically i'm getting a syntax
error and the breakpoint is being setted in the class GaxiosError
. Any clue on this? Thanks :)
The release PR #193 is still in a pending state after several hours
@vc102375 Oh, that's bad. URL
class was added in v6.13.0. The easiest way for you is switching to Node.js v8 since v6 will be EOL in less than a month.
As a quick workaround, you can add this to the very beginning of the your application:
const url = require('url'); // legacy Node6 url
const semver = require('semver');
class Node6CompatibilityURL {
constructor(str) {
this.url = url.parse(str);
this.origin = this.url.protocol + '//';
this.pathname = this.url.pathname ? this.url.pathname : '';
this.search = this.url.search ? this.url.search : '';
this.href = this.url.href ? this.url.href : '';
}
}
if (semver.lt(process.version, '6.13.0')) {
window = {};
window.URL = Node6CompatibilityURL; // no warranty ๐ฑ
}
Make sure you npm install semver
to make it work. This code creates a global window
object with window.URL
that will make gaxios think it's running in browser mode, so it will use this instead of the URL class that will appear in v6.13.0. Thanks for semver
check, it will keep working even after you upgrade Node.js. Please try that and let me know if it helped.
Originally posted by @alexander-fenster in #44 (comment)
Hello! Autosynth couldn't regenerate gaxios. ๐
Here's the output from running synth.py
:
Cloning into 'working_repo'...
Switched to branch 'autosynth'
Traceback (most recent call last):
File "/home/kbuilder/.pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/home/kbuilder/.pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/tmpfs/src/git/autosynth/autosynth/synth.py", line 256, in <module>
main()
File "/tmpfs/src/git/autosynth/autosynth/synth.py", line 196, in main
last_synth_commit_hash = get_last_metadata_commit(args.metadata_path)
File "/tmpfs/src/git/autosynth/autosynth/synth.py", line 149, in get_last_metadata_commit
text=True,
File "/home/kbuilder/.pyenv/versions/3.6.1/lib/python3.6/subprocess.py", line 403, in run
with Popen(*popenargs, **kwargs) as process:
TypeError: __init__() got an unexpected keyword argument 'text'
Google internal developers can see the full log here.
We just ran into an issue where require('url').URL
was a feature added in Node 6.13. Our tests seem to build on 6@latest, so all was assumed to be well.
The release PR #202 is still in a pending state after several hours
currently we don't have publication setup through kokoro, perhaps this could be a candidate for a wombat-dressing-room probot app.
I'm confused. I was reading the Google OAuth2 workflow when I saw a link to this library. What is the advantage of using this over axios?
gaxios
version: 2.0.1Make a request.
Error on ๐ line.
class Gaxios {
/**
* The Gaxios class is responsible for making HTTP requests.
* @param defaults The default set of options to be used for this instance.
*/
constructor(defaults) {
this.agentCache = new Map();
this.defaults = defaults || {};
}
/**
* Perform an HTTP request with the given options.
* @param opts Set of HTTP options that will be used for this HTTP request.
*/
async request(opts = {}) {
opts = this.validateOpts(opts); // <-- ๐๐๐๐๐๐๐๐๐
try {
let translatedResponse;
if (opts.adapter) {
translatedResponse = await opts.adapter(opts);
}
I want to force my node js app to work through a specific interface or IP address like the localAddress parameter of request module, is possible on axios?
No units are specified for the retryDelay
option, which makes it hard to be sure what the value represents.
// The amount of time to initially delay the retry. Defaults to 100.
retryDelay?: number;
I was using the option in a library that uses gaxios
as a dependency of a dependency, so I had to dig through multiple layers to end up in the source code here to confirm that it uses milliseconds.
It'd be helpful for the units of the number to be in the option name, so that it's called something like retryDelayMilliseconds
. Or even better, initialRetryDelayMilliseconds
.
I didn't look through all other options to see whether they're missing units, but generally, I think it's helpful for all units to be specified wherever possible, to reduce ambiguity.
There are 2 discrepancies between gaxios and axios
> const api = new URL('/account/me', 'https://googleapi.com/v2/')
TypeError: URL is not a constructor
URL {
href: 'https://googleapi.com/account/me',
origin: 'https://googleapi.com',
protocol: 'https:',
username: '',
password: '',
host: 'googleapi.com',
hostname: 'googleapi.com',
port: '',
pathname: '/account/me'',
search: '',
searchParams: URLSearchParams {},
hash: '' }
Thanks for stopping by to let us know something could be better!
PLEASE READ: If you have a support contract with Google, please create an issue in the support console instead of filing on GitHub. This will ensure a timely response.
Please run down the following list and make sure you've tried the usual "quick fixes":
If you are still having issues, please be sure to include as much information as possible:
gaxios
version:Making sure to follow these steps will guarantee the quickest resolution possible.
Thanks!
Hello! Autosynth couldn't regenerate gaxios. ๐
Here's the output from running synth.py
:
Cloning into 'working_repo'...
Switched to branch 'autosynth'
Running synthtool
['/tmpfs/src/git/autosynth/env/bin/python3', '-m', 'synthtool', 'synth.py', '--']
synthtool > Executing /tmpfs/src/git/autosynth/working_repo/synth.py.
.eslintignore
.eslintrc.yml
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/feature_request.md
.github/ISSUE_TEMPLATE/support_request.md
.github/PULL_REQUEST_TEMPLATE.md
synthtool > Wrote metadata to synth.metadata.
Traceback (most recent call last):
File "/home/kbuilder/.pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/home/kbuilder/.pyenv/versions/3.6.1/lib/python3.6/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/__main__.py", line 99, in <module>
main()
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/__main__.py", line 91, in main
spec.loader.exec_module(synth_module) # type: ignore
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "/tmpfs/src/git/autosynth/working_repo/synth.py", line 6, in <module>
templates = common_templates.node_library()
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/gcp/common.py", line 89, in node_library
return self._generic_library("node_library", **kwargs)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/gcp/common.py", line 49, in _generic_library
result = t.render(**kwargs)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/sources/templates.py", line 83, in render
_render_to_path(self.env, template_name, self.dir, kwargs)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/sources/templates.py", line 53, in _render_to_path
output.dump(fh)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/environment.py", line 1313, in dump
fp.writelines(iterable)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/environment.py", line 1357, in __next__
return self._next()
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/environment.py", line 1125, in generate
yield self.environment.handle_exception()
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/synthtool/gcp/templates/node_library/.github/PULL_REQUEST_TEMPLATE.md", line 2, in top-level template code
- [ ] Make sure to open an issue as a [bug/issue](https://github.com/{{ metadata['repo']['repo'] }}/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
File "/tmpfs/src/git/autosynth/env/lib/python3.6/site-packages/jinja2/environment.py", line 452, in getitem
return obj[argument]
jinja2.exceptions.UndefinedError: 'dict object' has no attribute 'repo'
Synthesis failed
Google internal developers can see the full log here.
It looks like with the move from axios to gaxios, googleapis lost the ability to define adapters using axios' adapter option. We've previously used this to instrument googleapi client requests and would like to continue that while upgrading to future versions of googleapis.
(source: googleapis/gcs-resumable-upload#174 (comment))
When sending a POST request, node-fetch embeds the stream in the request options.
const reqOpts = {uri: 'http://')
fs.createReadStream('file.zip')
.on('error', console.error)
.pipe(fetch(reqOpts))
.on('error', console.error)
.pipe(dest)
const readFileStream = fs.createReadStream('file.zip')
readFileStream.on('error', console.error)
const reqOpts = {uri: 'http://', body: readFileStream} // < embedded
const resp = await fetch(reqOpts)
resp.data
.on('error', console.error)
.pipe(dest)
I believe there is room for simplification here. Doing a GET response could be easier, too.
const reqOpts = {uri: 'http://')
fetch(reqOpts)
.on('error', console.error)
.pipe(fs.createWriteStream('file.zip'))
.on('error', console.error)
const reqOpts = {uri: 'http://', responseType: 'stream'}
const resp = await fetch(reqOpts)
resp.data
.on('error', console.error)
.pipe(fs.createWriteStream('file.zip'))
.on('error', console.error)
Please correct any of these examples, if there is an easier option I don't know about!
The release PR #159 is still in a pending state after several hours
The release PR #259 is still in a pending state after several hours
Hey friends, I found this module via JustinBeckwith/retry-axios#1, and tried it out as a 'drop-in replacement' for axios because I need that sweet retry goodness and retry-axios
has this issue where it only retries once, then seems to...forget my config. Something seems to be missing, though: interceptors!
Is your feature request related to a problem? Please describe.
I think this is a feature request, unless I'm really bad at reading documentation. Couldn't see an indication in the source code that it's supported either.
So I copy/paste replaced axios
with gaxios
, ran my code...
const requests = require('gaxios'),
_ = require('lodash')
const logHttpErrorDetails = requests.interceptors.response.use(/* my fully sick function for logging all error responses */)
...and got this error:
TypeError: Cannot read property 'response' of undefined
Describe the solution you'd like
I would like axios-like interceptors supported for use in gaxios
.
Describe alternatives you've considered
Probably just going back to axios
and putting up with my retry-axios
issue.
Additional context
๐
The default test environment that Jest uses for testing is a browser-like one through jsdom.
The browser-like environment makes your following line of code fail:
const fetch = isBrowser() ? window.fetch : nodeFetch;
because typeof window !== 'undefined'
in isBrowser()
evaluates to true but window.fetch
is undefined.
Maybe, you can directly check against the existence of window.fetch
instead of relying on isBrowser
.
If you agree, I can send you a PR to replace each and every check against isBrowser
with a feature-detection check.
When I look for how the retry is implemented with exponential delay, I found that retryDelay is not used when calculating the delay.
Maybe the delay could be an addition or multiplication with the retryDelay parameter ? This could let anyone modify the initial delay, or the delay time between retries.
Alternatively, maybe removing the retryDelay from the README and in the code would be less misleading ?
I don't think this break anything, but I guess this would produce a better code quality.
In yarn there exists version 1.8.5: https://yarnpkg.com/en/package/gaxios
Github it does not exists: https://github.com/googleapis/gaxios
In the registry of yarn it does not exsist: https://registry.yarnpkg.com/gaxios/
NPM does not have the version: https://www.npmjs.com/package/gaxios
But this breaks my build, for some reason, I have it in my lockfile with version 1.8.5, without having it as a dependency myself. Its a child dependency of google libs.
So maybe I should delete the lockfile and update?
Currently putting 1.8.4 in my resolution works, but not sure how that will affect, as it is not my own dependency.
Getting this : node_modules/gaxios/build/src/index.js:28
async function request(opts) {
^^^^^^^^
SyntaxError: Unexpected token function
Gaxios rewrites the Content-Type
header when the payload is of type 'object' in validateOpts
:
if (opts.data) {
if (this.isReadableStream(opts.data)) {
opts.body = opts.data;
} else if (typeof opts.data === 'object') { // <-- Here
opts.body = JSON.stringify(opts.data);
opts.headers['Content-Type'] = 'application/json';
} else {
opts.body = opts.data;
}
}
I am currently updating to the google publisher v3 API (NodeJS) and I've hit a snag.
I am reading and passing the apk data as follows:
const apk = fs.readFileSync(apkFilePath);
this.publisher.edits.apks.upload({
editId,
packageName,
media: {
mimeType: 'application/vnd.android.package-archive',
body: apk
}
}, (err, res) => {});
In this case, I am explicitly specifying the mimeType
to the one required by the upload API, apk
variable is of type Buffer
, but a typeof
check returns 'object'. The upload API then returns
Media type 'application/json' is not supported. Valid media types: [application/octet-stream, application/vnd.android.package-archive]
I'm not sure why there's a need to force the header and serialization when the user has explicitly set them, maybe I am missing something though ๐ค
baseURL
(eg: 'https://www.google.com')retry
option enabled. Browser will try to request to these following URLs:The problem seems to be at these places:
Line 106 in 7137a2d
Line 110 in 7137a2d
Line 86 in 7137a2d
Lines 149 to 152 in 7137a2d
On retry, request()
will be called recursively. Hence validateOpts()
will also be called and the baseUrl
will be appended again and again.
My proposed solution is to add a new property to GaxiosOptions
to handle the modified URL instead of mutating the original URL.
I think this is likely an omission in shouldRetryRequest
. While this function can be overridden, the default behavior is probably surprising.
It looks like after migration from axios to gaxios in googleapis v37.0.0 feat: make it webpackable feature does not work properly.
Build with webpack works fine but getting an error on any request: URL is not a constructor at Gaxios.validateOpts
gaxios.ts#L151
Node URL Api is incompatible with node-url in webpack's lib. Some details can be found here:
webpack/node-libs-browser#69
webpack/node-libs-browser#78
Is it supposed to be used with webpack ?
Currently if one were to set a "content-type" header and a "Content-Type" header, the two are not equivalent.
I've seen libraries like express
approach this differently, such that headers
are case-insensitive.
Related to googleapis/google-api-nodejs-client#1777.
We accept a responseType
as part of the request config that dictates what processing we do with the response body before returning it in res.data
. By default, we just assume json
if not told otherwise. The problem pops up when the content type is defined in a response header, and we just ignore it. When an application/gzip
content type comes back in a header, I'd argue we shouldn't try JSON.parse
-ing that by default :)
gaxios
version: 2.0.1I have dug into the code and find the main reason is the function isReadableStream
in gaxios.js.
The object from @google-cloud/storage does have the _read
function and act as a 'Readable', but it is not the instance of stream.Readable. So the function isReadableStream
will always return false here and the request will be changed from application/octet-stream
to application/json
.
I think the solution maybe:
Please kindly advise. Thanks!
The release PR #174 is still in a pending state after several hours
Could you add support for no_proxy environment variable please? so we are able to bypass proxy for specific url pattern?
Thanks
FYI: Similar request was made to axios as well but it yet not be part of official release - axios/axios#434
With google-api-nodejs-client's move from Axios to gaxios, the cancellation feature has been lost. This turns out to be important for certain use cases.
For example, the PubSub pull API has an option to return immediately or wait for some messages to arrive. Waiting for some messages is desirable if polling in a loop, so the loop doesn't poll overly frequently causing a high request volume and incurring costs for each request. But if the client decides to cancel the request, it may be stuck waiting for an indeterminate amount of time without the ability to cancel the request.
The ideal solution would be to support the same cancellation semantics as Axios, or some other cancellation API.
The release PR #186 is still in a pending state after several hours
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.