@eyepop.ai/eyepop 0.20.1 → 0.21.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.
@@ -1,50 +1,18 @@
1
1
  import { Logger } from 'pino';
2
+ import { Prediction as Prediction$1 } from '@eyepop.ai/eyepop';
2
3
 
3
4
  interface Session {
4
5
  readonly eyepopUrl: string;
5
- readonly popId: string;
6
6
  readonly accessToken: string;
7
7
  readonly validUntil: number;
8
8
  }
9
- interface SessionPlus extends Session {
10
- readonly baseUrl: string;
11
- readonly pipelineId: string;
12
- readonly sandboxId: string | undefined;
13
- }
14
9
  declare enum EndpointState {
15
10
  Idle = "Idle",
16
11
  Busy = "Busy",
17
12
  Authenticating = "Authenticating",
18
13
  FetchConfig = "FetchConfig",
19
- StartingPop = "StartingPop",
20
14
  Error = "Error"
21
15
  }
22
- interface LiveMedia {
23
- ingressId(): string;
24
- stream(): Promise<MediaStream>;
25
- close(): Promise<void>;
26
- }
27
- interface IngressEvent {
28
- readonly ingressId: string;
29
- readonly event: "stream-ready" | "stream-ready";
30
- }
31
- interface FileSource {
32
- readonly file: File;
33
- }
34
- interface StreamSource {
35
- readonly stream: ReadableStream<Uint8Array>;
36
- readonly mimeType: string;
37
- }
38
- interface PathSource {
39
- readonly path: string;
40
- }
41
- interface LiveSource {
42
- readonly ingressId: string;
43
- }
44
- interface UrlSource {
45
- readonly url: string;
46
- }
47
- type Source = FileSource | StreamSource | PathSource | LiveSource | UrlSource;
48
16
  interface Box {
49
17
  readonly topLeft: Point2d;
50
18
  readonly bottomRight: Point2d;
@@ -57,19 +25,19 @@ interface SourceParams {
57
25
  readonly roi: Roi | undefined;
58
26
  }
59
27
  interface StreamTime {
60
- timestamp: number;
61
- seconds: number;
62
- offset: number;
28
+ timestamp?: number;
29
+ seconds?: number;
30
+ offset?: number;
63
31
  }
64
32
  interface Prediction extends StreamTime {
65
33
  source_width: number;
66
34
  source_height: number;
67
- source_id: string;
68
- objects: Array<PredictedObject>;
69
- classes: Array<PredictedClass>;
70
- labels: Array<PredictedLabel>;
71
- meshs: Array<PredictedMesh>;
72
- keyPoints: Array<PredictedKeyPoints>;
35
+ source_id?: string;
36
+ objects?: Array<PredictedObject>;
37
+ classes?: Array<PredictedClass>;
38
+ labels?: Array<PredictedLabel>;
39
+ meshs?: Array<PredictedMesh>;
40
+ keyPoints?: Array<PredictedKeyPoints>;
73
41
  }
74
42
  interface PredictedClass {
75
43
  id: number;
@@ -130,9 +98,6 @@ interface PredictedKeyPoints {
130
98
  interface PredictedKeyPoint extends Point3d, PredictedClass {
131
99
  visible: boolean | undefined;
132
100
  }
133
- interface ResultStream extends AsyncIterable<Prediction> {
134
- cancel(): void;
135
- }
136
101
 
137
102
  interface Auth0Options {
138
103
  domain: string;
@@ -160,59 +125,222 @@ interface OAuth2Auth {
160
125
  oAuth2: true | Auth0Options;
161
126
  }
162
127
  type Authentication = undefined | SecretKeyAuth | SessionAuth | OAuth2Auth;
163
- declare enum TransientPopId {
164
- Transient = "transient"
165
- }
166
128
  interface Options {
167
129
  auth?: Authentication | undefined;
168
- /**
169
- * Defaults to process.env['EYEPOP_POP_ID'].
170
- */
171
- popId?: string | TransientPopId | undefined;
172
130
  /**
173
131
  * Override the default base URL for the API, e.g., "https://api.eyepop.ai/"
174
132
  *
175
133
  * Defaults to process.env['EYEPOP_URL'].
176
134
  */
177
135
  eyepopUrl?: string;
178
- autoStart?: boolean;
179
- stopJobs?: boolean;
180
136
  jobQueueLength?: number;
181
137
  logger?: Logger | undefined;
182
138
  }
183
139
 
184
- declare class Endpoint {
185
- private _options;
140
+ interface HttpClient {
141
+ fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
142
+ close(): Promise<void>;
143
+ }
144
+
145
+ /** Semaphores are initialized with a number of permits that get aquired and released
146
+ * over the lifecycle of the semaphore. These permits limit the number of simultaneous
147
+ * executions of the code that the semaphore synchronizes. Functions can wait on a semaphore
148
+ * and stop executing until a permit becomes available.
149
+ *
150
+ * Locks are a special case of semaphores that only allow one execution of a critical section.
151
+ * If you need a lock, you can import the Lock class from this package.
152
+ *
153
+ * This Semaphore class is implemented with the help of promises that get returned
154
+ * by functions that wait for permits to become available. This makes it possible
155
+ * to use async/await to synchronize your code.
156
+ */
157
+ declare class Semaphore {
158
+ private permits;
159
+ private promiseResolverQueue;
160
+ /**
161
+ * Creates a semaphore.
162
+ * @param permits The number of permits, i.e. strands of execution being allowed
163
+ * to run in parallel.
164
+ * This number can be initialized with a negative integer.
165
+ */
166
+ constructor(permits: number);
167
+ /**
168
+ * Returns the number of available permits.
169
+ * @returns The number of available permits.
170
+ */
171
+ getPermits(): number;
172
+ /**
173
+ * Returns a promise used to wait for a permit to become available. This method should be awaited on.
174
+ * @returns A promise that gets resolved when execution is allowed to proceed.
175
+ */
176
+ wait(): Promise<boolean>;
177
+ /**
178
+ * Alias for {@linkcode Semaphore.wait}.
179
+ * @returns A promise that gets resolved when execution is allowed to proceed.
180
+ */
181
+ acquire(): Promise<boolean>;
182
+ /**
183
+ * Same as {@linkcode Semaphore.wait} except the promise returned gets resolved with false if no
184
+ * permit becomes available in time.
185
+ * @param milliseconds The time spent waiting before the wait is aborted. This is a lower bound,
186
+ * you shouldn't rely on it being precise.
187
+ * @returns A promise that gets resolved to true when execution is allowed to proceed or
188
+ * false if the time given elapses before a permit becomes available.
189
+ */
190
+ waitFor(milliseconds: number): Promise<boolean>;
191
+ /**
192
+ * Synchronous function that tries to acquire a permit and returns true if successful, false otherwise.
193
+ * @returns Whether a permit could be acquired.
194
+ */
195
+ tryAcquire(): boolean;
196
+ /**
197
+ * Acquires all permits that are currently available and returns the number of acquired permits.
198
+ * @returns Number of acquired permits.
199
+ */
200
+ drainPermits(): number;
201
+ /**
202
+ * Increases the number of permits by one. If there are other functions waiting, one of them will
203
+ * continue to execute in a future iteration of the event loop.
204
+ */
205
+ signal(): void;
206
+ /**
207
+ * Alias for {@linkcode Semaphore.signal}.
208
+ */
209
+ release(): void;
210
+ /**
211
+ * Schedules func to be called once a permit becomes available.
212
+ * Returns a promise that resolves to the return value of func.
213
+ * @typeparam T The return type of func.
214
+ * @param func The function to be executed.
215
+ * @return A promise that gets resolved with the return value of the function.
216
+ */
217
+ execute<T>(func: () => T | PromiseLike<T>): Promise<T>;
218
+ }
219
+
220
+ declare class Endpoint<T extends Endpoint<T>> {
221
+ protected _options: Options;
186
222
  private _token;
187
223
  private _expire_token_time;
224
+ protected _client: HttpClient | null;
225
+ private _statusRetryHandlers;
226
+ protected _limit: Semaphore;
227
+ private _state;
228
+ private _stateChangeHandler;
229
+ protected _logger: Logger;
230
+ protected readonly _requestLogger: Logger;
231
+ constructor(options: Options);
232
+ protected setStatusRetryHandlers(statusRetryHandlers?: Map<number, Function> | undefined): void;
233
+ eyepopUrl(): string;
234
+ pendingJobs(): number;
235
+ state(): EndpointState;
236
+ onStateChanged(handler: (fromState: EndpointState, toState: EndpointState) => void): T;
237
+ protected updateState(newState?: EndpointState | undefined): void;
238
+ connect(): Promise<T>;
239
+ disconnect(wait?: boolean): Promise<void>;
240
+ session(): Promise<Session>;
241
+ protected statusHandler401(statusCode: number): void;
242
+ protected fetchWithRetry(fetcher: () => Promise<Response>, retries?: number): Promise<Response>;
243
+ protected reconnect(): Promise<T>;
244
+ protected authorizationHeader(): Promise<string>;
245
+ private currentAccessToken;
246
+ }
247
+
248
+ declare enum TransientPopId {
249
+ Transient = "transient"
250
+ }
251
+ interface WorkerOptions extends Options {
252
+ /**
253
+ * Defaults to process.env['EYEPOP_POP_ID'].
254
+ */
255
+ popId?: string | TransientPopId | undefined;
256
+ isSandbox?: boolean;
257
+ autoStart?: boolean;
258
+ stopJobs?: boolean;
259
+ }
260
+
261
+ interface WorkerSession extends Session {
262
+ readonly popId: string;
263
+ readonly baseUrl: string | undefined;
264
+ readonly pipelineId: string | undefined;
265
+ readonly sandboxId: string | undefined;
266
+ }
267
+ interface LiveMedia {
268
+ ingressId(): string;
269
+ stream(): Promise<MediaStream>;
270
+ close(): Promise<void>;
271
+ }
272
+ interface IngressEvent {
273
+ readonly ingressId: string;
274
+ readonly event: "stream-ready" | "stream-ready";
275
+ }
276
+ interface FileSource {
277
+ readonly file: File;
278
+ }
279
+ interface StreamSource {
280
+ readonly stream: ReadableStream<Uint8Array>;
281
+ readonly mimeType: string;
282
+ }
283
+ interface PathSource {
284
+ readonly path: string;
285
+ }
286
+ interface LiveSource {
287
+ readonly ingressId: string;
288
+ }
289
+ interface UrlSource {
290
+ readonly url: string;
291
+ }
292
+ type Source = FileSource | StreamSource | PathSource | LiveSource | UrlSource;
293
+ interface ResultStream extends AsyncIterable<Prediction> {
294
+ cancel(): void;
295
+ }
296
+ type SourcesEntry = {
297
+ readonly authority: string;
298
+ readonly manifest: string;
299
+ };
300
+ declare enum ModelFormat {
301
+ TensorFlowLite = "TensorFlowLite",
302
+ TensorFlowGraphDef = "TensorFlowGraphDef",
303
+ ONNX = "ONNX",
304
+ TorchScript = "TorchScript",
305
+ TorchScriptCpu = "TorchScriptCpu",
306
+ TorchScriptCuda = "TorchScriptCuda"
307
+ }
308
+ declare enum ModelPrecisionType {
309
+ float32 = "float32",
310
+ float16 = "float16",
311
+ int32 = "int32",
312
+ int8 = "int8",
313
+ uint8 = "uint8"
314
+ }
315
+ interface ModelInstanceDef {
316
+ id?: string;
317
+ model_id: string;
318
+ dataset: string;
319
+ version: string | undefined;
320
+ format: ModelFormat;
321
+ type: ModelPrecisionType;
322
+ }
323
+
324
+ declare class WorkerEndpoint extends Endpoint<WorkerEndpoint> {
188
325
  private _baseUrl;
189
326
  private _pipelineId;
190
327
  private _sandboxId;
191
328
  private _popName;
192
329
  private _pipeline;
193
- private _client;
194
- private _limit;
195
- private _state;
196
- private _stateChangeHandler;
197
330
  private _ingressEventHandler;
198
331
  private _ingressEventWs;
199
- private _logger;
200
- private readonly _requestLogger;
201
- constructor(options: Options);
202
- eyepopUrl(): string;
203
- state(): EndpointState;
204
- pendingJobs(): number;
332
+ constructor(options: WorkerOptions);
333
+ private options;
334
+ disconnect(wait?: boolean): Promise<void>;
335
+ protected statusHandler404(statusCode: number): void;
336
+ session(): Promise<WorkerSession>;
205
337
  popName(): string | null;
206
338
  popComp(): string | null;
207
339
  postTransform(): string | null;
208
340
  changePopComp(popComp: string): Promise<void>;
209
341
  changePostTransform(postTransform: string | null): Promise<void>;
210
342
  popId(): string | null;
211
- onStateChanged(handler: (fromState: EndpointState, toState: EndpointState) => void): Endpoint;
212
- onIngressEvent(handler: (event: IngressEvent) => void): Endpoint;
213
- connect(): Promise<Endpoint>;
214
- disconnect(wait?: boolean): Promise<void>;
215
- session(): Promise<SessionPlus>;
343
+ onIngressEvent(handler: (event: IngressEvent) => void): WorkerEndpoint;
216
344
  liveIngress(stream: MediaStream): Promise<LiveMedia>;
217
345
  liveEgress(ingressId: string): Promise<LiveMedia>;
218
346
  process(source: Source, params?: SourceParams | undefined): Promise<ResultStream>;
@@ -223,17 +351,208 @@ declare class Endpoint {
223
351
  private loadFrom;
224
352
  private loadLiveIngress;
225
353
  private jobDone;
226
- private updateState;
227
354
  private jobStatus;
228
- private fetchWithRetry;
229
- private reconnect;
230
- private authorizationHeader;
231
- private currentAccessToken;
355
+ protected reconnect(): Promise<WorkerEndpoint>;
232
356
  private startPopLessPipeline;
357
+ manifest(): Promise<SourcesEntry[]>;
358
+ models(): Promise<ModelInstanceDef[]>;
359
+ changeManifest(manifests: SourcesEntry[]): Promise<void>;
360
+ loadModel(model: ModelInstanceDef): Promise<ModelInstanceDef>;
361
+ unloadModel(modelId: string): Promise<void>;
362
+ }
363
+
364
+ interface DataOptions extends Options {
365
+ /**
366
+ * Defaults to process.env['EYEPOP_ACCOUNT_ID'].
367
+ */
368
+ accountId?: string | undefined;
369
+ disableWs?: boolean | undefined;
370
+ }
371
+
372
+ interface DataSession extends Session {
373
+ readonly accountId: string;
374
+ readonly baseUrl: string | undefined;
375
+ }
376
+ interface DatasetVersion {
377
+ version: number;
378
+ modifiable: boolean;
379
+ created_at: Date;
380
+ updated_at: Date;
381
+ asset_count: number;
382
+ }
383
+ interface Dataset {
384
+ uuid: string;
385
+ name: string;
386
+ description?: string;
387
+ auto_annotates: string[];
388
+ tags: string[];
389
+ account_uuid: string;
390
+ created_at: Date;
391
+ updated_at: Date;
392
+ versions: DatasetVersion[];
393
+ }
394
+ interface DatasetCreate {
395
+ name: string;
396
+ description?: string;
397
+ tags?: string[];
398
+ auto_annotates?: string[];
399
+ }
400
+ interface DatasetUpdate {
401
+ name: string;
402
+ description?: string;
403
+ tags?: string[];
404
+ auto_annotates?: string[];
405
+ }
406
+ declare enum AssetStatus {
407
+ rejected = "rejected",
408
+ upload_in_progress = "upload_in_progress",
409
+ upload_failed = "upload_failed",
410
+ transform_failed = "transform_failed",
411
+ transform_in_progress = "transform_in_progress",
412
+ accepted = "accepted"
413
+ }
414
+ declare enum AnnotationType {
415
+ manual = "manual",
416
+ prediction = "prediction",
417
+ auto = "auto"
418
+ }
419
+ declare enum UserReview {
420
+ approved = "approved",
421
+ rejected = "rejected",
422
+ unknown = "unknown"
423
+ }
424
+ interface Annotation {
425
+ type: AnnotationType;
426
+ user_review: UserReview;
427
+ auto_annotate?: string;
428
+ uncertainty_score?: number;
429
+ annotation: Prediction;
430
+ }
431
+ declare enum TranscodeMode {
432
+ original = "original",
433
+ image_original_size = "image_original_size",
434
+ image_fit_1024 = "image_fit_1024",
435
+ image_fit_640 = "image_fit_640",
436
+ image_fit_224 = "image_fit_224",
437
+ image_cover_1024 = "image_cover_1024",
438
+ image_cover_640 = "image_cover_640",
439
+ image_cover_224 = "image_cover_224"
440
+ }
441
+ interface Asset {
442
+ uuid: string;
443
+ mime_type: string;
444
+ file_size_bytes: number;
445
+ status: AssetStatus;
446
+ created_at: Date;
447
+ updated_at: Date;
448
+ annotations: Annotation[];
449
+ }
450
+ declare enum ModelType {
451
+ epdet_b1 = "epdet_b1"
452
+ }
453
+ declare enum ModelStatus {
454
+ error = "error",
455
+ draft = "draft",
456
+ requested = "requested",
457
+ in_progress = "in_progress",
458
+ available = "available",
459
+ published = "published"
460
+ }
461
+ interface Model {
462
+ uuid: string;
463
+ name: string;
464
+ description?: string;
465
+ type: ModelType;
466
+ status: ModelStatus;
467
+ account_uuid: string;
468
+ created_at: Date;
469
+ updated_at: Date;
470
+ dataset_uuid: string;
471
+ dataset_version: number;
472
+ }
473
+ interface ModelCreate {
474
+ name: string;
475
+ description?: string;
476
+ type: ModelType;
477
+ }
478
+ interface ModelUpdate {
479
+ name: string;
480
+ description?: string;
481
+ }
482
+ declare enum ChangeType {
483
+ dataset_added = "dataset_added",
484
+ dataset_removed = "dataset_removed",
485
+ dataset_modified = "dataset_modified",
486
+ dataset_version_modified = "dataset_version_modified",
487
+ asset_added = "asset_added",
488
+ asset_removed = "asset_removed",
489
+ asset_status_modified = "asset_status_modified",
490
+ asset_annotation_modified = "asset_annotation_modified",
491
+ model_added = "model_added",
492
+ model_removed = "model_removed",
493
+ model_modified = "model_modified",
494
+ model_status_modified = "model_status_modified"
495
+ }
496
+ interface ChangeEvent {
497
+ change_type: ChangeType;
498
+ account_uuid: string;
499
+ dataset_uuid: string;
500
+ dataset_version?: number;
501
+ asset_uuid?: string;
502
+ mdl_uuid?: string;
503
+ }
504
+ type OnChangeEvent = (event: ChangeEvent) => Promise<void>;
505
+
506
+ declare class DataEndpoint extends Endpoint<DataEndpoint> {
507
+ private _baseUrl;
508
+ private _accountId;
509
+ private _ws;
510
+ private _ws_current_reconnect_delay;
511
+ private _account_event_handlers;
512
+ private _dataset_uuid_to_event_handlers;
513
+ constructor(options: DataOptions);
514
+ session(): Promise<DataSession>;
515
+ disconnect(wait?: boolean): Promise<void>;
516
+ protected reconnect(): Promise<DataEndpoint>;
517
+ private reconnect_ws;
518
+ private options;
519
+ private request;
520
+ listDatasets(): Promise<any>;
521
+ createDataset(data: DatasetCreate): Promise<Dataset>;
522
+ getDataset(dataset_uuid: string): Promise<Dataset>;
523
+ updateDataset(dataset_uuid: string, data: DatasetUpdate): Promise<Dataset>;
524
+ deleteDataset(dataset_uuid: string): Promise<void>;
525
+ freezeDatasetVersion(dataset_uuid: string, dataset_version?: number): Promise<Dataset>;
526
+ deleteDatasetVersion(dataset_uuid: string, dataset_version: number): Promise<Dataset>;
527
+ uploadAsset(dataset_uuid: string, dataset_version: number | undefined, blob: Blob): Promise<Asset>;
528
+ listAssets(dataset_uuid: string, dataset_version?: number, include_annotations?: boolean): Promise<Asset[]>;
529
+ getAsset(asset_uuid: string, dataset_uuid?: string, dataset_version?: number, include_annotations?: boolean): Promise<Asset>;
530
+ deleteAsset(asset_uuid: string, dataset_uuid?: string, dataset_version?: number): Promise<void>;
531
+ resurrectAsset(asset_uuid: string, dataset_uuid: string, from_dataset_version: number, into_dataset_version?: number): Promise<void>;
532
+ updateAssetManualAnnotation(asset_uuid: string, dataset_uuid?: string, dataset_version?: number, prediction?: Prediction$1): Promise<void>;
533
+ updateAutoAnnotationStatus(asset_uuid: string, auto_annotate: string, user_review: UserReview): Promise<void>;
534
+ downloadAsset(asset_uuid: string, dataset_uuid?: string, dataset_version?: number, transcode_mode?: TranscodeMode): Promise<Blob>;
535
+ listModels(): Promise<Model[]>;
536
+ createModel(dataset_uuid: string, dataset_version: number, data: ModelCreate): Promise<Model>;
537
+ getModel(model_uuid: string): Promise<Model>;
538
+ updateModel(model_uuid: string, data: ModelUpdate): Promise<Model>;
539
+ deleteModel(model_uuid: string): Promise<void>;
540
+ publishModel(model_uuid: string): Promise<Model>;
541
+ addAccountEventHandler(eventHandler: OnChangeEvent): void;
542
+ removeAccountEventHandler(eventHandler: OnChangeEvent): void;
543
+ addDatasetEventHandler(dataset_uuid: string, eventHandler: OnChangeEvent): void;
544
+ removeDatasetEventHandler(dataset_uuid: string, eventHandler: OnChangeEvent): void;
545
+ removeAllDatasetEventHandlers(dataset_uuid: string): void;
546
+ private dispatchChangeEvent;
233
547
  }
234
548
 
235
549
  declare namespace EyePop {
236
- function endpoint(opts?: Options): Endpoint;
550
+ /**
551
+ * @deprecated use workerEndpoint() instead
552
+ */
553
+ const endpoint: typeof workerEndpoint;
554
+ function workerEndpoint(opts?: WorkerOptions): WorkerEndpoint;
555
+ function dataEndpoint(opts?: DataOptions): DataEndpoint;
237
556
  }
238
557
 
239
- export { type Contour, EndpointState, EyePop, type FileSource, type IngressEvent, type LiveMedia, type LiveSource, type PathSource, type Point2d, type Point3d, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type Session, type Source, type StreamSource, type StreamTime, type UrlSource, EyePop as default };
558
+ export { type Annotation, AnnotationType, type Asset, AssetStatus, type Auth0Options, type Authentication, type ChangeEvent, ChangeType, type Contour, DataEndpoint, type DataOptions, type DataSession, type Dataset, type DatasetCreate, type DatasetUpdate, type DatasetVersion, EndpointState, EyePop, type FileSource, type IngressEvent, type LiveMedia, type LiveSource, type Model, type ModelCreate, ModelFormat, type ModelInstanceDef, ModelPrecisionType, ModelStatus, ModelType, type ModelUpdate, type OAuth2Auth, type OnChangeEvent, type Options, type PathSource, type Point2d, type Point3d, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type SecretKeyAuth, type Session, type SessionAuth, type Source, type SourcesEntry, type StreamSource, type StreamTime, TranscodeMode, TransientPopId, type UrlSource, UserReview, WorkerEndpoint, type WorkerOptions, type WorkerSession, EyePop as default };