import os
from typing import Callable, Dict, Tuple

from streamlit import session_state as _state

from streamlit.components.v1 import components as _components

from pollination_streamlit.interactors import ApiClient

from .components_callbacks import register_callback

_RELEASE = True

if not _RELEASE:
    _get_host = _components.declare_component("get_host", url="http://localhost:3000")
    _manage_settings = _components.declare_component("manage_settings", url="http://localhost:3000")
    _get_geometry = _components.declare_component("get_geometry", url="http://localhost:3000")
    _recipe_inputs_form = _components.declare_component("recipe_inputs_form", url="http://localhost:3000")
    _get_hbjson = _components.declare_component("get_hbjson", url="http://localhost:3000")
    _run_card = _components.declare_component("run_card", url="http://localhost:3000")
    _study_card = _components.declare_component("study_card", url="http://localhost:3000")
    _send_geometry = _components.declare_component("send_geometry", url="http://localhost:3000")
    _create_study = _components.declare_component("create_study", url="http://localhost:3000")
    _send_hbjson = _components.declare_component("send_hbjson", url="http://localhost:3000")
    _auth_user = _components.declare_component("auth_user", url="http://localhost:3000")
    _send_results = _components.declare_component("send_results", url="http://localhost:3000")
    _select_account = _components.declare_component("select_account", url="http://localhost:3000")
    _select_run = _components.declare_component("select_run", url="http://localhost:3000")
    _select_study = _components.declare_component( "select_study", url="http://localhost:3000")
    _select_recipe = _components.declare_component("select_recipe", url="http://localhost:3000")
    _select_project = _components.declare_component("select_project", url="http://localhost:3000")
    _select_cloud_artifact = _components.declare_component("select_cloud_artifact", url="http://localhost:3000")
else :
    parent_dir = os.path.dirname(os.path.abspath(__file__))
    build_dir = os.path.join(parent_dir, "./components/frontend/build")
    _get_host = _components.declare_component("get_host", path=build_dir)
    _manage_settings = _components.declare_component("manage_settings", path=build_dir)
    _get_geometry = _components.declare_component("get_geometry", path=build_dir)
    _recipe_inputs_form = _components.declare_component("recipe_inputs_form", path=build_dir)
    _get_hbjson = _components.declare_component("get_hbjson", path=build_dir)
    _run_card = _components.declare_component("run_card", path=build_dir)
    _study_card = _components.declare_component("study_card", path=build_dir)
    _send_geometry = _components.declare_component("send_geometry", path=build_dir)
    _create_study = _components.declare_component("create_study", path=build_dir)
    _send_hbjson = _components.declare_component("send_hbjson", path=build_dir)
    _auth_user = _components.declare_component("auth_user", path=build_dir)
    _send_results = _components.declare_component("send_results", path=build_dir)
    _select_account = _components.declare_component("select_account", path=build_dir)
    _select_run = _components.declare_component("select_run", path=build_dir)
    _select_study = _components.declare_component( "select_study", path=build_dir)
    _select_recipe = _components.declare_component("select_recipe", path=build_dir)
    _select_project = _components.declare_component("select_project", path=build_dir)
    _select_cloud_artifact = _components.declare_component("select_cloud_artifact", path=build_dir)

def get_host(key='foo'):
    """Create a new instance of "get_host".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.

    Returns
    -------
    host: 'web' | 'rhino' | 'revit' | 'sketchup'
    """

    get_host = _get_host(
      component='get_host',
      key=key
    )

    return get_host


def manage_settings(key='foo', *, settings):
    """Create a new instance of "get_host".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    settings: dict
        A dictionary with the following structure
        
        { 
            "location":{
                        "city": string,
                        "latitude": float,
                        "longitude": float,
                        "time_zone": float,
                        "elevation": integer
                        },
            "units": 'Meters' | 'Millimeters' | 'Feet' | 'Inches' | 'Centimeters',
            "layers": string[],
            "tolerance": float,
            "angle_tolerance": float
        }

    Returns
    -------
    settings: 
        A dictionary with the following structure

        { 
            "location":{
                        "city": string,
                        "latitude": float,
                        "longitude": float,
                        "time_zone": float,
                        "elevation": integer
                        },
            "units": 'Meters' | 'Millimeters' | 'Feet' | 'Inches' | 'Centimeters',
            "layers": string[],
            "tolerance": float,
            "angle_tolerance": float
        }
    """

    manage_settings = _manage_settings(
      component='manage_settings',
      key=key, 
      settings=settings
    )

    return manage_settings

