Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.env
app/node_modules/
storage/
storage/

*.pyc
1 change: 1 addition & 0 deletions python_client/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
82 changes: 82 additions & 0 deletions python_client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Python RunwayClient

The `RunwayClient` is a slim Python wrapper around Runway's REST API to trigger
jobs programmatically. See the Slite design document for more information:
[DIIP 17: API-triggered jobs](https://edanalytics.slite.com/app/docs/eJ7maazQl3s5vP)

## Installation

To install locally, specify the path to `runway_python_client`, like:

```shell
pip install ./runway/python_client
```

This project was built with `uv`, so this works too:

```shell
uv pip install ./runway/python_client
```

To install from Github, use the subdirectory syntax:

```shell
pip install "git+https://github.com/edanalytics/runway.git#subdirectory=python_client"
```

The name of the installed module is `runway_client`, so after installing, you'd
import like:

```python
from runway_client import RunwayClient
```

## Running the Client

To get started, you'll need four things:

1. Client Id and Secret for requesting tokens
2. Base URL for requesting tokens
3. Base URL for Runway API
4. A sample assessment file

After installing, you can then instantiate the client and trigger a job like
this:

```python
from runway_client import RunwayClient

client = RunwayClient(
runway_base_url="https://api.<instance name>-<env>.runwayloader.org/api/v1",
auth_base_url="https://<name>.<env>.us.auth0.com",
client_id="<client id>",
client_secret="<client secret>",
partner_code="ea",
)

client.load_files(
tenant_code="ea",
bundle_name="assessments/PSAT_SAT",
input_files={"INPUT_FILE": "/path/to/sat.csv"},
bundle_params={"TEST_TYPE": "SAT"},
school_year="2526",
)
```

Executing `load_files(...)` will:

1. Request authorization from Auth0 using the client id, secret, and partner
code.
2. Request Runway to create a job for the assessment files. If the bundle
parameters are valid, Runway will return a job id, as well as S3 presigned
URLs per file.
3. Upload assessment files to S3.
4. Request Runway to begin processing the assessment files.

`RunwayClient` will do some basic validation of its constructor arguments, but
it does not validate the bundle parameters. Runway validates each request. An
exception is raised for failed requests.

Neither the Runway API nor the client will report the status of processing the
assessment files. To check the status and results, you'll need to go to the
Runway UI.
20 changes: 20 additions & 0 deletions python_client/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[project]
name = "runway-client"
version = "0.1.0"
description = "Slim wrapper around Runway's Job Request API"
readme = "README.md"
authors = [
{ name = "Jacob Bortell", email = "jbortell@edanalytics.org" }
]
requires-python = ">=3.13"
dependencies = [
"pydantic>=2.12.5",
"requests>=2.32.5",
]

[build-system]
requires = ["uv_build>=0.9.28,<0.10.0"]
build-backend = "uv_build"

[tool.uv.build-backend]
module-name = "runway_client"
Loading