Skip to content

Commit

Permalink
refactor(js-api-clients): move js-api-clients to the opentrons repo (#…
Browse files Browse the repository at this point in the history
…8515)

* refactor(js-api-clients): move js-api-clients to the opentrons repo

closes #8497

Co-authored-by: Shlok Amin <[email protected]>
Co-authored-by: Brian Cooper <[email protected]>
  • Loading branch information
3 people committed Oct 14, 2021
1 parent 8ab549e commit c67eb8b
Show file tree
Hide file tree
Showing 49 changed files with 1,687 additions and 19 deletions.
62 changes: 62 additions & 0 deletions .github/workflows/react-api-client-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Run tests, build components bundle, and deploy it to sandbox

name: 'JS API Clients test'

on:
pull_request:
paths:
- 'react-api-client/**'
- 'api-client/**'
- 'package.json'
- '.github/workflows/react-api-client-test.yaml'
push:
paths:
- 'react-api-client/**'
- 'api-client/**'
- 'package.json'
- '.github/workflows/react-api-client-test.yaml'
branches:
- '*'
workflow_dispatch:

defaults:
run:
shell: bash

env:
CI: true

jobs:
js-unit-test:
name: 'react-api-client unit tests'
timeout-minutes: 30
runs-on: 'ubuntu-18.04'
steps:
- uses: 'actions/checkout@v2'
- uses: 'actions/setup-node@v1'
with:
node-version: '14'
- name: 'install libudev for usb-detection'
run: sudo apt-get update && sudo apt-get install libudev-dev
- name: 'cache yarn cache'
uses: actions/cache@v2
with:
path: |
${{ github.workspace }}/.yarn-cache
${{ github.workspace }}/.npm-cache
key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
- name: 'setup-js'
run: |
npm config set cache ./.npm-cache
yarn config set cache-folder ./.yarn-cache
make setup-js
- name: 'run react-api-client unit tests'
run: |
yarn jest --coverage=true --ci=true --collectCoverageFrom="react-api-client/src/**/*.(js|ts|tsx)" react-api-client/src
- name: 'Upload coverage report'
uses: codecov/codecov-action@v2
with:
files: ./coverage/lcov.info
flags: react-api-client
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,7 @@ shared-data/python/pyproject.toml

# Static storybook build artifacts
storybook-static/

# api client type caches
api-client/lib
react-api-client/lib
19 changes: 19 additions & 0 deletions api-client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# opentrons api-client makefile

# using bash instead of /bin/bash in SHELL prevents macOS optimizing away our PATH update
# TODO(mc, 2021-02-12): this may be unnecessary by using `yarn run` instead
SHELL := bash

# standard targets
#####################################################################

.PHONY: all
all: clean build

.PHONY: clean
clean:
tsc --build --clean && yarn shx rm -rf \"dist\"

.PHONY: build
build:
rollup --config rollup.config.js
31 changes: 31 additions & 0 deletions api-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Opentrons HTTP API Client

Opentrons robot HTTP API client for Node.js and browsers. Compatible with [Opentrons robot software][] `v4` and later.

[opentrons robot software]: https://github.com/Opentrons/opentrons

## Getting Started

### Installation

```shell
npm install @opentrons/api-client
```

### Usage

```typescript
import { HostConfig, Response, Health, getHealth } from '@opentrons/api-client'

const host: HostConfig = { hostname: 'OT2CEP9999999A99.local' }

getHealth(host)
.then((response: Response<Health>) => console.log(response.data))
.catch(error => console.error(error))
```

## Details

The `@opentrons/api-client` module is built using [axios][].