def get_geometry(
    key: str = 'foo', *, 
    label: str = None, 
    options: dict = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "get_geometry".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    label: str or None
        A string that will be displayed on the button. Defaults to "Get Geometry"
    options: dictionary or None
        A dictionary to show / hide button options. Defaults each option to visible & unselected.

        {
            "subscribe" : {
                "show": True or False,
                "selected": True or False
            },
            "selection" : {
                "show": True or False,
                "selected": True or False
            }
        }

    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.

    Returns
    -------
    dict
        A dictionary with the following structure

        {
            'geometry': List[dict]
        }

        where
            'geometry': List of ladybug geometries as dictionary
    """
    
    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    get_geometry = _get_geometry(
      component='get_geometry',
      key=key, 
      button_label=label, 
      options_config=options
    )

    return get_geometry

def get_hbjson(
    key: str = 'foo', *,
    label: str = None,
    options: Dict = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "get_hbjson".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    label: str or None
        A string that will be displayed on the button. Defaults to "Get Geometry"
    options: dictionary or None
        A dictionary to show / hide button options. Defaults each option to visible & unselected.

        {
            "subscribe" : {
                "show": True or False,
                "selected": True or False
            },
            "selection" : {
                "show": True or False,
                "selected": True or False
            }
        }

    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.

    Returns
    -------
    dict
        A dictionary with the following structure

        {
            'hbjson': dict
        }

        where
            'hbjson': hbjson model as dictionary
    """

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    get_hbjson = _get_hbjson(
      component='get_hbjson',
      key=key, 
      button_label=label, 
      options_config=options
    )

    return get_hbjson

def send_geometry(
    key='foo', *, 
    geometry={}, 
    label: str = None, 
    option='preview', 
    options: dict = None,
    geometry_options: dict = None):

    """Create a new instance of "send_geometry".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    geometry: dictionary
        A dictionary of ladybug geometries.
    option: 'add' | 'preview' | 'clear' | 'subscribe-preview'
        An option that modifies the action to be taken in the host CAD platform.
    label: str or None
        A string that will be displayed on the button. Defaults to "Get Geometry"
    options: dictionary or None
        A dictionary to show / hide button options. Defaults to show all.

        {
            'add' = True or False
            'delete' = True or False
            'preview' = True or False
            'clear' = True or False
            'subscribe-preview' = True or False
        }
    geometry_options: dictionary or None
        A dictionary to control translation of geometry from app to CAD plugin.
        Defaults to using the CAD plugin document settings.

        {
            'units' = 'Meters' | 'Millimeters' | 'Feet' | 'Inches' | 'Centimeters',
        }
    Returns
    -------
    """

    send_geometry = _send_geometry(
      component='send_geometry',
      key=key,
      geometry=geometry,
      option=option,
      button_label=label,
      options_config=options,
      geometry_options=geometry_options
    )

    return send_geometry

def send_hbjson(key='foo', *, 
    hbjson={}, 
    option='preview',
    label: str = None,
    options: dict = None):

    """Create a new instance of "send_hbjson".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    hbjson: dictionary
        An hbjson model as a dictionary.
    option: 'add' | 'preview' | 'clear' | 'subscribe-preview'
        An option that modifies the action to be taken in the host CAD platform.
    label: str or None
        A string that will be displayed on the button. Defaults to "Get Geometry"
    options: dictionary or None
        A dictionary to show / hide button options. Defaults to show all.

        {
            'add', = True or False
            'delete', = True or False
            'preview', = True or False
            'clear', = True or False
            'subscribe-preview' = True or False
        }
    Returns
    -------
    """

    send_hbjson = _send_hbjson(
        component='send_hbjson',
        key=key,
        hbjson=hbjson,
        option=option,
        button_label=label,
        options_config=options
    )

    return send_hbjson

def send_results(key='foo', *, 
    results={}, 
    option='preview', 
    options=None, 
    label=None,
    geometry_options: dict = None):
    
    """Create a new instance of "send_results".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    results: dictionary
        If host === 'rhino' use new GraphicContainer object
        If host === 'revit' dictionary with fields: 'results', 'sensorGrids' and 'configs.
    option: 'add' | 'delete' | 'preview' | 'clear' | 'subscribe-preview'
        An option that modifies the action to be taken in the host CAD platform.
    label: str or None
        A string that will be displayed on the button. Defaults to "Get Geometry"
    options: dictionary or None
        A dictionary to show / hide button options. Defaults to show all.

        {
            'add', = True or False
            'delete', = True or False
            'preview', = True or False
            'clear', = True or False
            'subscribe-preview' = True or False
        }
    geometry_options: dictionary or None
        A dictionary to control translation of geometry from app to CAD plugin.
        Defaults to using the CAD plugin document settings.

        {
            'units' = 'Meters' | 'Millimeters' | 'Feet' | 'Inches' | 'Centimeters',
        }
    Returns
    -------
    """

    send_results = _send_results(
        component='send_results',
        key=key, 
        results=results, 
        option=option, 
        options_config=options, 
        button_label=label,
        geometry_options=geometry_options
    )

    return send_results

def auth_user(key='foo', api_client: ApiClient = None):
    """Create a new instance of "auth_user".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```

    Returns
    -------
    dict
        A dictionary with the following structure

        {
            'id': string
            'email': string
            'name': string
            'username': string
            'description': string or None
            'picture': string or None
        }
    """

    client = api_client.__dict__

    auth_user = _auth_user(
      component='auth_user',
      key=key,
      access_token=client["_jwt_token"],
      api_key=client["_api_token"],
      base_path=client["_host"]
    )

    return auth_user

def select_account(
    key='foo',
    api_client: ApiClient = None, *,
    default_account_username: str = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "select_account".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    default_account_username: str
        default account name, component will select this account as a default state
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.
    
    Returns
    -------
    dict
        A dictionary with the following structure

        {
            'id': string
            'email': string or None
            'contact_email': string or None
            'name': string
            'username': string or None
            'account_name': string or None
            'description': string or None
            'picture': string or None
            'picture_url': string or None
            'owner': dictionary or None
            'role': string or None
            'member_count': number or None
            'team_count': number or None
        }

        where

            'owner': dictionary with the following structure

            {
              'id': string
              'type': 'org' | 'user'
              'name': string
            }
    """
    client = api_client.__dict__

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    select_account = _select_account(
      component='select_account',
      key=key,
      default_account_username=default_account_username,
      access_token=client["_jwt_token"],
      api_key=client["_api_token"],
      base_path=client["_host"]
    )

    return select_account

def select_cloud_artifact(
    key='foo',
    api_client: ApiClient = None, *,
    project_name: str,
    project_owner: str,
    study_id: str,
    file_name_match: str = ".*",
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "select_cloud_artifact".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: str
        A project's unique name
    project_owner: str
        The username (user) or account_name (org) of a projects owner
    file_name_match: str
        A regular expression to match the file name, e.g. ".*(hbjson$)"
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.
    
    Returns
    -------
    file: 
    """
    client = api_client.__dict__

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    select_cloud_artifact = _select_cloud_artifact(
      component='select_cloud_artifact',
      key=key,
      project_name=project_name,
      project_owner=project_owner,
      study_id=study_id,
      file_name_match=file_name_match,
      access_token=client["_jwt_token"],
      api_key=client["_api_token"],
      base_path=client["_host"],
    )

    return select_cloud_artifact

def select_project(
    key='foo', 
    api_client: ApiClient = None, *,
    project_owner: str = None,
    default_project_id: str = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "select_project".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_owner: str or None
        username of project owner
    default_project_id: str or None
        default project id
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.

    Returns
    -------
    dict
        A dictionary with the following structure

            {
                'name': string,
                'description': string or None,
                'public': boolean,
                'id': string,
                'owner': dictionary,
                'permissions': dictionary,
                'slug': string,
                'usage': dictionary,            
            }

            where

                'owner' is a dictionary with the following structure

                    {
                        "id": string,
                        "account_type": string,
                        "name": string,
                        "display_name": string,
                        "description": string or None,
                        "picture_url": string or None
                    }

                'permissions' is a dictionary with the following structure

                    {
                        "admin": boolean,
                        "write": boolean,
                        "read": boolean
                    }

                'usage' is a dictionary with the following structure

                    {
                        "start": string,
                        "end": string,
                        "cpu": int,
                        "memory": int,
                        "succeeded": int,
                        "failed": int,
                        "daily_usage": tuple
                    }
    """

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)
    
    client = api_client.__dict__

    select_project = _select_project(
      component='select_project',
      key=key,
      project_owner=project_owner,
      default_project_id=default_project_id,
      access_token=client["_jwt_token"],
      api_key=client["_api_token"],
      base_path=client["_host"]
    )

    return select_project

def select_recipe(
    key='foo', 
    api_client: ApiClient = None, *, 
    project_name: str = None, 
    project_owner: str = None,
    default_recipe: Dict = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "select_recipe".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: str or None
        project name
    project_owner: str or None
        username of the project owner
    default_recipe: Dict or None
        recipe json object that will be passed as input to select_recipe
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.

    Returns
    -------
    dict
        A dictionary with the structure described here:

            https://api.pollination.cloud/docs#/Projects/get_project_recipes

    """
    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    client = api_client.__dict__

    select_recipe = _select_recipe(
        component='select_recipe',
        key=key,
        project_name=project_name,
        project_owner=project_owner,
        default_recipe=default_recipe,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"])

    return select_recipe

def select_study(
    key='foo', api_client: ApiClient = None, *,
    project_name: str = None,
    project_owner: str = None,
    default_study_id: str = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None,
):
    """Create a new instance of "select_study".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: str or None
        name of project
    project_owner: str or None
        username of project owner
    default_study_id: str or None
        default study id
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.

    Returns
    -------
    dict
        A dictionary with the structure documented here:

            https://api.pollination.cloud/docs#/Jobs/list_jobs
    """
    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)
    
    client = api_client.__dict__

    select_study = _select_study(
        component='select_study',
        key=key,
        project_name=project_name,
        project_owner=project_owner,
        default_study_id=default_study_id,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"])

    return select_study

def select_run(
    key='foo', api_client: ApiClient = None, *,
    project_name: str = None,
    project_owner: str = None,
    job_id: str = None,
    default_run_id: str = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None
):
    """Create a new instance of "select_run".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_owner: str or None
        username of project owner
    job_id: str or None
        id of study
    default_run_id: str or None
        default run id
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.
        
    Returns
    -------
    dict
        A dictionary with the sturcture described here:

            https://api.pollination.cloud/docs#/Runs/list_runs
    """

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    client = api_client.__dict__

    select_run = _select_run(
        component='select_run',
        key=key,
        project_name=project_name,
        project_owner=project_owner,
        job_id=job_id,
        default_run_id=default_run_id,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"])

    return select_run

def create_study(
    key='foo', api_client: ApiClient = None, *,
    default_inputs: Dict = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None
):
    """Create a new instance of "select_run".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    default_inputs: Dict
        A dictionary with the structure
        
        {
            [input_name: string] : {
                value: string,
                hidden: boolean
            }
        }

        The hidden field is optional.
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.
        
    Returns
    -------
    """

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    client = api_client.__dict__

    create_study = _create_study(
        component='create_study',
        key=key,
        default_inputs=default_inputs,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"]
    )

    return create_study

def recipe_inputs_form(
    key='foo', api_client: ApiClient = None, *,
    project_name: str = None,
    project_owner: str = None,
    default_inputs: Dict = None,
    recipe: Dict = None,
    on_change:  Callable = None,
    args: Tuple = None,
    kwargs: Dict = None
):
    """Create a new instance of "select_run".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: str
        Unique name representing a project
    project_owner: str
        Unique name representing the project's owner
    default_inputs: Dict
        A dictionary with the structure
        
        {
            [input_name: string] : {
                value: string,
                hidden: boolean
            }
        }

        The hidden field is optional.
    recipe: Dict
        Dictionary representing a pollination recipe, use select_recipe
    on_change: Callable or None
        An optional on_change function that will be called when hbjson input
        is changed.
    args: Tuple or None
        An optional tuple of positional arguments that will be passed to the
        on_change function.
    kwargs: dictionary or None
        An optional dictionary of kwargs that will be passed to the on_change
        function.
        
    Returns
    -------
    
    """

    if on_change is not None:
        args = args or []
        kwargs = kwargs or {}
        register_callback(key, on_change, *args, **kwargs)

    client = api_client.__dict__

    recipe_inputs_form = _recipe_inputs_form(
        component='recipe_inputs_form',
        key=key,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"],
        project_owner=project_owner,
        project_name=project_name,
        default_inputs=default_inputs,
        recipe=recipe)

    return recipe_inputs_form

def study_card(
    key='foo', api_client: ApiClient = None, *,
    project_name=None,
    project_owner=None,
    study=None,
    run_list=None,
):
    """Create a new instance of "select_run".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: string
        The projects unique name
    project_owner: string
        The project owner's unique name
    study: dict
        A dictionary that represents a Study, or Job as it's called in the 
        pollination-sdk. Retreive a study object using the select_study component.
    run_list: boolean
        Toggle the runs list at the bottom of the card
        
    Returns
    -------
    """

    client = api_client.__dict__

    study_card = _study_card(
        component='study_card',
        key=key,
        project_name=project_name,
        project_owner=project_owner,
        study=study,
        run_list=run_list,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"])

    return study_card

def run_card(
    key='foo', api_client: ApiClient = None, *,
    project_name=None,
    project_owner=None,
    job_id=None,
    run=None,
):
    """Create a new instance of "select_run".

    Parameters
    ----------
    key: str or None
        An optional key that uniquely identifies this component. If this is
        None, and the component's arguments are changed, the component will
        be re-mounted in the Streamlit frontend and lose its current state.
    api_client: ApiClient
        ApiClient is a class returned by get_api_client(), part of the 
        pollination_streamlit package.
        ```
        from pollination_streamlit.selectors import get_api_client
        ...
        api_client = get_api_client
        ```
    project_name: string
        The projects unique name
    project_owner: string
        The project owner's unique name
    run: dict
        A dictionary representing a CloudRun object. Retrieve this object using the 
        select_run component.
        
    Returns
    -------
    """

    client = api_client.__dict__

    run_card = _run_card(
        component='run_card',
        key=key,
        project_name=project_name,
        project_owner=project_owner,
        job_id=job_id,
        run=run,
        access_token=client["_jwt_token"],
        api_key=client["_api_token"],
        base_path=client["_host"])

    return run_card
