# Cloud Foundry Integration

SeaLights' Python agent can be integrated with applications running in Cloud Foundry using the standard [Python Buildpack](https://github.com/cloudfoundry/python-buildpack) version `v1.8.13` or later. This document explains how to install and configure the agent in your Python-based applications deployed on Cloud Foundry.

{% hint style="info" %}
Sealights use the `BeforeCompile` hook in the Python build pack to install an agent and all required dependencies in the target container. When the application is staged and pushed to Cloud Foundry, the following occurs:

1. The Sealights hook verifies that the application is bound with a service whose name includes `sealights`.
2. It installs the agent and its dependencies from the PyPI repository.
3. It modifies the target application's start command to include the agent wrapper logic.

This process is automatic and requires no code or buildpack changes from the developer.
{% endhint %}

## Installing CF Python Buildpack <a href="#installing-cf-python-buildpack" id="installing-cf-python-buildpack"></a>

To run Python applications on Cloud Foundry with Sealights integration, you must use the official Python Buildpack version **v1.8.13** or later. The buildpack can be specified in one of two ways:

{% tabs %}
{% tab title="CLI" %}
{% code overflow="wrap" lineNumbers="true" %}

```javascript
cf push -b https://github.com/cloudfoundry/python-buildpack.git 
```

{% endcode %}
{% endtab %}

{% tab title="Manifest.yml" %}
{% code overflow="wrap" lineNumbers="true" %}

```yaml
applications:
  - name: yourApp
    buildpacks:
      - https://github.com/cloudfoundry/python-buildpack.git
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Configuring the Sealights Service in Python Buildpack <a href="#configuring-the-sealights-service-in-python-buildpack" id="configuring-the-sealights-service-in-python-buildpack"></a>

Integrating the Sealights Python agent using the Cloud Foundry buildpack involves a few straightforward steps:

* **Create** a user-provided service for Sealights and define its core settings (typically the agent token).
* **Bind** your application to the Sealights service.
* **Define** Sealights-specific environment variables for your application (e.g., `lab_id`, `proxy`, etc.).
* **Restage** the application to apply the configuration.

While these steps can also be managed through a `manifest.yml` file using Cloud Foundry's native support for services and environment variables, the following sections focus on the equivalent CLI-based workflow, which is commonly used in CI/CD automation pipelines.

### Create Your Sealights User-Provided Service <a href="#create-your-sealights-user-provided-service" id="create-your-sealights-user-provided-service"></a>

Use the following command to create a user-provided service named `sealights`:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
cf cups sealights -p '{"token":"<your_sealights_token>"}'
```

{% endcode %}

