-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate connector builder api client #18274
Changes from all commits
28cccb2
2366d0b
8c5ed50
2512bdd
5635349
9d6a8fe
4ae298a
2599eda
6ab3272
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { | ||
StreamRead, | ||
StreamReadRequestBody, | ||
StreamsListRead, | ||
StreamsListRequestBody, | ||
} from "core/request/ConnectorBuilderClient"; | ||
|
||
import { AirbyteRequestService } from "../../request/AirbyteRequestService"; | ||
|
||
export class ConnectorBuilderRequestService extends AirbyteRequestService { | ||
public readStream(readParams: StreamReadRequestBody): Promise<StreamRead> { | ||
// TODO: uncomment this and remove mock responses once there is a real API to call | ||
// return readStream(readParams, this.requestOptions); | ||
console.log("------------"); | ||
console.log(`Stream: ${readParams.stream}`); | ||
console.log(`Connector manifest:\n${JSON.stringify(readParams.manifest)}`); | ||
console.log(`Config:\n${JSON.stringify(readParams.config)}`); | ||
return new Promise((resolve) => setTimeout(resolve, 200)).then(() => { | ||
return { | ||
logs: [ | ||
{ level: "INFO", message: "Syncing stream: rates " }, | ||
{ level: "INFO", message: "Setting state of rates stream to {'date': '2022-09-25'}" }, | ||
], | ||
slices: [ | ||
{ | ||
sliceDescriptor: { start: "Jan 1, 2022", end: "Jan 2, 2022" }, | ||
state: { | ||
type: "STREAM", | ||
stream: { stream_descriptor: { name: readParams.stream }, stream_state: { date: "2022-09-26" } }, | ||
data: { rates: { date: "2022-09-26" } }, | ||
}, | ||
pages: [ | ||
{ | ||
records: [ | ||
{ | ||
stream: readParams.stream, | ||
data: { | ||
id: "dp_123", | ||
object: readParams.stream, | ||
amount: 2000, | ||
balance_transaction: "txn_123", | ||
}, | ||
}, | ||
], | ||
request: { | ||
url: "https://api.com/path", | ||
}, | ||
response: { | ||
status: 200, | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
}); | ||
} | ||
|
||
public listStreams(listParams: StreamsListRequestBody): Promise<StreamsListRead> { | ||
// TODO: uncomment this and remove mock responses once there is a real API to call | ||
// return listStreams(listParams, this.requestOptions); | ||
console.log(`Received listStreams body: ${JSON.stringify(listParams)}`); | ||
return new Promise((resolve) => setTimeout(resolve, 200)).then(() => { | ||
return { | ||
streams: [ | ||
{ | ||
name: "disputes", | ||
url: "https://api.com/disputes", | ||
}, | ||
{ | ||
name: "transactions", | ||
url: "https://api.com/transactions", | ||
}, | ||
{ | ||
name: "users", | ||
url: "https://api.com/users", | ||
}, | ||
], | ||
}; | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { useQuery } from "react-query"; | ||
|
||
import { useConfig } from "config"; | ||
import { ConnectorBuilderRequestService } from "core/domain/connectorBuilder/ConnectorBuilderRequestService"; | ||
import { | ||
StreamReadRequestBody, | ||
StreamReadRequestBodyConfig, | ||
StreamReadRequestBodyManifest, | ||
StreamsListRequestBody, | ||
} from "core/request/ConnectorBuilderClient"; | ||
import { useSuspenseQuery } from "services/connector/useSuspenseQuery"; | ||
import { useDefaultRequestMiddlewares } from "services/useDefaultRequestMiddlewares"; | ||
import { useInitService } from "services/useInitService"; | ||
|
||
const connectorBuilderKeys = { | ||
all: ["connectorBuilder"] as const, | ||
read: (streamName: string, manifest: StreamReadRequestBodyManifest, config: StreamReadRequestBodyConfig) => | ||
[...connectorBuilderKeys.all, "read", { streamName, manifest, config }] as const, | ||
list: (manifest: StreamReadRequestBodyManifest) => [...connectorBuilderKeys.all, "list", { manifest }] as const, | ||
}; | ||
|
||
function useConnectorBuilderService() { | ||
const config = useConfig(); | ||
const middlewares = useDefaultRequestMiddlewares(); | ||
return useInitService( | ||
() => new ConnectorBuilderRequestService(config.connectorBuilderApiUrl, middlewares), | ||
[config.connectorBuilderApiUrl, middlewares] | ||
); | ||
} | ||
|
||
export const useReadStream = (params: StreamReadRequestBody) => { | ||
const service = useConnectorBuilderService(); | ||
|
||
return useQuery( | ||
connectorBuilderKeys.read(params.stream, params.manifest, params.config), | ||
() => service.readStream(params), | ||
{ refetchOnWindowFocus: false, enabled: false } | ||
); | ||
}; | ||
|
||
export const useListStreams = (params: StreamsListRequestBody) => { | ||
const service = useConnectorBuilderService(); | ||
|
||
return useSuspenseQuery(connectorBuilderKeys.list(params.manifest), () => service.listStreams(params)); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ paths: | |
/v1/stream/read: | ||
post: | ||
summary: Reads a specific stream in the source. TODO in a later phase - only read a single slice of data. | ||
operationId: readStream | ||
requestBody: | ||
content: | ||
application/json: | ||
|
@@ -37,7 +38,8 @@ paths: | |
$ref: "#/components/responses/InvalidInputResponse" | ||
/v1/streams/list: | ||
post: | ||
summary: List all streams present in the connector definition, along with their specific request URLs | ||
summary: List all streams present in the connector manifest, along with their specific request URLs | ||
operationId: listStreams | ||
requestBody: | ||
content: | ||
application/json: | ||
|
@@ -61,53 +63,71 @@ components: | |
StreamRead: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @girarda @brianjlai @sherifnada The reasoning behind this is mainly coming from not being able to pull in the AirbyteProtocol struct into this openAPI spec, so we will need the connector-builder-server to filter out the various types of AirbyteMessages into separate fields like this so that the frontend knows what to do with them. I pulled I also pulled There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with moving the state to the slice-level. No strong opinion on whether the the logs should be at the page-level or global. I think global is fine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also seems fine to me. We sometimes have to deal w/ consecutive state messages (or the case where slices have no records) so maybe this approach works better anyway so the underlying python server can obfuscate the complexity of formatting what some of these outputs might look like |
||
type: object | ||
required: | ||
- logs | ||
- slices | ||
properties: | ||
logs: | ||
type: array | ||
description: The LOG AirbyteMessages that were emitted during the read of this slice | ||
items: | ||
type: object | ||
# $ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteLogMessage" | ||
slices: | ||
type: array | ||
description: The stream slices returned from the read command | ||
description: The stream slices returned from the read command. If no stream slicer is configured, this should contain a single item containing all of the results. | ||
items: | ||
type: object | ||
required: | ||
- sliceDescriptor | ||
- pages | ||
properties: | ||
sliceDescriptor: | ||
type: object | ||
description: 'An object describing the current slice, e.g. {start_time: "2021-01-01", end_time: "2021-01-31"}' | ||
pages: | ||
type: array | ||
description: The pages returned from the read command | ||
description: The pages returned from the read command. If no pagination is configured, this should contain a single item containing all of the results. | ||
items: | ||
type: object | ||
required: | ||
- airbyteMessages | ||
- records | ||
- request | ||
- response | ||
properties: | ||
airbyteMessages: | ||
records: | ||
type: array | ||
description: The RECORD/STATE/LOG AirbyteMessages coming from the read operation for this page | ||
description: The RECORD AirbyteMessages coming from the read operation for this page | ||
items: | ||
$ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteMessage" | ||
type: object | ||
# $ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteRecordMessage" | ||
request: | ||
$ref: "#/components/schemas/HttpRequest" | ||
response: | ||
$ref: "#/components/schemas/HttpResponse" | ||
sliceDescriptor: | ||
type: object | ||
description: 'An object describing the current slice, e.g. {start_time: "2021-01-01", end_time: "2021-01-31"}. This can be omitted if a stream slicer is not configured.' | ||
state: | ||
type: object | ||
description: The STATE AirbyteMessage emitted at the end of this slice. This can be omitted if a stream slicer is not configured. | ||
# $ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteStateMessage" | ||
StreamReadRequestBody: | ||
type: object | ||
required: | ||
- definition | ||
- manifest | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are several changes in this spec to rename "connector definition" to "manifest", following this decision made in slack: https://airbytehq-team.slack.com/archives/C03TP6W8081/p1666214768391589 |
||
- stream | ||
- config | ||
properties: | ||
definition: | ||
$ref: "#/components/schemas/ConnectorDefinitionBody" | ||
description: The config-based connector definition contents | ||
manifest: | ||
type: object | ||
description: The config-based connector manifest contents | ||
# $ref: "#/components/schemas/ConnectorManifest" | ||
stream: | ||
type: string | ||
description: Name of the stream to read | ||
config: | ||
type: object | ||
description: The config blob containing the user inputs for testing | ||
Comment on lines
+124
to
+126
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realized that this was missing from the |
||
state: | ||
$ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteStateMessage" | ||
type: object | ||
description: The AirbyteStateMessage object to use as the starting state for this read | ||
# $ref: "#/components/schemas/AirbyteProtocol/definitions/AirbyteStateMessage" | ||
# --- Potential addition for a later phase --- | ||
# numPages: | ||
# type: integer | ||
|
@@ -144,18 +164,20 @@ components: | |
headers: | ||
type: object | ||
description: The headers of the HTTP response, if any | ||
ConnectorDefinitionBody: | ||
$ref: ../../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/config_component_schema.json | ||
AirbyteProtocol: | ||
$ref: ../../../../airbyte-protocol/protocol-models/src/main/resources/airbyte_protocol/airbyte_protocol.yaml | ||
# --- Commenting out for now since they do not work with our orval openapi client generator --- | ||
# ConnectorManifest: | ||
# $ref: ../../../../airbyte-cdk/python/airbyte_cdk/sources/declarative/config_component_schema.json | ||
# AirbyteProtocol: | ||
# $ref: ../../../../airbyte-protocol/protocol-models/src/main/resources/airbyte_protocol/airbyte_protocol.yaml | ||
StreamsListRequestBody: | ||
type: object | ||
required: | ||
- definition | ||
- manifest | ||
properties: | ||
definition: | ||
$ref: "#/components/schemas/ConnectorDefinitionBody" | ||
description: The config-based connector definition contents | ||
manifest: | ||
type: object | ||
description: The config-based connector manifest contents | ||
# $ref: "#/components/schemas/ConnectorManifest" | ||
StreamsListRead: | ||
type: object | ||
required: | ||
|
@@ -165,7 +187,7 @@ components: | |
type: array | ||
items: | ||
type: object | ||
description: The stream names present in the connector definition | ||
description: The stream names present in the connector manifest | ||
required: | ||
- name | ||
- url | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
8080 seems like a very common port
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to change it to whatever port we think is appropriate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use 8003, since it seems like that is not currently used by anything else in OSS or Cloud (8001 is used by airbyte-server, and 8002 is used by the airyte-cloud-server in Cloud)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way, I'm just going to commit this as is for now, since we can easily change this later