Skip to content

Commit

Permalink
feat: setup base & lister class
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniAkash committed Feb 19, 2024
1 parent 46ac29c commit e21d453
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/client/auth/stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const retryCodesGrpc = new Set([
]);

// Utility type to extract the first parameter type from a function
type FirstParameterType<T> = T extends (
export type FirstParameterType<T> = T extends (
arg1: infer P,
...args: unknown[]
) => unknown
Expand Down
122 changes: 122 additions & 0 deletions src/client/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { UserAppIDSet } from "clarifai-nodejs-grpc/proto/clarifai/api/resources_pb";
import { ClarifaiAuthHelper } from "./auth/helper";
import { getFromDictOrEnv } from "../utils/misc";
import { FirstParameterType, createStub } from "./auth/stub";
import { V2Stub } from "./auth/register";
import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
import { V2Client } from "clarifai-nodejs-grpc/proto/clarifai/api/service_grpc_pb";

/**
* BaseClient is the base class for all the classes interacting with Clarifai endpoints.
* It initializes with various configuration options to set up the authentication helper,
* gRPC stub, and other necessary properties for interacting with the Clarifai API.
*
* @property {ClarifaiAuthHelper} authHelper An instance of ClarifaiAuthHelper for authentication.
* @property {V2Stub} STUB The gRPC Stub object for API interaction.
* @property {[string, string][]} metadata The gRPC metadata containing the personal access token.
* @property {string} pat The personal access token.
* @property {UserAppIDSet} userAppId The protobuf object representing user and app IDs.
* @property {string} base The base URL for the API endpoint.
*/
export class BaseClient {
protected authHelper: ClarifaiAuthHelper;
protected STUB: V2Stub;
protected metadata: [string, string][];
protected pat: string;
protected userAppId: UserAppIDSet;
protected base: string;

/**
* Constructs a new BaseClient instance with specified configuration options.
*
* @param {Object} kwargs Configuration options for the client.
* @param {string} kwargs.userId A user ID for authentication.
* @param {string} kwargs.appId An app ID for the application to interact with.
* @param {string} kwargs.pat A personal access token for authentication. If not provided, it attempts to fetch from environment variables.
* @param {string} [kwargs.token] An optional token for authentication.
* @param {string} [kwargs.base='https://api.clarifai.com'] The base URL for the API endpoint. Defaults to 'https://api.clarifai.com'.
* @param {string} [kwargs.ui='https://clarifai.com'] The URL for the UI. Defaults to 'https://clarifai.com'.
*/
constructor(
kwargs:
| {
userId: string;
appId: string;
pat: string;
token?: string;
base?: string;
ui?: string;
}
| Record<string, never> = {},
) {
const pat = getFromDictOrEnv("pat", "CLARIFAI_PAT", kwargs);
kwargs.pat = pat;
this.authHelper =
Object.keys(kwargs).length === 0
? new ClarifaiAuthHelper(
kwargs.userId,
kwargs.appId,
kwargs.pat,
kwargs.token,
kwargs.base,
kwargs.ui,
false,
)
: ClarifaiAuthHelper.fromEnv(false); // The validate parameter is set to false explicitly
this.STUB = createStub(this.authHelper);
this.metadata = this.authHelper.metadata;
this.pat = this.authHelper.pat;
this.userAppId = this.authHelper.getUserAppIdProto();
this.base = this.authHelper.base;
}

/**
* Makes a gRPC request to the API.
*
* @param method The gRPC method to call.
* @param argument The argument to pass to the gRPC method.
* @returns A Promise resolving to the result of the gRPC method call.
*/
protected async grpcRequest<MethodName extends keyof V2Client>(
method: MethodName,
argument: FirstParameterType<V2Client[MethodName]>,
) {
await this.STUB.makeCall(method, argument);
}

/**
* Converts a string to a Timestamp object.
*
* @param dateStr The string to convert.
* @returns A Timestamp object representing the given date string.
*/
convertStringToTimestamp(dateStr: string): Timestamp {
const timestamp = new Timestamp();

// Attempt to parse the date string into a Date object
const datetimeObj = new Date(dateStr);

// Check if the date is valid
if (isNaN(datetimeObj.getTime())) {
throw new Error("Invalid date string");
}

// Convert the Date object to a Timestamp
timestamp.fromDate(datetimeObj);

return timestamp;
}

/**
* Converts keys in a response object to resource proto format.
*
* @param oldObj The object to convert.
* @param listingResource Optionally specifies a resource name to transform 'id' keys.
* @returns The object with keys processed according to protobuf structures.
*
* TODO: Implement the actual conversion logic
*/
processResponseKeys() {
throw new Error("Not implemented");
}
}
29 changes: 29 additions & 0 deletions src/client/lister.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { BaseClient } from "./base";

export class Lister extends BaseClient {
defaultPageSize: number;

constructor(
kwargs:
| {
userId: string;
appId: string;
pat: string;
token?: string;
base?: string;
ui?: string;
}
| Record<string, never> = {},
pageSize: number = 16,
) {
super(kwargs);
this.defaultPageSize = pageSize;
}

/**
* TODO: Implement the actual pagination logic
*/
listPagesGenerator() {
throw new Error("Not implemented");
}
}
29 changes: 29 additions & 0 deletions src/utils/misc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { UserError } from "../errors";

/**
* Get a value from a dictionary or an environment variable.
*/
export function getFromDictOrEnv(
key: string,
envKey: string,
data: { [key: string]: string },
): string {
if (data?.[key]) {
return data[key];
} else {
return getFromEnv(key, envKey);
}
}

/**
* Get a value from an environment variable.
*/
function getFromEnv(key: string, envKey: string): string {
if (process.env?.[envKey]) {
return process.env[envKey]!;
} else {
throw new UserError(
`Did not find \`${key}\`, please add an environment variable \`${envKey}\` which contains it, or pass \`${key}\` as a named parameter.`,
);
}
}

0 comments on commit e21d453

Please sign in to comment.