Source setup failed

I am trying to build a connector, using LinkedIn API, which is an oauth2.0 authentication, connector build was successful, and added it to airbyte GUI, but while source setup test cases are failed and showed a 404 error, the given URL and credentials are correct
image

source.py file

from abc import ABC, abstractproperty
from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Tuple
from urllib.parse import urlencode

import requests
from airbyte_cdk import AirbyteLogger
from airbyte_cdk.models import SyncMode
from airbyte_cdk.sources import AbstractSource
from airbyte_cdk.sources.streams import Stream
from airbyte_cdk.sources.streams.http import HttpStream
from airbyte_cdk.sources.streams.http.auth import Oauth2Authenticator, TokenAuthenticator

Basic full refresh stream

class LinkedinStream(HttpStream, ABC):
# TODO: Fill in the url base. Required.

url_base = "https://api.linkedin.com/v2/"
primary_key = None
records_limit = 500

def __init__(self, config: Dict):
    super().__init__(authenticator=config.get("authenticator"))
    self.config = config

def request_params(
        self,
        stream_state: Mapping[str, Any],
        stream_slice: Mapping[str, Any] = None,
        next_page_token: Mapping[str, Any] = None,
) -> MutableMapping[str, Any]:
    # The api requires that we include the data as a query param so we do that in this method.
    return None

def parse_response(
        self,
        response: requests.Response,
        stream_state: Mapping[str, Any],
        stream_slice: Mapping[str, Any] = None,
        next_page_token: Mapping[str, Any] = None,
) -> Iterable[Mapping]:
    # The response is a simple JSON whose schema matches our stream's schema exactly,
    # so we just return a list containing the response.
    return [response.json()]

def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
    # While the API does offer pagination, we will only ever retrieve one parameter with this implementation,
    # so we just return None to indicate that there will never be any more pages in the response.
    return None

class details(LinkedinStream):
def path(self, **kwargs) → str:
# This defines the path to the endpoint that we want to hit.
return f"/me"

Source

class SourceLinkedin(AbstractSource):
“”"
Abstract Source inheritance, provides:
- implementation for check connector’s connectivity
- implementation to call each stream with it’s input parameters.
“”"

def get_authenticator(cls, config: Mapping[str, Any]) -> TokenAuthenticator:
    """
    Validate input parameters and generate a necessary Authentication object

    """
    auth_method = config.get("credentials", {}).get("auth_method")
    if auth_method == "oAuth2.0":
        return Oauth2Authenticator(
            token_refresh_endpoint="https://www.linkedin.com/oauth/v2/accessToken",
            client_id=config["credentials"]["client_id"],
            client_secret=config["credentials"]["client_secret"],
            refresh_token=config["credentials"]["refresh_token"],
        )
    raise Exception("incorrect input parameters")

def check_connection(self, logger: AirbyteLogger, config: Mapping[str, Any]) -> Tuple[bool, any]:
    config["authenticator"] = self.get_authenticator(config)
    stream = details(config)
    # need to load the first item only
    stream.records_limit = 1
    try:
        next(stream.read_records(sync_mode=SyncMode.full_refresh), None)
        return True, None
    except Exception as e:
        return False, e

def streams(self, config: Mapping[str, Any]) -> List[Stream]:
    """
    Mapping an input config of the user input configuration as defined in the connector spec.
    Passing config to the streams.
    """
    config["authenticator"] = self.get_authenticator(config)
    return [details(config),]

Hey was it running when you run using python as mentioned in the README. That way it is easy to debug. If you can run the command python main.py check --config secrets/config.json

and share the error here

python main.py check --config secrets/config.json
{“type”: “LOG”, “log”: {“level”: “ERROR”, “message”: “Check failed”}}
{“type”: “CONNECTION_STATUS”, “connectionStatus”: {“status”: “FAILED”, “message”: “Exception(‘incorrect input parameters’)”}}

Given parameters are correct…!

Yeah looks like it’s not working in python also can you try fixing this. You can start by checking check function

After making some changes it shows this error

