Skip to content

Commit

Permalink
Add *WithResponseHeaders() methods
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierapivideo authored Apr 24, 2024
1 parent 9f0c184 commit bf54a6b
Show file tree
Hide file tree
Showing 16 changed files with 1,578 additions and 685 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog
All changes to this project will be documented in this file.

## [2.5.7] - 2024-04-23
- Add *WithResponseHeaders() methods

## [2.5.6] - 2024-02-19
- Update VideoStatusIngest enum

Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- [WatermarksApi](#watermarksapi)
- [WebhooksApi](#webhooksapi)
- [Models](#models)
- [Rate Limiting](#rate-limiting)
- [Authorization](#authorization)
- [API key](#api-key)
- [Get the access token](#get-the-access-token)
Expand Down Expand Up @@ -280,6 +281,24 @@ Method | Description | HTTP request
- [WebhooksListResponse](https://github.com/apivideo/api.video-nodejs-client/blob/main/docs/model/WebhooksListResponse.md)


### Rate Limiting

api.video implements rate limiting to ensure fair usage and stability of the service. The API provides the rate limit values in the response headers for any API requests you make. The /auth endpoint is the only route without rate limitation.

In this Node.js client, you can access these headers by using the `*WithResponseHeaders()` versions of the methods. These methods return both the response body and the headers, allowing you to check the `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Retry-After` headers to understand your current rate limit status.

Read more about these response headers in the [API reference](https://docs.api.video/reference#limitation).

Here is an example of how to use these methods:

```js
const client = new ApiVideoClient({ apiKey: "YOUR_API_KEY" });
const { body: videos, headers } = await client.videos.listWithResponseHeaders();
console.log('Rate Limit:', headers['x-ratelimit-limit']);
console.log('Rate Limit Remaining:', headers['x-ratelimit-remaining']);
console.log('Rate Limit Retry after:', headers['x-ratelimit-retry-after']);
```

### Authorization

#### API key
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@api.video/nodejs-client",
"version": "2.5.6",
"version": "2.5.7",
"description": "api.video nodejs API client",
"keywords": [
"api.video",
Expand Down
17 changes: 16 additions & 1 deletion src/HttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,21 @@ export type QueryOptions = {
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
};

export type ApiResponseHeaders = {
server: string;
'content-type': string;
'transfer-encoding': string;
connection: string;
'cache-control': string;
date: string;
'x-ratelimit-remaining': string;
'x-ratelimit-retry-after': string;
'x-ratelimit-limit': string;
'x-server': string;
'access-control-allow-origin': string;
'timing-allow-origin': string;
};

export default class HttpClient {
private apiKey?: string;
private baseUri: string;
Expand All @@ -44,7 +59,7 @@ export default class HttpClient {
this.chunkSize = params.chunkSize;
this.headers = new AxiosHeaders({
Accept: 'application/json, */*;q=0.8',
'AV-Origin-Client': 'nodejs:2.5.6',
'AV-Origin-Client': 'nodejs:2.5.7',
Authorization: this.apiKey ? `Basic ${encode(`${this.apiKey}:`)}` : '',
...(params.applicationName && params.applicationVersion
? {
Expand Down
80 changes: 53 additions & 27 deletions src/api/AdvancedAuthenticationApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

import ObjectSerializer from '../ObjectSerializer';
import HttpClient, { QueryOptions } from '../HttpClient';
import HttpClient, { QueryOptions, ApiResponseHeaders } from '../HttpClient';
import AccessToken from '../model/AccessToken';
import AuthenticatePayload from '../model/AuthenticatePayload';
import RefreshTokenPayload from '../model/RefreshTokenPayload';
Expand All @@ -33,6 +33,19 @@ export default class AdvancedAuthenticationApi {
public async authenticate(
authenticatePayload: AuthenticatePayload
): Promise<AccessToken> {
return this.authenticateWithResponseHeaders(authenticatePayload).then(
(res) => res.body
);
}

/**
* Returns a bearer token that can be used to authenticate other endpoint. You can find the tutorial on using the disposable bearer token [here](https://docs.api.video/reference/disposable-bearer-token-authentication).
* Get Bearer Token
* @param authenticatePayload
*/
public async authenticateWithResponseHeaders(
authenticatePayload: AuthenticatePayload
): Promise<{ headers: ApiResponseHeaders; body: AccessToken }> {
const queryParams: QueryOptions = {};
queryParams.headers = {};
if (authenticatePayload === null || authenticatePayload === undefined) {
Expand Down Expand Up @@ -60,19 +73,19 @@ export default class AdvancedAuthenticationApi {

queryParams.method = 'POST';

return this.httpClient
.call(localVarPath, queryParams)
.then(
(response) =>
ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AccessToken',
''
) as AccessToken
);
return this.httpClient.call(localVarPath, queryParams).then((response) => {
return {
headers: response.headers,
body: ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AccessToken',
''
) as AccessToken,
};
});
}

/**
Expand All @@ -83,6 +96,19 @@ export default class AdvancedAuthenticationApi {
public async refresh(
refreshTokenPayload: RefreshTokenPayload
): Promise<AccessToken> {
return this.refreshWithResponseHeaders(refreshTokenPayload).then(
(res) => res.body
);
}

/**
* Accepts the old bearer token and returns a new bearer token that can be used to authenticate other endpoint. You can find the tutorial on using the disposable bearer token [here](https://docs.api.video/reference/disposable-bearer-token-authentication).
* Refresh Bearer Token
* @param refreshTokenPayload
*/
public async refreshWithResponseHeaders(
refreshTokenPayload: RefreshTokenPayload
): Promise<{ headers: ApiResponseHeaders; body: AccessToken }> {
const queryParams: QueryOptions = {};
queryParams.headers = {};
if (refreshTokenPayload === null || refreshTokenPayload === undefined) {
Expand Down Expand Up @@ -110,18 +136,18 @@ export default class AdvancedAuthenticationApi {

queryParams.method = 'POST';

return this.httpClient
.call(localVarPath, queryParams)
.then(
(response) =>
ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AccessToken',
''
) as AccessToken
);
return this.httpClient.call(localVarPath, queryParams).then((response) => {
return {
headers: response.headers,
body: ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AccessToken',
''
) as AccessToken,
};
});
}
}
120 changes: 89 additions & 31 deletions src/api/AnalyticsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import { URLSearchParams } from 'url';
import ObjectSerializer from '../ObjectSerializer';
import HttpClient, { QueryOptions } from '../HttpClient';
import HttpClient, { QueryOptions, ApiResponseHeaders } from '../HttpClient';
import AnalyticsPlaysResponse from '../model/AnalyticsPlaysResponse';

/**
Expand All @@ -35,7 +35,37 @@ export default class AnalyticsApi {
* @param { number } searchParams.currentPage Choose the number of search results to return per page. Minimum value: 1
* @param { number } searchParams.pageSize Results per page. Allowed values 1-100, default is 25.
*/
public async getLiveStreamsPlays({
public async getLiveStreamsPlays(args: {
from: string;
dimension:
| 'liveStreamId'
| 'emittedAt'
| 'country'
| 'deviceType'
| 'operatingSystem'
| 'browser';
to?: string;
filter?: string;
currentPage?: number;
pageSize?: number;
}): Promise<AnalyticsPlaysResponse> {
return this.getLiveStreamsPlaysWithResponseHeaders(args).then(
(res) => res.body
);
}

/**
* Retrieve filtered analytics about the number of plays for your live streams in a project.
* Get play events for live stream
* @param {Object} searchParams
* @param { string } searchParams.from Use this query parameter to set the start date for the time period that you want analytics for. - The API returns analytics data including the day you set in &#x60;from&#x60;. - The date you set must be **within the last 30 days**. - The value you provide must follow the &#x60;YYYY-MM-DD&#x60; format.
* @param { &#39;liveStreamId&#39; | &#39;emittedAt&#39; | &#39;country&#39; | &#39;deviceType&#39; | &#39;operatingSystem&#39; | &#39;browser&#39; } searchParams.dimension Use this query parameter to define the dimension that you want analytics for. - &#x60;liveStreamId&#x60;: Returns analytics based on the public live stream identifiers. - &#x60;emittedAt&#x60;: Returns analytics based on the times of the play events. The API returns data in specific interval groups. When the date period you set in &#x60;from&#x60; and &#x60;to&#x60; is less than or equals to 2 days, the response for this dimension is grouped in hourly intervals. Otherwise, it is grouped in daily intervals. - &#x60;country&#x60;: Returns analytics based on the viewers&#39; country. The list of supported country names are based on the [GeoNames public database](https://www.geonames.org/countries/). - &#x60;deviceType&#x60;: Returns analytics based on the type of device used by the viewers during the play event. Possible response values are: &#x60;computer&#x60;, &#x60;phone&#x60;, &#x60;tablet&#x60;, &#x60;tv&#x60;, &#x60;console&#x60;, &#x60;wearable&#x60;, &#x60;unknown&#x60;. - &#x60;operatingSystem&#x60;: Returns analytics based on the operating system used by the viewers during the play event. Response values include &#x60;windows&#x60;, &#x60;mac osx&#x60;, &#x60;android&#x60;, &#x60;ios&#x60;, &#x60;linux&#x60;. - &#x60;browser&#x60;: Returns analytics based on the browser used by the viewers during the play event. Response values include &#x60;chrome&#x60;, &#x60;firefox&#x60;, &#x60;edge&#x60;, &#x60;opera&#x60;.
* @param { string } searchParams.to Use this optional query parameter to set the end date for the time period that you want analytics for. - If you do not specify a &#x60;to&#x60; date, the API returns analytics data starting from the &#x60;from&#x60; date up until today, and excluding today. - The date you set must be **within the last 30 days**. - The value you provide must follow the &#x60;YYYY-MM-DD&#x60; format.
* @param { string } searchParams.filter Use this query parameter to filter your results to a specific live stream in a project that you want analytics for. You must use the &#x60;liveStreamId:&#x60; prefix when specifying a live stream ID.
* @param { number } searchParams.currentPage Choose the number of search results to return per page. Minimum value: 1
* @param { number } searchParams.pageSize Results per page. Allowed values 1-100, default is 25.
*/
public async getLiveStreamsPlaysWithResponseHeaders({
from,
dimension,
to,
Expand All @@ -55,7 +85,7 @@ export default class AnalyticsApi {
filter?: string;
currentPage?: number;
pageSize?: number;
}): Promise<AnalyticsPlaysResponse> {
}): Promise<{ headers: ApiResponseHeaders; body: AnalyticsPlaysResponse }> {
const queryParams: QueryOptions = {};
queryParams.headers = {};
if (from === null || from === undefined) {
Expand Down Expand Up @@ -119,19 +149,19 @@ export default class AnalyticsApi {

queryParams.method = 'GET';

return this.httpClient
.call(localVarPath, queryParams)
.then(
(response) =>
ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AnalyticsPlaysResponse',
''
) as AnalyticsPlaysResponse
);
return this.httpClient.call(localVarPath, queryParams).then((response) => {
return {
headers: response.headers,
body: ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AnalyticsPlaysResponse',
''
) as AnalyticsPlaysResponse,
};
});
}

/**
Expand All @@ -145,7 +175,35 @@ export default class AnalyticsApi {
* @param { number } searchParams.currentPage Choose the number of search results to return per page. Minimum value: 1
* @param { number } searchParams.pageSize Results per page. Allowed values 1-100, default is 25.
*/
public async getVideosPlays({
public async getVideosPlays(args: {
from: string;
dimension:
| 'videoId'
| 'emittedAt'
| 'country'
| 'deviceType'
| 'operatingSystem'
| 'browser';
to?: string;
filter?: string;
currentPage?: number;
pageSize?: number;
}): Promise<AnalyticsPlaysResponse> {
return this.getVideosPlaysWithResponseHeaders(args).then((res) => res.body);
}

/**
* Retrieve filtered analytics about the number of plays for your videos in a project.
* Get play events for video
* @param {Object} searchParams
* @param { string } searchParams.from Use this query parameter to set the start date for the time period that you want analytics for. - The API returns analytics data including the day you set in &#x60;from&#x60;. - The date you set must be **within the last 30 days**. - The value you provide must follow the &#x60;YYYY-MM-DD&#x60; format.
* @param { &#39;videoId&#39; | &#39;emittedAt&#39; | &#39;country&#39; | &#39;deviceType&#39; | &#39;operatingSystem&#39; | &#39;browser&#39; } searchParams.dimension Use this query parameter to define the dimension that you want analytics for. - &#x60;videoId&#x60;: Returns analytics based on the public video identifiers. - &#x60;emittedAt&#x60;: Returns analytics based on the times of the play events. The API returns data in specific interval groups. When the date period you set in &#x60;from&#x60; and &#x60;to&#x60; is less than or equals to 2 days, the response for this dimension is grouped in hourly intervals. Otherwise, it is grouped in daily intervals. - &#x60;country&#x60;: Returns analytics based on the viewers&#39; country. The list of supported country names are based on the [GeoNames public database](https://www.geonames.org/countries/). - &#x60;deviceType&#x60;: Returns analytics based on the type of device used by the viewers during the play event. Possible response values are: &#x60;computer&#x60;, &#x60;phone&#x60;, &#x60;tablet&#x60;, &#x60;tv&#x60;, &#x60;console&#x60;, &#x60;wearable&#x60;, &#x60;unknown&#x60;. - &#x60;operatingSystem&#x60;: Returns analytics based on the operating system used by the viewers during the play event. Response values include &#x60;windows&#x60;, &#x60;mac osx&#x60;, &#x60;android&#x60;, &#x60;ios&#x60;, &#x60;linux&#x60;. - &#x60;browser&#x60;: Returns analytics based on the browser used by the viewers during the play event. Response values include &#x60;chrome&#x60;, &#x60;firefox&#x60;, &#x60;edge&#x60;, &#x60;opera&#x60;.
* @param { string } searchParams.to Use this optional query parameter to set the end date for the time period that you want analytics for. - If you do not specify a &#x60;to&#x60; date, the API returns analytics data starting from the &#x60;from&#x60; date up until today, and excluding today. - The date you set must be **within the last 30 days**. - The value you provide must follow the &#x60;YYYY-MM-DD&#x60; format.
* @param { string } searchParams.filter Use this query parameter to filter your results to a specific video in a project that you want analytics for. You must use the &#x60;videoId:&#x60; prefix when specifying a video ID.
* @param { number } searchParams.currentPage Choose the number of search results to return per page. Minimum value: 1
* @param { number } searchParams.pageSize Results per page. Allowed values 1-100, default is 25.
*/
public async getVideosPlaysWithResponseHeaders({
from,
dimension,
to,
Expand All @@ -165,7 +223,7 @@ export default class AnalyticsApi {
filter?: string;
currentPage?: number;
pageSize?: number;
}): Promise<AnalyticsPlaysResponse> {
}): Promise<{ headers: ApiResponseHeaders; body: AnalyticsPlaysResponse }> {
const queryParams: QueryOptions = {};
queryParams.headers = {};
if (from === null || from === undefined) {
Expand Down Expand Up @@ -229,18 +287,18 @@ export default class AnalyticsApi {

queryParams.method = 'GET';

return this.httpClient
.call(localVarPath, queryParams)
.then(
(response) =>
ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AnalyticsPlaysResponse',
''
) as AnalyticsPlaysResponse
);
return this.httpClient.call(localVarPath, queryParams).then((response) => {
return {
headers: response.headers,
body: ObjectSerializer.deserialize(
ObjectSerializer.parse(
response.body,
response.headers['content-type']
),
'AnalyticsPlaysResponse',
''
) as AnalyticsPlaysResponse,
};
});
}
}
Loading

0 comments on commit bf54a6b

Please sign in to comment.