If the token is retrieved securely from a Vault secret store, as an Industry Best practice, you can use a command similar to:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
cf cups sealights -p "{\"token\":\"$(vault kv get -field=token secret/sealights)\"}"
```

{% endcode %}

{% hint style="warning" %}
The service name must include the word `sealights` (lowercase) for the integration to be recognized by the buildpack.
{% endhint %}

{% hint style="info" %}

* Alternatively, provide a token file as `'{"tokenfile":"/home/vcap/app/sltoken.txt"}'` instead of the `token` parameter.
* In the Windows command line, you have to use the escape character (`"`) in the parameter passed, like `'{\"token\":\"ey…\"}'`
* You can change the parameters later with the command [update-user-provided-service](https://cli.cloudfoundry.org/en-US/v7/update-user-provided-service.html) `cf uups` (for example, for using a project-specific token)
  {% endhint %}

### Bind the Application with the SL Service <a href="#bind-the-application-with-the-sl-service" id="bind-the-application-with-the-sl-service"></a>

Once your application is pushed, bind it to the user-provided Sealights service:

{% code overflow="wrap" lineNumbers="true" %}

```python
cf bind-service [app name] sealights
```

{% endcode %}

### Defining Sealights-Specific Parameters <a href="#defining-sealights-specific-parameters" id="defining-sealights-specific-parameters"></a>

You can define various parameters as environment variables using either the CLI or `manifest.yml`:

{% tabs %}
{% tab title="CLI" %}
{% code overflow="wrap" lineNumbers="true" %}

```python
cf set-env [your-app-name] SL_LAB_ID "yourLabId"
cf set-env [your-app-name] SL_DEBUG true
```

{% endcode %}
{% endtab %}

{% tab title="Manifest.yml" %}
{% code overflow="wrap" lineNumbers="true" %}

```yaml
env:
  SL_LAB_ID: yourLabId
  SL_DEBUG: true
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here is a list of the most common Environment variables to be used (For additional options, consult the [command-reference](https://docs.sealights.io/knowledgebase/setup-and-configuration/sealights-agents-and-plugins/python-agent/command-reference "mention")):&#x20;

<table><thead><tr><th width="256.57421875">Parameter name</th><th>Description</th></tr></thead><tbody><tr><td><code>SL_LAB_ID</code></td><td>Identifier for your test lab</td></tr><tr><td><code>SL_BUILD_SESSION_ID</code></td><td>Sealights' Build session ID (manual override)</td></tr><tr><td><code>SL_BUILD_SESSION_ID_FILE</code></td><td>Path to the file containing the Build session ID.</td></tr><tr><td><code>SL_PROXY</code></td><td>Proxy URL to run connection through (e.g., <code>http://proxy.mycompany.com</code><a href="http://proxy.mycompany.com)/">)</a></td></tr><tr><td><code>SL_DEBUG</code></td><td>Set to `true` to enable debug logging.<br>Messages will be written to <code>stdout</code> and the file, <code>sealights-python-agent.log</code></td></tr></tbody></table>

### Restage Application <a href="#restage-application" id="restage-application"></a>

To apply changes (e.g., service binding or env vars), restage your application with the dedicated command [restage](https://cli.cloudfoundry.org/en-US/v7/restage.html).

{% code overflow="wrap" lineNumbers="true" %}

```javascript
cf restage [app name]
```

{% endcode %}

{% hint style="success" %}
Once the Sealights service is bound, the coverage listener will be triggered attached to your application, you can monitor the live agent status from the **SeaLights Cockpit > Live Agents Monitor** screen in your dashboard.
{% endhint %}

## How to Download the SL Agent to CF from a Custom Repository <a href="#how-to-download-the-sl-agent-to-cf-from-a-custom-repository" id="how-to-download-the-sl-agent-to-cf-from-a-custom-repository"></a>

By default, the agent is fetched from the public PyPI repository. If your environment restricts public access, you can configure the agent installation to use an internal PyPI mirror (if supported by your platform) or use a build-time proxy via `SL_PROXY`.

Currently, the Python buildpack does **not** support specifying a custom index YAML like the Java one, but you can preinstall the agent into your container using a `.profile` or Dockerfile override.

## Sample Configuration <a href="#sample-configuration" id="sample-configuration"></a>

#### Sample `manifest.yml` <a href="#sample-manifest.yml" id="sample-manifest.yml"></a>

{% code overflow="wrap" lineNumbers="true" %}

```yaml
applications:
  - name: my-python-app
    memory: 512M
    buildpacks:
      - https://github.com/cloudfoundry/python-buildpack.git
    env:
      SL_LAB_ID: "myLabId"
      SL_PROXY: "http://myproxy.internal"
      SL_DEBUG: true
    services:
      - sealights
```

{% endcode %}

#### Sample Deployment Script with `manifest.yml` Fallback <a href="#sample-deployment-script-with-manifest.yml-fallback" id="sample-deployment-script-with-manifest.yml-fallback"></a>

{% code overflow="wrap" lineNumbers="true" %}

```sh
#!/bin/bash
set -e

APP_NAME="my-python-app"
SEALIGHTS_SERVICE="sealights"

# Set required values
export SL_LAB_ID="myLabId"
export SL_PROXY="http://myproxy.internal"
export SEALIGHTS_TOKEN=$(vault kv get -field=token secret/sealights) # Replace with your secret manager

# Create or update the Sealights service
cf cups $SEALIGHTS_SERVICE -p "{\"token\":\"$SEALIGHTS_TOKEN\"}"

# Check if manifest.yml exists
if [ -f "manifest.yml" ]; then
  echo "manifest.yml found. Deploying with manifest..."
  cf push
else
  echo "manifest.yml not found. Using manual deployment..."
  cf push $APP_NAME -b https://github.com/cloudfoundry/python-buildpack.git
  cf set-env $APP_NAME SL_LAB_ID "$SL_LAB_ID"
  cf set-env $APP_NAME SL_PROXY "$SL_PROXY"
  cf set-env $APP_NAME SL_DEBUG true
  cf bind-service $APP_NAME $SEALIGHTS_SERVICE
  cf restage $APP_NAME
fi
# Optionally display recent logs and status
cf logs $APP_NAME --recent
cf app $APP_NAME
```

{% endcode %}

## Troubleshooting Sealights Buildpack Configuration <a href="#troubleshooting-sealights-buildpack-configuration" id="troubleshooting-sealights-buildpack-configuration"></a>

If the Sealights Python agent does not appear to be active or coverage is not being reported, perform the following checks:

* Run `cf logs your-app --recent | grep sealights` to search for log messages related to the agent, including any errors or warnings.
* Run `cf services` to verify that a user-provided service with a name containing `sealights` is correctly bound to the application.
* SSH into the application container and run `pip list | grep sealights` to check that the agent was installed successfully.
* Inside the container, run `env | grep -E '^(SL_|SEALIGHTS_)'` to confirm that the required Sealights environment variables are set.

#### Verifying the Application Start Command <a href="#verifying-the-application-start-command" id="verifying-the-application-start-command"></a>

To confirm how the Sealights Python agent modifies the application’s start command during staging:

* SSH into the application container and run the `ps -ef | grep python` command to display the current Python process and its full start command. If the Sealights agent is active, the command will typically appear as `python -m sealights_python_agent.run -- python app.py`. This indicates that the original application command (e.g., `python app.py`) has been wrapped by the agent.
* To review the original startup definition, check for a custom start command in the `manifest.yml` or `Procfile`:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
cat manifest.yml 
cat Procfile
```

{% endcode %}

* If neither file is present or they do not define a command, the Python buildpack attempts to infer the entry point. You can list common startup files with:

{% code overflow="wrap" lineNumbers="true" %}

```javascript
ls -1 | grep -E '^(app|server|wsgi)\.py$' 
```

{% endcode %}

This will help determine which file is likely to be used as the default entry script.

Further configuration can be refined via the Python Buildpack built-in settings <https://docs.cloudfoundry.org/buildpacks/python/index.html>