python main.py check --config secrets/config.json
{“type”: “LOG”, “log”: {“level”: “FATAL”, “message”: “Expecting value: line 1 column 1 (char 0)\nTraceback (most recent call last):\n File “C:\Users\my-user\airbyte\airbyte-inte
grations\connectors\source-linkedin\main.py”, line 13, in \n launch(source, sys.argv[1:])\n File “C:\Users\my-user\airbyte\airbyte-integrations\connectors\sourc
e-linkedin\.venv\lib\site-packages\airbyte_cdk\entrypoint.py”, line 127, in launch\n for message in source_entrypoint.run(parsed_args):\n File “C:\Users\my-user\airbyte
\airbyte-integrations\connectors\source-linkedin\.venv\lib\site-packages\airbyte_cdk\entrypoint.py”, line 80, in run\n self.configure_sentry(source_spec.connectionSpecification
, parsed_args)\n File “C:\Users\my-user\airbyte\airbyte-integrations\connectors\source-linkedin\.venv\lib\site-packages\airbyte_cdk\entrypoint.py”, line 67, in configure
_sentry\n config = self.source.read_config(parsed_args.config)\n File “C:\Users\my-user\airbyte\airbyte-integrations\connectors\source-linkedin\.venv\lib\site-packages\
airbyte_cdk\connector.py”, line 53, in read_config\n return json.loads(contents)\n File “C:\python_3.9\lib\json\init.py”, line 346, in loads\n return _default_decoder.d
ecode(s)\n File “C:\python_3.9\lib\json\decoder.py”, line 337, in decode\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n File “C:\python_3.9\lib\json\decoder.py”, l
ine 355, in raw_decode\n raise JSONDecodeError(“Expecting value”, s, err.value) from None\njson.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)”}}

Hey, can you check the spec.json is a valid json

yes it was valid…! , Spec.json–>

{
“documentationUrl”: “https://docsurl.com”,
“connectionSpecification”: {
“$schema”: “http://json-schema.org/draft-07/schema#”,
“title”: “Linkedin Spec”,
“type”: “object”,
“additionalProperties”: true,
“properties”: {
“credentials”: {
“title”: “Authentication mechanism”,
“description”: “Choose how to authenticate into Linkedin Api”,
“type”: “object”,
“oneOf”: [
{
“type”: “object”,
“title”: “OAuth 2.0”,
“required”: [
“access_token”,
“client_id”,
“client_secret”,
“option_title”
],
“properties”: {
“option_title”: {
“type”: “string”,
“const”: “Default OAuth2.0 authorization”
},
“client_id”: {
“title”: “Client ID”,
“description”: “Linkedin client_id.”,
“type”: “string”,
“examples”: [“Linkedin-client-id-example”],
“airbyte_secret”: true
},
“client_secret”: {
“title”: “Client Secret”,
“description”: “Linkedin client_secret.”,
“type”: “string”,
“examples”: [“Linkedin-client-secret-example”],
“airbyte_secret”: true
},
“access_token”: {
“title”: “Access token”,
“description”: “Linkedin access_token.”,
“type”: “string”,
“examples”: [“Linkedin-access-token-example”],
“airbyte_secret”: true
}
},
“order”: 0
},
{
“type”: “object”,
“title”: “API Token”,
“required”: [“api_token”, “option_title”],
“properties”: {
“option_title”: {
“type”: “string”,
“const”: “API Token Credentials”
},
“api_token”: {
“type”: “string”,
“title”: “API Token”,
“description”: “A Linkedin bot token.”,
“airbyte_secret”: true
}
},
“order”: 1
}
]
}
}
},
“authSpecification”: {
“auth_type”: “oauth2.0”,
“oauth2Specification”: {
“rootObject”: [“credentials”, 0],
“oauthFlowInitParameters”: [[“client_id”], [“client_secret”]],
“oauthFlowOutputParameters”: [[“access_token”]]
}
}
}

Can you upload the spec as a file?

spec.txt (2.6 KB)
Spec.json

