Typed, validated schemas for Gherkin data tables
Project description
Talika — Hindi for tables.
Declarative schemas for typed, validated Gherkin data tables.
Gherkin data tables are wonderfully easy to read. The raw list[list[str]] that
arrives in Python is less wonderful to maintain.
As a test suite grows, step definitions accumulate the same invisible work: matching labels, converting strings, applying defaults, rejecting typos, and explaining which cell was wrong. Talika moves that work into a small, reusable table contract.
Define the shape once. Talika parses the table, converts its cells into real
Python values, validates the result, and keeps errors connected to the original
.feature file.
Quickstart · Why Talika? · API reference
What you get
- Declarative table contracts — describe labels, required fields, aliases, defaults, and parsing rules in one Python class.
- Typed records — turn cells into
int,bool,Decimal, enums, lists, and your own domain values. - Both natural table shapes — use row-oriented tables for lists and column-oriented tables for detailed items.
- Errors where the data lives — report stable error codes with the field, row, column, item ID, and original value.
- Your team's vocabulary — build readable cell conventions such as
random,today, or20 wordswith tokens and full-match patterns. - Room for real test suites — model variants, references, table transforms, cross-record validation, and dataclass or Pydantic output.
- Checks before test execution — validate Gherkin tables in CI with the
optional
talika checkCLI. - A zero-dependency core — install integrations only when you need them.
Installation
Talika supports Python 3.10 and newer.
pip install talika
Or with uv:
uv add talika
Optional extras keep the core package small:
pip install "talika[cli]" # Static checks for .feature files
pip install "talika[pydantic]" # Pydantic v2 output models
See the installation guide for environment setup and all available extras.
A table contract in a few lines
Start with a table that stays readable for everyone working on the scenario:
Given the users exist
| name | age | roles | active |
| Akash | 27 | Developer, Manager | yes |
| Badal | 25 | Tester | no |
Describe what those cells mean:
from talika import RowTable, boolean, field, split
class UserTable(RowTable):
name = field("name", required=True)
age: int = field("age", required=True)
roles = field("roles", parser=split(","))
active = field("active", parser=boolean(), default=True)
Then parse at the boundary of your step:
from pytest_bdd import given
@given("the users exist", target_fixture="users")
def users(datatable):
return UserTable.parse(datatable)
Your test now receives useful Python values instead of table-shaped strings:
assert users[0].name == "Akash"
assert users[0].age == 27
assert users[0].roles == ["Developer", "Manager"]
assert users[0].active is True
Bad input fails at the table boundary with source-aware diagnostics:
Field parser failed: invalid literal for int() with base 10: 'old'
(code=parser_failed, schema=UserTable, field='age', row=2, column=2, value='old').
The quickstart walks
through defaults, collected errors, source metadata, and the pytest-bdd
fixture.
Tables can have different shapes
RowTable treats the first row as labels and each following row as one record:
| name | role |
| Akash | admin |
| Badal | user |
ColumnTable treats the first column as labels and each following column as
one record—useful when each item has many attributes:
| IDs | 1 | 2 |
| Type | Article | Poll |
| Headline | Hello | Vote? |
| Published | yes | no |
Both shapes use the same field declarations, parsers, validation hooks, output models, and source-aware errors. Read choosing a table shape for the trade-offs.
Make tables speak your domain
Talika does not impose a universal table DSL. It gives your project safe hooks to own its vocabulary:
from talika import CellDSL
cells = CellDSL()
@cells.token("random", fields=("headline",))
def random_headline(context):
return context.user_data["faker"].headline()
@cells.pattern(r"(?P<count>\d+) words", fields=("body",))
def generated_words(match, context):
return context.user_data["faker"].words(int(match["count"]))
Feature authors can write compact intent such as random or 20 words, while
the project decides exactly what those phrases mean. Explore
tokens,
patterns,
and composition.
Check feature files without running scenarios
Install the CLI extra and validate tables during local development or CI:
pip install "talika[cli]"
talika check features/users.feature --schema tests.tables:UserTable --step "the users exist"
The checker uses the official Gherkin parser and can emit JSON diagnostics for editor and CI integrations. See the static checking guide for discovery, context factories, and exit codes.
Where Talika fits
Talika is deliberately focused. It is not a test runner, fixture factory, business workflow engine, or general model-validation library.
pytest-bdd still runs scenarios. Pydantic can still validate final models.
Factories can still build database objects. Talika owns the boundary between a
human-authored data table and the Python objects your test code wants to use.
Learn more
- Why Talika? — the problem it solves and how it compares with adjacent tools.
- Quickstart — build and use your first schema.
- Guides — fields, parsers, validation, variants, references, transforms, and more.
- API reference — the complete public interface.
- Changelog — releases and notable changes.
Contributing
Contributions are welcome. See CONTRIBUTING.md for the local development workflow and project checks.
License
Talika is released under the MIT License.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file talika-0.1.1.tar.gz.
File metadata
- Download URL: talika-0.1.1.tar.gz
- Upload date:
- Size: 73.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed344eeac73beb98463a9e06c850f16359cff44c6531359066ecffed80058543
|
|
| MD5 |
0523874eb7c84cf134df45be8646fe81
|
|
| BLAKE2b-256 |
6c3352ad0b279623c7d01077a9fee50c8f2c54919e6180f412231a6fe93425d9
|
Provenance
The following attestation bundles were made for talika-0.1.1.tar.gz:
Publisher:
publish-pypi.yml on talikadev/talika
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
talika-0.1.1.tar.gz -
Subject digest:
ed344eeac73beb98463a9e06c850f16359cff44c6531359066ecffed80058543 - Sigstore transparency entry: 2168368228
- Sigstore integration time:
-
Permalink:
talikadev/talika@f0a55a0ffd48c5d06a9fa07df169a7b8a81135fb -
Branch / Tag:
refs/heads/master - Owner: https://github.com/talikadev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f0a55a0ffd48c5d06a9fa07df169a7b8a81135fb -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file talika-0.1.1-py3-none-any.whl.
File metadata
- Download URL: talika-0.1.1-py3-none-any.whl
- Upload date:
- Size: 67.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e4b64080ff15cb79a7a9e859886cdfb5d4dd2c2bfcd106d7022afb165e1b610
|
|
| MD5 |
036317f375950e1d5e0562622a3fa018
|
|
| BLAKE2b-256 |
a0c60fd736c9cd5278fe2995088b5d9c06f0ef13638b662212513be5c3fc8d4d
|
Provenance
The following attestation bundles were made for talika-0.1.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on talikadev/talika
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
talika-0.1.1-py3-none-any.whl -
Subject digest:
0e4b64080ff15cb79a7a9e859886cdfb5d4dd2c2bfcd106d7022afb165e1b610 - Sigstore transparency entry: 2168368231
- Sigstore integration time:
-
Permalink:
talikadev/talika@f0a55a0ffd48c5d06a9fa07df169a7b8a81135fb -
Branch / Tag:
refs/heads/master - Owner: https://github.com/talikadev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f0a55a0ffd48c5d06a9fa07df169a7b8a81135fb -
Trigger Event:
workflow_dispatch
-
Statement type: