Skip to main content

An unofficial implementation of the Camtrap DP 1.0.2 datapackage standard with explicit Python dataclasses and pydantic. Intended to help developers with exporting their data to the Camtrap DP 1.0.2 datapackage format.

Project description

PyPI version Python Versions CI Status Code style: ruff License: MIT

trap-schema

An unofficial, strictly-typed implementation of the Camtrap DP 1.0.2 datapackage standard.

trap-schema uses Python dataclasses and Pydantic to provide robust, schema-aware data structures. It is designed to help developers easily parse, validate, and export camera trap data into the official Frictionless Data format without second-guessing schema constraints or having the documentation open on a second monitor.

Features

  • Strict Validation: Built on pydantic to enforce constraints (e.g., coordinate bounds, unique IDs, valid media types) at instantiation.
  • Ergonomic Tables: Treat tabular data natively. Tables act as columnar data structures but guarantee per-row validation.
  • Auto-Synced Documentation: Docstrings and schema attributes are automatically kept in sync with the official Camtrap DP JSON Schemas using a custom AST transformer.

Installation

This project uses uv for fast and reliable package management.

To add trap-schema to your project:

uv add trap-schema

Quick Start

trap-schema is made primarily to facilate immediate errors via static analysis in your IDE or exceptions, so the following example does not show how you actually transform your data, merely how the interface for the containers in trap-schema are supposed to be used.

# All Camtrap DP 1.0.2 Resources
from trap_schema import (
    Contributor,
    DataPackage,
    Dataset,
    DeploymentsRow,
    DeploymentsTable,
    License,
    MediaRow,
    MediaTable,
    ObservationsRow,
    ObservationsTable,
    Project,
    RelatedIdentifiers,
    Resource,
    Source,
    Taxonomic,
    Temporal,
)

# 1. Create validated rows
deployments_row = DeploymentsRow(
    deploymentID="dep_001",
    latitude=56.2,
    longitude=10.4,
    deploymentStart="2026-04-25T10:00:00Z",
    deploymentEnd="2026-05-25T10:00:00Z",
)

# 2. Group into a Table (validates unique keys and types)
deployments = DeploymentsTable(rows=[deployment])

# 3. Export table 
# (all file-backed resources share a `.save()` and `.load()` function for reading and loading to/from file)
deployments.save("out_dir")

# 4. Do the same for the other tables
media_data = ...
observations_data = ...
# (all row types can be created from a dictionary)
media_rows = [MediaRow.from_dict(data) for data in media_data]
observation_rows = [ObservationsRow.from_dict(data) for data in observations_data]
# (all tables are created via a list of rows)
media = MediaTable(rows=media_rows)
observations = ObservationsTable(rows=observations_rows)

# 5. Create the datapackage object
# (the `resources` and `profile` fields cannot be changed since they are "hardcoded" via the standard)
# * technically the standard allows additional resources, but this is a TODO for trap-schema
datapackage = DataPackage(
    name="my_dataset",
    id="...",
    ...,
    contributors=[
        Contributor(
            ...
        ),
        Contributor(
            ...
        )
    ],
    ...
) # See the docstring and/or https://camtrap-dp.tdwg.org/metadata/ for further details

# 6. Create the dataset
dataset = Dataset(
    datapackage=datapackage,
    deployments=deployments,
    media=media,
    observations=observations
)

# 7. Export dataset
dataset.save("<output_dir>")

# 8. (optional) Load dataset
# You can also load an existing dataset via:
new_dataset = Dataset.load("<dataset_dir>")
# or individual ressources
new_observations = ObservationsTable.load("<dataset_dir>")
# or
new_observations = ObservationsTable.load("<dataset_dir>/observations.csv")
# etc.

Run validation with frictionless via:

uvx frictionless validate <output_dir>/datapackage.json

Development

git clone https://github.com/asgersvenning/trap-schema.git
cd trap-schema
uv sync --all-groups

Update docstrings

We use libcst and frictionless to seamlessly and automatically integrate the official docstrings for table and metadata fields.

To update these run:

uv run tools/docstrings.py

Linting

[uv] ruff check --ignore E501

Testing

uv run pytest tests

License

MIT

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

trap_schema-0.2.0.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trap_schema-0.2.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file trap_schema-0.2.0.tar.gz.

File metadata

  • Download URL: trap_schema-0.2.0.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for trap_schema-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8093ddab8118a5e639126b972784b41c05f4dd868d9b81ec3f1036bef09c6548
MD5 5cb81b31d4259f8305545c4390f654a1
BLAKE2b-256 8d860d73d521fcf30238da1eb7d1b8200e39a6685d76e87dfb836ed86ecca3c8

See more details on using hashes here.

File details

Details for the file trap_schema-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: trap_schema-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for trap_schema-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e57028fcb0a8390f1f173cbfa7b5b35e0a78dd841c5811458c6e553cc6bf0b35
MD5 f550b8474f9e5f17a9bd1c75a2a19999
BLAKE2b-256 e02514c7e6874462b990134997acd97f48b002666bf31671afae7fe09e8694f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page