Can you check response for these 2 commands

  1. python3 main.py discover --config secrets/config.json
  2. python3 main.py spec

PS C:\Users\Tree\airbyte\airbyte-integrations\connectors\source-linkedin> python main.py discover --config secrets/config.json

{“type”: “LOG”, “log”: {“level”: “FATAL”, “message”: “Expecting value: line 1 column 1 (char 0)\nTraceback (most recent call last):\n File “C:\Users\Tree\airbyte\airbyte-inte
grations\connectors\source-linkedin\main.py”, line 13, in \n launch(source, sys.argv[1:])\n File “C:\Users\Tree\airbyte\venv\lib\site-packages\airbyte_cdk\
entrypoint.py”, line 127, in launch\n for message in source_entrypoint.run(parsed_args):\n File “C:\Users\Tree\airbyte\venv\lib\site-packages\airbyte_cdk\entrypoint.p
y”, line 80, in run\n self.configure_sentry(source_spec.connectionSpecification, parsed_args)\n File “C:\Users\Tree\airbyte\venv\lib\site-packages\airbyte_cdk\entrypo
int.py”, line 67, in configure_sentry\n config = self.source.read_config(parsed_args.config)\n File “C:\Users\Tree\airbyte\venv\lib\site-packages\airbyte_cdk\connecto
r.py”, line 44, in read_config\n return json.loads(contents)\n File “C:\python_3.9\lib\json\init.py”, line 346, in loads\n return _default_decoder.decode(s)\n File “C:
\python_3.9\lib\json\decoder.py”, line 337, in decode\n obj, end = self.raw_decode(s, idx=_w(s, 0).end())\n File “C:\python_3.9\lib\json\decoder.py”, line 355, in raw_decod
e\n raise JSONDecodeError(“Expecting value”, s, err.value) from None\njson.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)”}}

PS C:\Users\Tree\airbyte\airbyte-integrations\connectors\source-linkedin> python main.py spec

{“type”: “SPEC”, “spec”: {“documentationUrl”: “https://docsurl.com”, “connectionSpecification”: {"$schema": “http://json-schema.org/draft-07/schema#”, “title”: “Linkedin Spec”, “type”: “o
bject”, “additionalProperties”: true, “properties”: {“credentials”: {“title”: “Authentication mechanism”, “description”: “Choose how to authenticate into Linkedin Api”, “type”: “object”,
“oneOf”: [{“type”: “object”, “title”: “OAuth 2.0”, “required”: [“access_token”, “client_id”, “client_secret”, “option_title”], “properties”: {“option_title”: {“type”: “string”, “const”: "
Default OAuth2.0 authorization"}, “client_id”: {“title”: “Client ID”, “description”: “Linkedin client_id.”, “type”: “string”, “examples”: [“Linkedin-client-id-example”], “airbyte_secret”:
true}, “client_secret”: {“title”: “Client Secret”, “description”: “Linkedin client_secret.”, “type”: “string”, “examples”: [“Linkedin-client-secret-example”], “airbyte_secret”: true}, “a
ccess_token”: {“title”: “Access token”, “description”: “Linkedin access_token.”, “type”: “string”, “examples”: [“Linkedin-access-token-example”], “airbyte_secret”: true}}, “order”: 0}, {"
type": “object”, “title”: “API Token”, “required”: [“api_token”, “option_title”], “properties”: {“option_title”: {“type”: “string”, “const”: “API Token Credentials”}, “api_token”: {“type”
: “string”, “title”: “API Token”, “description”: “A Linkedin bot token.”, “airbyte_secret”: true}}, “order”: 1}]}}}, “authSpecification”: {“auth_type”: “oauth2.0”, “oauth2Specification”:
{“rootObject”: [“credentials”, “0”], “oauthFlowInitParameters”: [[“client_id”], [“client_secret”]], “oauthFlowOutputParameters”: [[“access_token”]]}}}}

Hey looks to me like discover is failing can you check if the schema files have the right json

Checked…! , Given schema files have correct JSON file

Is it possible that I can see the code of this source ?