Building a python source connector, Added it to airbyte GUI, setup source & destination is successful but failed to fetch schema
Ref:
import json
from datetime import datetime
from typing import Dict, Generator
from airbyte_cdk.logger import AirbyteLogger
from airbyte_cdk.models import (
AirbyteCatalog,
AirbyteConnectionStatus,
AirbyteMessage,
AirbyteRecordMessage,
AirbyteStream,
ConfiguredAirbyteCatalog,
Status,
Type,
)
from airbyte_cdk.sources import Source
from . import weather_list
class SourcePython(Source):
url_base = "https://weatherapi-com.p.rapidapi.com/"
def check(self, logger: AirbyteLogger, config: json) -> AirbyteConnectionStatus:
try:
input_list = config["q"]
return AirbyteConnectionStatus(status=Status.SUCCEEDED)
except Exception as e:
return AirbyteConnectionStatus(status=Status.FAILED, message=f"An exception occurred: {str(e)}")
def discover(self, logger: AirbyteLogger, config: json) -> AirbyteCatalog:
streams = []
stream_name = "sports" # Example
json_schema = { # Example
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"football": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
}
]
},
"cricket": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
},
{
"type": "object",
"properties": {
"stadium": {
"type": "string"
},
"country": {
"type": "string"
},
"region": {
"type": "string"
},
"tournament": {
"type": "string"
},
"start": {
"type": "string"
},
"match": {
"type": "string"
}
},
"required": [
"stadium",
"country",
"region",
"tournament",
"start",
"match"
]
}
]
},
"golf": {
"type": "array",
"items": {}
}
},
}
streams.append(AirbyteStream(name=stream_name, json_schema=json_schema))
return AirbyteCatalog(streams=streams)
def read(
self, logger: AirbyteLogger, config: json, catalog: ConfiguredAirbyteCatalog, state: Dict[str, any]
) -> Generator[AirbyteMessage, None, None]:
stream_name = "sports" # Example
data = {"columnName": "football"} # Example
yield AirbyteMessage(
type=Type.RECORD,
record=AirbyteRecordMessage(stream=stream_name, data=data, emitted_at=int(datetime.now().timestamp()) * 1000),
)
class sports(SourcePython):
# Set this as a noop.
primary_key = None
def path(self, **kwargs) -> str:
weather_list = self.weather_list
return f"/sports.json?q={weather_list}&rapidapi-key=***************"