> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coaxial.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> This is a short tutorial on using the Coaxial Developer SDK

<Info>
  **Prerequisite** You should have installed Python (version 3.7 or
  higher).
</Info>

For this tutorial, we will integrate Coaxial with an example vector-embedding chat application for internal company employees.

## Setup your development

Currently, we provide developer clients for Python and Typescript. You can install the client with `pip`:

```python theme={null}
pip install coaxial-python
```

or `npm`:

```typescript theme={null}
npm i coaxial-ts --save
```

To use the package, import the client like so:

```python theme={null}
import coaxial
```

or

```typescript theme={null}
import { CoaxialApi } from "coaxial-ts"
```

### API Keys/Authentication

To generate a Coaxial API Key, see the API Reference. Once you've generated your key, create a Coaxial API Instance:

```python theme={null}
coaxial_api = coaxial.Api(api_key="YOUR_COAXIAL_API_KEY")
```

## Auth Integration

Let's integrate our employees from Okta using the Okta client key and organization URL.

```python theme={null}
from coaxial.models import IntegrateOktaRequest

integrate_okta_request = IntegrateOktaRequest(
  client_key="OKTA_API_KEY", 
  org_url="OKTA_ORGANIZATION_URL"
)

try:
    coaxial_api.auth_integration.integrate_okta(integrate_okta_request)
except Exception as e:
    print("Exception when Integrating Okta: %s\n" % e)
```

### Listing Users

If the integration is successful, we'll list our users to get their user IDs.

```python theme={null}
api_response = coaxial_api.auth_integration.list_users()
print(api_response)

#Here, we can save the User ID's for provisioning/de-provisioning later on
```

## Data Integration

Now, let's track the data our model ingests. Assume our application pulls vectors from two Pinecone indexes. We'll need the Pinecone API Key and associated environment (ex. us-west1-gcp-free)

```python theme={null}
from coaxial.models import IntegratePineconeRequest

integrate_pinecone_request = IntegratePineconeRequest(
  api_key="PINECONE_API_KEY", 
  environment="PINECONE_ENVIRONMENT"
)

try:
    coaxial_api.data_integration.integrate_pinecone(
      integrate_pinecone_request
    )
except Exception as e:
    print("Exception when Integrating Pinecone: %s\n" % e)
```

### Listing Data Integrations

If the integration is successful, we'll list our integrated indexes (there should be two for our example application).

```python theme={null}
api_response = coaxial_api.data_integration.list_data_integrations()
print(api_response)

# Here, we can save the data integration Coaxial ID's
# for provisioning/de-provisioning later on
```

## Model Integration

For this LLM application, we can control the models users have access to. Assuming we're building a standard chat interface with OpenAI, we can pull all available models from our OpenAI account.

```python theme={null}
from coaxial.models import IntegrateOpenaiRequest

integrate_openai_request = IntegrateOpenaiRequest(openai_key="OPENAI_API_KEY")

try:
    coaxial_api.model_integration.integrate_openai(integrate_openai_request)
except Exception as e:
    print("Exception when Integrating OpenAI: %s\n" % e)
```

### Listing Model Integrations

If the integration is successful, we'll list our integrated models and their respective Coaxial IDs (specifically, we should look out for the chat/embedding models).

```python theme={null}
api_response = coaxial_api.model_integration.list_model_integrations()
print(api_response)
```

## Functions

Now, let's say we want the model to call an OpenAI function that gives a JSON Object summary of the chat response (and only certain users can access this function). Here is how we would integrate it:

```python theme={null}
from coaxial.models import IntegrateFunctionRequest

integrate_function_request = IntegrateFunctionRequest(
  function_name="summarize_chat_response", 
  description="This is an OpenAI function that gives a JSON Object summary of the chat response")

try:
    coaxial_api.function.integrate_function(integrate_function_request)
except Exception as e:
    print("Exception when Integrating Function: %s\n" % e)
```

### Listing Functions

If the integration is successful, we'll see the function we just integrated.

```python theme={null}
api_response = coaxial_api.function.list_functions()
print(api_response)
```

## Access Controls

### Provisioning

Now, we will provision a specific employee with access to the entire LLM application functionality. This includes both Pinecone indexes, the embedding/chat models, and OpenAI function.

```python theme={null}
from coaxial.models import GrantAccessRequest

resource_ids = [ #These IDs can also be found on the Coaxial Dashboard
  "PINECONE_INDEX_1_COAXIAL_ID", 
  "PINECONE_INDEX_2_COAXIAL_ID",
  "EMBEDDING_MODEL_COAXIAL_ID",
  "CHAT_MODEL_COAXIAL_ID",
  "FUNCTION_COAXIAL_ID"
]

try:
    for resource in resource_ids:
      grant_access_request = GrantAccessRequest(
        user_id="EMPLOYEE_ID", 
        coaxial_id=resource
      )
      coaxial_api.provision.grant_access(grant_access_request)
except Exception as e:
    print("Exception when granting access: %s\n" % e)
```

### Checking Access

At any point during the LLM application life-cycle, we are able to see if a user can access the required resources.
This way, if our admin wants to revoke an employee's function access (for example) through the dashboard, the application will respond immediately.

```python theme={null}
from coaxial.models import CheckAccessForAllRequest

def check_resources(user_id):
  check_access_for_all_request = CheckAccessForAllRequest(
    user_id=user_id, 
    tags=resource_ids
  ) 
  return coaxial_api.provision.check_access_for_all(
    check_access_for_all_request
  )
```

### Revoking Access

Finally, say we want automatically revoke access to the datasets for a specific user who has been misbehaving.

```python theme={null}
from coaxial.models import RevokeAccessRequest

revoke_ids = [
  "PINECONE_INDEX_1_COAXIAL_ID", 
  "PINECONE_INDEX_2_COAXIAL_ID"
]

try:
  for resource in revoke_ids:
    revoke_access_request = RevokeAccessRequest(
      user_id="EMPLOYEE_ID", 
      coaxial_id=resource
    )
    coaxial_api.provision.revoke_access(revoke_access_request)
except Exception as e:
    print("Exception when revoking access: %s\n" % e)
  
print(check_resources("EMPLOYEE_ID")) #double-check access to resources
```

That's the end of the Quickstart! Our example LLM application now has precise control over the functionality and data the model ingests (depending on user identity).
For a more detailed overview of all the endpoints Coaxial provides (including client code examples), please see the API Integration.