[axios]: https://github.com/axios/axios
19 changes: 19 additions & 0 deletions api-client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"private": true,
"name": "@opentrons/api-client",
"description": "Opentrons robot API client for Node.js and the browser",
"version": "0.0.0",
"license": "Apache-2.0",
"main": "dist/api-client.js",
"module": "dist/api-client.mjs",
"types": "lib/index.d.ts",
"source": "src/index.ts",
"browser": {
"./dist/api-client.js": "./dist/api-client.browser.js",
"./dist/api-client.mjs": "./dist/api-client.browser.mjs"
},
"dependencies": {
"axios": "^0.21.1",
"react-query": "3.12.0"
}
}
9 changes: 9 additions & 0 deletions api-client/src/health/getHealth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { GET, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { Health } from './types'

export function getHealth(config: HostConfig): ResponsePromise<Health> {
return request<Health>(GET, '/health', null, config)
}
2 changes: 2 additions & 0 deletions api-client/src/health/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { getHealth } from './getHealth'
export type { Health, HealthLinks } from './types'
19 changes: 19 additions & 0 deletions api-client/src/health/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export interface Health {
name: string
api_version: string
fw_version: string
board_revision: string
logs: string[]
system_version: string
maximum_protocol_api_version: [major: number, minor: number]
minimum_protocol_api_version: [major: number, minor: number]
links: HealthLinks
}

export interface HealthLinks {
apiLog: string
serialLog: string
serverLog: string
apiSpec: string
systemTime: string
}
5 changes: 5 additions & 0 deletions api-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// api client entry point
export type { HostConfig } from './types'
export * from './request'
export * from './health'
export * from './sessions'
32 changes: 32 additions & 0 deletions api-client/src/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import axios, { AxiosRequestConfig } from 'axios'

import type { Method, AxiosPromise, AxiosResponse } from 'axios'
import type { HostConfig } from './types'

export type ResponsePromise<Data> = AxiosPromise<Data>

export type Response<Data> = AxiosResponse<Data>

export const DEFAULT_PORT = 31950

export const DEFAULT_HEADERS = {
'Opentrons-Version': '*',
}

export const GET = 'GET'
export const POST = 'POST'
export const DELETE = 'DELETE'

export function request<ResData, ReqData = null>(
method: Method,
url: string,
data: ReqData,
config: HostConfig,
params?: AxiosRequestConfig['params']
): ResponsePromise<ResData> {
const { hostname, port } = config
const headers = { ...DEFAULT_HEADERS }
const baseURL = `http:https://${hostname}:${port ?? DEFAULT_PORT}`

return axios.request({ headers, method, baseURL, url, data, params })
}
21 changes: 21 additions & 0 deletions api-client/src/sessions/createSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { POST, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { Session } from './types'
import { SessionType } from '.'

export interface CreateSessionData {
sessionType: SessionType
createParams?: Record<string, unknown>
}

export function createSession(
config: HostConfig,
data?: CreateSessionData
): ResponsePromise<Session> {
return request<
Session,
{ data: { sessionType: SessionType; createParams?: unknown } | undefined }
>(POST, '/sessions', { data }, config)
}
12 changes: 12 additions & 0 deletions api-client/src/sessions/deleteSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DELETE, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { Session } from './types'

export function deleteSession(
config: HostConfig,
sessionId: string
): ResponsePromise<Session> {
return request<Session>(DELETE, `/sessions/${sessionId}`, null, config)
}
12 changes: 12 additions & 0 deletions api-client/src/sessions/getSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GET, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { Session } from './types'

export function getSession(
config: HostConfig,
sessionId: string
): ResponsePromise<Session> {
return request<Session>(GET, `/sessions/${sessionId}`, null, config)
}
12 changes: 12 additions & 0 deletions api-client/src/sessions/getSessions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { GET, request } from '../request'

import type { ResponsePromise } from '../request'
import type { HostConfig } from '../types'
import type { Sessions, SessionType } from './types'

export function getSessions(
config: HostConfig,
params?: { session_type: SessionType }
): ResponsePromise<Sessions> {
return request<Sessions>(GET, `/sessions`, null, config, params)
}
7 changes: 7 additions & 0 deletions api-client/src/sessions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { getSession } from './getSession'
export { deleteSession } from './deleteSession'
export { createSession } from './createSession'
export { getSessions } from './getSessions'

export * from './types'
export type { CreateSessionData } from './createSession'
71 changes: 71 additions & 0 deletions api-client/src/sessions/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
export const SESSION_TYPE_CALIBRATION_HEALTH_CHECK: 'calibrationCheck' =
'calibrationCheck'
export const SESSION_TYPE_TIP_LENGTH_CALIBRATION: 'tipLengthCalibration' =
'tipLengthCalibration'
export const SESSION_TYPE_DECK_CALIBRATION: 'deckCalibration' =
'deckCalibration'
export const SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION: 'pipetteOffsetCalibration' =
'pipetteOffsetCalibration'

export const SESSION_TYPE_BASIC: 'basic' = 'basic'

export type SessionType =
| typeof SESSION_TYPE_CALIBRATION_HEALTH_CHECK
| typeof SESSION_TYPE_TIP_LENGTH_CALIBRATION
| typeof SESSION_TYPE_DECK_CALIBRATION
| typeof SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION
| typeof SESSION_TYPE_BASIC

interface CalibrationCheckSession {
id: string
sessionType: typeof SESSION_TYPE_CALIBRATION_HEALTH_CHECK
createParams: Record<string, unknown>
}

interface TipLengthCalibrationSession {
id: string
sessionType: typeof SESSION_TYPE_TIP_LENGTH_CALIBRATION
createParams: Record<string, unknown>
}

interface DeckCalibrationSession {
id: string
sessionType: typeof SESSION_TYPE_DECK_CALIBRATION
createParams: {}
}

interface PipetteOffsetCalibrationSession {
id: string
sessionType: typeof SESSION_TYPE_PIPETTE_OFFSET_CALIBRATION
createParams: Record<string, unknown>
}

interface BasicSession {
id: string
sessionType: typeof SESSION_TYPE_BASIC
createParams: Record<string, unknown>
}

export type SessionData =
| CalibrationCheckSession
| TipLengthCalibrationSession
| DeckCalibrationSession
| PipetteOffsetCalibrationSession
| BasicSession

interface ResourceLink {
href: string
meta?: Partial<{ [key: string]: string | null | undefined }>
}

type ResourceLinks = Record<string, ResourceLink | string | null | undefined>

export interface Session {
data: SessionData
links?: ResourceLinks
}

export interface Sessions {
data: SessionData[]
links?: ResourceLinks
}
4 changes: 4 additions & 0 deletions api-client/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface HostConfig {
hostname: string
port?: number | null
}
10 changes: 10 additions & 0 deletions api-client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../tsconfig-base.json",
"references": [],
"compilerOptions": {
"composite": true,
"rootDir": "src",
"outDir": "lib"
},
"include": ["src"]
}
10 changes: 9 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ module.exports = {
'^@opentrons/components$': `@opentrons/components/src/index.ts`,
'^@opentrons/shared-data$': `@opentrons/shared-data/js/index.ts`,
'^@opentrons/step-generation$': `@opentrons/step-generation/src/index.ts`,
'^@opentrons/api-client$': `@opentrons/api-client/src/index.ts`,
'^@opentrons/react-api-client$': `@opentrons/react-api-client/src/index.ts`,
},
},
],
Expand All @@ -58,7 +60,13 @@ module.exports = {
// apps that should be polyfilled
// these projects require `core-js` in their package.json `dependencies`
{
test: ['app/**/*', 'labware-library/**/*', 'protocol-designer/**/*'],
test: [
'app/**/*',
'labware-library/**/*',
'protocol-designer/**/*',
'react-api-client/**/*',
'api-client/**/*',
],
presets: [['@babel/preset-env', { useBuiltIns: 'usage', corejs: 3 }]],
},
],
Expand Down
Loading

0 comments on commit c67eb8b

Please sign in to comment.