---
title: "Introduction"
description: "How the CAT Python module is used: install and import, the session model, paths, logging, .NET objects in Python, exceptions, sign-in and plans, environment variables and files."
url: "https://docs.justcat.it/reference/python-module/introduction/"
---
# Introduction


The CAT Python module — package `justcatit` on PyPI, module `justcatit.cat` — drives CAT from Python: it opens a project file (`.cat.yaml`), runs its tests, hands the results back as objects, and manages the installation. It works with the same project file and runs tests with the same engine as CAT Studio, CAT CLI and the PowerShell module — which tool you use is a matter of environment and taste, not of capability. Under the hood it loads CAT's .NET engine into the Python process through [pythonnet](https://pythonnet.github.io/), which is why the objects it returns are .NET objects (see below) and why an installed .NET runtime is a prerequisite. For a hands-on first contact, follow the [Get started with the Python module](https://docs.justcat.it/get-started/python-module/ "Get started with the Python module") tutorial; this section is the reference.

## Install and import

```
pip install justcatit
```

plus an installed .NET runtime, version 10 or later — see [Installation](https://docs.justcat.it/reference/python-module/installation/ "Installation"). Then:

```python
from justcatit import cat
```

Importing loads nothing of .NET yet; the engine is loaded by the first function you call. Every public function has a docstring (`help(cat.invoke_project)`).

## Functions

By task:

| Task | Functions |
|------|-----------|
| Run tests in one go | [`invoke_project`](https://docs.justcat.it/reference/python-module/invoke-project/ "invoke_project") |
| Open a project and work with it | [`open_project`](https://docs.justcat.it/reference/python-module/open-project/ "open_project") · [`invoke_tests`](https://docs.justcat.it/reference/python-module/invoke-tests/ "invoke_tests") · [`close_project`](https://docs.justcat.it/reference/python-module/close-project/ "close_project") |
| Inspect the open project | [`get_data_sources`](https://docs.justcat.it/reference/python-module/get-data-sources/ "get_data_sources") · [`get_data_source_lists`](https://docs.justcat.it/reference/python-module/get-data-source-lists/ "get_data_source_lists") · [`get_tests`](https://docs.justcat.it/reference/python-module/get-tests/ "get_tests") · [`get_test_lists`](https://docs.justcat.it/reference/python-module/get-test-lists/ "get_test_lists") |
| Read the results of the last run | [`get_test_results_summary`](https://docs.justcat.it/reference/python-module/get-test-results-summary/ "get_test_results_summary") · [`get_test_results`](https://docs.justcat.it/reference/python-module/get-test-results/ "get_test_results") |
| Query a data source directly | [`invoke_command`](https://docs.justcat.it/reference/python-module/invoke-command/ "invoke_command") |
| Create a project | [`new_project`](https://docs.justcat.it/reference/python-module/new-project/ "new_project") · [`get_project_templates`](https://docs.justcat.it/reference/python-module/get-project-templates/ "get_project_templates") |
| The installation | [`get_instance`](https://docs.justcat.it/reference/python-module/get-instance/ "get_instance") · [`set_instance`](https://docs.justcat.it/reference/python-module/set-instance/ "set_instance") |

Plus the `cat.LoggingLevel` enum (below) and the exception classes (below). Everything else in the module is private.

## The session model

The module keeps one **session** and at most one **open project** per Python process.

- The first function you call loads the .NET engine, creates the session, and — for every function except `get_instance` and `set_instance` — signs in and checks the plan. This happens once per process; later calls reuse the session.
- `open_project` (and `invoke_project`, which opens internally) makes a project *the* open project. Functions that work with "the project" — `get_tests`, `get_data_sources`, `invoke_tests`, `invoke_command`, … — use it and fail when there is none. Opening another project replaces the first.
- `invoke_project` is the one-liner: open, run, return the summary. After it, the project stays open and `get_test_results_summary()` / `get_test_results()` still read its results.
- `close_project()` forgets the open project; the session and the last results stay. It is never required.

## Paths

`project_file_path` (`open_project`, `invoke_project`) is a path to a `.cat.yaml` file or to a directory that contains **exactly one** `*.cat.yaml` file — none or more than one is an error naming the files found. The argument is required; there is no "current directory" default in Python. A relative path is resolved against the process's current working directory. Relative paths *inside* the project file (test lists, outputs, CSV files, …) are resolved against the project file's folder.

## Logging

`cat.LoggingLevel` has the members `NOTHING`, `FATAL`, `ERROR`, `WARNING`, `INFORMATION`, `DEBUG`. Pass one as `loggingLevel` / `logging_level` to the function that makes the first call of the process — the level is fixed when the engine is loaded, and the parameter is ignored on every later call. `NOTHING` and `None` both mean *the engine's default*, which is `INFORMATION`; **logging cannot be switched off from Python** in the current version.

Log lines go to standard output (`[HH:mm:ss INF] …`) and to the log file `Documents\CAT\Logs\cat-log<yyyyMMddHH>.log` on Windows (`./CAT/Logs/` under the current directory on Linux). `INFORMATION` shows what CAT does step by step — which project it opened, how many data sources and tests it loaded from where, each test as it finishes.

## .NET objects in Python

Except `invoke_command` (a `dict`) and the functions that return nothing, every function returns the engine's own .NET object. Three things to know:

- **Properties are PascalCase** and read like attributes: `summary.FailedCount`, `test.TestFullName`, `instance.LicenseKey`. The function pages list them.
- **Collections iterate** and support `len()`: `for t in cat.get_tests(): …`. They are not Python lists; wrap them (`list(cat.get_tests())`) if you need list methods.
- **Numbers and dates are .NET types.** Counts are plain `int`. Rates (`PassRate`, `FailedRate`, …) are `System.Decimal`: `str()` and f-strings print them, `float(x)` raises `TypeError` — use `float(str(x))`. Dates and durations (`StartedOn`, `Duration`) print fine; call `.ToString()` for formatting. Test IDs are `System.Guid` objects (hand them back as they are; strings are not accepted).

## Exceptions

Refusals from the sign-in and plan check raise typed exceptions from `justcatit.exceptions` (the base class and the first six are also importable from `justcatit` directly); `args[0]` carries the message:

| Exception | Meaning |
|-----------|---------|
| `TokenMissingError` | `CAT_PORTAL_TOKEN` is not set. |
| `TokenInvalidError` | The token was rejected by the portal. |
| `PlanNotAllowedError` | The plan does not include the Python module (Starter, Professional). |
| `OfflineExpiredError` | The portal is unreachable and no cached authorisation can be used. |
| `VersionExpiredError` | The plan or version has expired. |
| `InteractiveUsageError` | Interactive-only plan (Team) started by a CI/CD platform or a scheduler. |
| `PlanLimitExceededError` | The project exceeds a per-project limit of the plan (`open_project`). |
| `CatPortalError` | Base class of all of the above. |

`set_instance` raises `ValueError` when it refuses a key. Everything else that goes wrong inside the engine — a project file that does not parse, an unknown data source name, a data source that cannot be reached while loading — surfaces as the .NET exception pythonnet wraps (`System.Exception`, `JC.Cat.Core.Exceptions.CatException`, …); `e.Message` is the message, `str(e)` adds the .NET stack trace. In the current version, calling a project function with no open project raises a bare `TypeError: exceptions must derive from BaseException` rather than a readable error — open a project first.

**Failed tests are not exceptions.** `invoke_project` and `invoke_tests` return normally whatever the results; a script that must fail on failed tests reads the summary:

```python
summary = cat.invoke_project("D:/Testing/DwhTests.cat.yaml")
if summary.FailedCount > 0 or summary.ErrorCount > 0:
    raise SystemExit(1)
```

## Sign-in, plans and the license key

The command-line tools are available in the **Team** and **Enterprise** plans; **Starter** and **Professional** cover CAT Studio only — the module refuses to work under them (`PlanNotAllowedError`). See [Compare plans](https://docs.justcat.it/compare-plans/ "Compare plans").

**Team** signs in to [CAT Portal](https://portal.justcat.it) with a personal access token: create one under **Developer → Personal access tokens** and put it into the `CAT_PORTAL_TOKEN` environment variable before the process starts (or `os.environ["CAT_PORTAL_TOKEN"] = "…"` before the first call). The Team plan is for interactive use only: when CAT detects that it was started by a CI/CD platform (GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, TeamCity and others, through their environment variables) or by a scheduler (Windows Task Scheduler, SQL Server Agent, cron — through the parent process; on Linux also a container runtime), it refuses with `InteractiveUsageError`. Nothing detected means allowed.

Once signed in, CAT caches the authorisation and keeps working without the portal for a limited time; during that time the first call emits a `UserWarning` `Working offline; authorised until <date>. Reconnect before then.` (silence it with the `warnings` module). When the portal is unreachable and no usable cache exists, it refuses with `OfflineExpiredError`.

**Enterprise** needs no sign-in and no network at all: set the license key once with [`set_instance`](https://docs.justcat.it/reference/python-module/set-instance/ "set_instance") and every function is unlocked, also behind a firewall; with a valid key in place `CAT_PORTAL_TOKEN` is not read. The key is shared with the other CAT tools on the machine. See [Get CAT license](https://docs.justcat.it/how-to-guides/licensing-and-admin/get-license/ "Get CAT license") and [Apply a license key](https://docs.justcat.it/how-to-guides/licensing-and-admin/apply-license-key/ "Apply a license key").

The check runs before any work, so a refused call does nothing — no project is opened, no test runs, no output is written. After a refusal the process is not poisoned: set the variable or the key and call again. `get_instance` and `set_instance` skip the check.

## Environment variables

| Variable | Purpose |
|----------|---------|
| `CAT_PORTAL_TOKEN` | Personal access token used to sign in (Team plan). Not read when a valid Enterprise key is set. |
| `DOTNET_ROOT` | Read by pythonnet to find the .NET runtime when it is not on `PATH`. |

Project files can reference environment variables of their own (connection strings, paths, passwords) — see [Environment variables](https://docs.justcat.it/reference/project-file/environment-variables/ "Environment variables in project files") and [Use environment variables](https://docs.justcat.it/how-to-guides/organize-and-run-tests/use-environment-variables/ "Use environment variables").

## Files the module touches

| Windows | Linux | Content |
|---------|-------|---------|
| `%APPDATA%\CAT\.catconfig` | `~/.config/CAT/.catconfig` | Instance identity and the license key (`get_instance` / `set_instance`). |
| `%APPDATA%\CAT\Templates\Projects\` | `~/.config/CAT/Templates/Projects/` | Project templates, including those downloaded with `online=True`. |
| `Documents\CAT\Logs\` | `./CAT/Logs/` | Log files. |
| Next to the project file | | Whatever the project's `Output` settings say (see [Outputs](https://docs.justcat.it/reference/outputs/ "Outputs")); `skip_outputs=True` skips them. |

## Platforms

The Python module runs on **Windows x64** only. It needs a 64-bit Python and an installed .NET runtime (10 or later). Linux and macOS are **not supported** — making the module work there is planned, not done. To run CAT on Linux today, use the [PowerShell module](https://docs.justcat.it/reference/powershell-module/introduction/ "PowerShell module") or [CAT CLI](https://docs.justcat.it/reference/cat-cli/introduction/ "CAT CLI"), both of which run there. Running CAT inside Databricks or Microsoft Fabric notebooks is discussed in the how-to guides [CAT in Databricks notebooks](https://docs.justcat.it/how-to-guides/data-platforms/cat-in-databricks-notebooks/ "CAT in Databricks notebooks") and [CAT and Microsoft Fabric](https://docs.justcat.it/how-to-guides/data-platforms/test-microsoft-fabric/ "CAT and Microsoft Fabric").

## Related

- [Installation](https://docs.justcat.it/reference/python-module/installation/ "Installation") — pip, the .NET runtime, Python versions, upgrade, uninstall.
- [Get started with the Python module](https://docs.justcat.it/get-started/python-module/ "Get started with the Python module") — the tutorial.
- [Run your tests](https://docs.justcat.it/how-to-guides/organize-and-run-tests/run-your-tests/ "Run your tests") — the same task across all tools.
- [Project file](https://docs.justcat.it/reference/project-file/ "Project file") — what the functions operate on.

