tinytim


Nametinytim JSON
Version 1.12.0 PyPI version JSON
download
home_pageNone
SummaryPure Python data table functions.
upload_time2025-10-19 00:07:05
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords data table dataframe pure-python lightweight
VCS
bugtrack_url
requirements hasattrs
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # TinyTim

A pure Python package for processing tabular data stored in dictionaries.

[![PyPI Latest Release](https://img.shields.io/pypi/v/tinytim.svg)](https://pypi.org/project/tinytim/)
![Tests](https://github.com/eddiethedean/tinytim/actions/workflows/tests.yml/badge.svg)
[![Python Version](https://img.shields.io/pypi/pyversions/tinytim.svg)](https://pypi.org/project/tinytim/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Description

TinyTim is a lightweight alternative to Pandas for processing tabular data. It's perfect for when you want to work with structured data but don't want to install Pandas and its many dependencies. TinyTim has **zero dependencies** outside of Python's standard library.

Data is stored in a simple dictionary format: `{column_name: column_values}`, making it easy to understand and work with.

## Features

- **Zero dependencies** - Pure Python implementation
- **Lightweight** - Minimal footprint, fast installation
- **Familiar API** - Intuitive functions for data manipulation
- **Type hints** - Full type annotations for better IDE support
- **Well tested** - Comprehensive test suite

## Installation

```bash
pip install tinytim
```

## Requirements

- Python >= 3.8

## Quick Start

### Basic Data Operations

```python
from tinytim.data import column_count, row_count, shape, head, tail

# Data is stored as {column_name: column_values}
data = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]}

# Get basic information
column_count(data)
# 2

row_count(data)
# 4

shape(data)
# (4, 2)

# Preview data
head(data, 2)
# {'x': [1, 2], 'y': [10, 20]}

tail(data, 2)
# {'x': [3, 4], 'y': [30, 40]}
```

### Working with Rows

```python
from tinytim.rows import row_dict, iterrows, row_dicts_to_data

data = {'x': [1, 2, 3], 'y': [6, 7, 8]}

# Get a single row
row_dict(data, 1)
# {'x': 2, 'y': 7}

# Iterate over rows
for index, row in iterrows(data):
    print(f"Row {index}: {row}")
# Row 0: {'x': 1, 'y': 6}
# Row 1: {'x': 2, 'y': 7}
# Row 2: {'x': 3, 'y': 8}

# Convert row dictionaries to data
rows = [{'x': 1, 'y': 20}, {'x': 2, 'y': 21}, {'x': 3, 'y': 22}]
result = row_dicts_to_data(rows)
# {'x': [1, 2, 3], 'y': [20, 21, 22]}
```

### Working with Columns

```python
from tinytim.edit import add_to_column, multiply_column

data = {'x': [1, 2, 3, 4], 'y': [5, 6, 7, 8]}

# Add to a column
result = add_to_column(data, 'x', 10)
# {'x': [11, 12, 13, 14], 'y': [5, 6, 7, 8]}

# Multiply a column
result = multiply_column(data, 'x', 2)
# {'x': [2, 4, 6, 8], 'y': [5, 6, 7, 8]}

# Column-wise operations with sequences
result = add_to_column(data, 'x', [10, 20, 30, 40])
# {'x': [11, 22, 33, 44], 'y': [5, 6, 7, 8]}
```

### Filtering and Selection

```python
from tinytim.filter import filter_by_column_gt, filter_by_column_isin

data = {'x': [1, 2, 3, 4, 5], 'y': [10, 20, 30, 40, 50]}

# Filter rows where column value is greater than threshold
filtered = filter_by_column_gt(data, 'x', 2)
# {'x': [3, 4, 5], 'y': [30, 40, 50]}

# Filter rows where column value is in a list
filtered = filter_by_column_isin(data, 'x', [1, 3, 5])
# {'x': [1, 3, 5], 'y': [10, 30, 50]}
```

### Handling Missing Values

```python
from tinytim.na import isna, dropna, fillna

data = {'x': [1, None, 3], 'y': [10, 20, None]}

# Check for missing values
isna(data)
# {'x': [False, True, False], 'y': [False, False, True]}

# Drop rows with missing values
dropna(data)
# {'x': [1], 'y': [10]}

# Fill missing values
fillna(data, 0)
# {'x': [1, 0, 3], 'y': [10, 20, 0]}

# Forward fill
data2 = {'x': [None, 2, None, 4], 'y': [10, None, None, 40]}
fillna(data2, method='ffill')
# {'x': [None, 2, 2, 4], 'y': [10, 10, 10, 40]}
```

### Grouping and Aggregation

```python
from tinytim.group import groupby, sum_groups

data = {'category': ['A', 'B', 'A', 'B'], 'value': [1, 2, 3, 4]}

# Group by column
groups = groupby(data, 'category')
# [('A', {'category': ['A', 'A'], 'value': [1, 3]}),
#  ('B', {'category': ['B', 'B'], 'value': [2, 4]})]

# Sum grouped data
labels, sums = sum_groups(groups)
# labels: ['A', 'B']
# sums: {'value': [4, 6]}
```

### Joining Data

```python
from tinytim.join import inner_join, left_join

left = {'id': [1, 2, 3], 'value': ['a', 'b', 'c']}
right = {'id': [2, 3, 4], 'score': [10, 20, 30]}

# Inner join on 'id' column
result = inner_join(left, right, 'id')
# {'id': [2, 3], 'value': ['b', 'c'], 'score': [10, 20]}

# Left join keeps all rows from left table
result = left_join(left, right, 'id')
# {'id': [1, 2, 3], 'value': ['a', 'b', 'c'], 'score': [None, 10, 20]}
```

## More Examples

### Editing Data

```python
from tinytim.edit import edit_row_items, drop_row, drop_column

data = {'name': ['Alice', 'Bob', 'Charlie'], 
        'age': [25, 30, 35], 
        'city': ['NYC', 'LA', 'SF']}

# Edit specific row values
result = edit_row_items(data, 1, {'age': 31, 'city': 'Seattle'})
# {'name': ['Alice', 'Bob', 'Charlie'], 
#  'age': [25, 31, 35], 
#  'city': ['NYC', 'Seattle', 'SF']}

# Drop a row
result = drop_row(data, 0)
# {'name': ['Bob', 'Charlie'], 'age': [30, 35], 'city': ['LA', 'SF']}

# Drop a column
result = drop_column(data, 'city')
# {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}
```

### Inserting Data

```python
from tinytim.insert import insert_row, insert_rows

data = {'x': [1, 2], 'y': [10, 20]}

# Insert a single row
result = insert_row(data, {'x': 3, 'y': 30})
# {'x': [1, 2, 3], 'y': [10, 20, 30]}

# Insert multiple rows
rows = [{'x': 4, 'y': 40}, {'x': 5, 'y': 50}]
result = insert_rows(data, rows)
# {'x': [1, 2, 4, 5], 'y': [10, 20, 40, 50]}
```

### Advanced Filtering

```python
from tinytim.filter import (
    filter_by_column_eq,
    filter_by_column_ne, 
    filter_by_column_le,
    sample
)

data = {'product': ['A', 'B', 'A', 'C', 'B'], 
        'price': [10, 20, 15, 30, 25]}

# Filter by equality
result = filter_by_column_eq(data, 'product', 'A')
# {'product': ['A', 'A'], 'price': [10, 15]}

# Filter by inequality
result = filter_by_column_ne(data, 'product', 'A')
# {'product': ['B', 'C', 'B'], 'price': [20, 30, 25]}

# Filter by less than or equal
result = filter_by_column_le(data, 'price', 20)
# {'product': ['A', 'B', 'A'], 'price': [10, 20, 15]}

# Random sample
result = sample(data, 2, random_state=42)
# Returns 2 random rows (deterministic with random_state)
```

### Copying Data

```python
from tinytim.copy import copy_table, deepcopy_table

data = {'x': [1, 2, 3], 'y': [[10], [20], [30]]}

# Shallow copy (copies dict and lists)
copy1 = copy_table(data)

# Deep copy (copies everything recursively)
copy2 = deepcopy_table(data)
copy2['y'][0][0] = 999
# Original data unchanged: data['y'][0][0] == 10
```

## Development

### Setting up a development environment

```bash
# Clone the repository
git clone https://github.com/eddiethedean/tinytim.git
cd tinytim

# Install development dependencies
pip install -e ".[dev]"

# Or use the requirements file
pip install -r requirements_dev.txt
```

### Running Tests

```bash
# Run tests with pytest
pytest

# Run tests with coverage
pytest --cov=tinytim

# Run tests across multiple Python versions
tox
```

### Linting and Type Checking

```bash
# Lint with ruff
ruff check src tests

# Format code with ruff
ruff format src tests

# Type check with mypy
mypy src
```

### Pre-commit Hooks

```bash
# Install pre-commit hooks
pip install pre-commit
pre-commit install

# Run hooks manually
pre-commit run --all-files
```

## Examples

See the [examples](https://github.com/eddiethedean/tinytim/tree/main/examples) directory for Jupyter notebooks demonstrating various features:

- [data.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/data.ipynb) - Basic data operations
- [rows.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/rows.ipynb) - Working with rows
- [columns.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/columns.ipynb) - Working with columns
- [join.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/join.ipynb) - Joining datasets
- [group.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/group.ipynb) - Grouping and aggregation
- [fillna.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/fillna.ipynb) - Handling missing values

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Author

**Odos Matthews** - [odosmatthews@gmail.com](mailto:odosmatthews@gmail.com)

## License

This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/eddiethedean/tinytim/blob/main/LICENSE.md) file for details.

## Why TinyTim?

TinyTim is ideal for:

- **Embedded systems** or environments with limited resources
- **Lambda functions** or serverless applications where package size matters
- **Learning** data manipulation concepts without the complexity of Pandas
- **Scripts** where you need basic data operations without heavy dependencies
- **Distribution** of tools where you want to minimize user installation burden

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tinytim",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "data, table, dataframe, pure-python, lightweight",
    "author": null,
    "author_email": "Odos Matthews <odosmatthews@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/41/43/ec22b6621f10b1f35a8f50b92d08abd861e35ebe4ef89c8c0d2547bb813f/tinytim-1.12.0.tar.gz",
    "platform": null,
    "description": "# TinyTim\n\nA pure Python package for processing tabular data stored in dictionaries.\n\n[![PyPI Latest Release](https://img.shields.io/pypi/v/tinytim.svg)](https://pypi.org/project/tinytim/)\n![Tests](https://github.com/eddiethedean/tinytim/actions/workflows/tests.yml/badge.svg)\n[![Python Version](https://img.shields.io/pypi/pyversions/tinytim.svg)](https://pypi.org/project/tinytim/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Description\n\nTinyTim is a lightweight alternative to Pandas for processing tabular data. It's perfect for when you want to work with structured data but don't want to install Pandas and its many dependencies. TinyTim has **zero dependencies** outside of Python's standard library.\n\nData is stored in a simple dictionary format: `{column_name: column_values}`, making it easy to understand and work with.\n\n## Features\n\n- **Zero dependencies** - Pure Python implementation\n- **Lightweight** - Minimal footprint, fast installation\n- **Familiar API** - Intuitive functions for data manipulation\n- **Type hints** - Full type annotations for better IDE support\n- **Well tested** - Comprehensive test suite\n\n## Installation\n\n```bash\npip install tinytim\n```\n\n## Requirements\n\n- Python >= 3.8\n\n## Quick Start\n\n### Basic Data Operations\n\n```python\nfrom tinytim.data import column_count, row_count, shape, head, tail\n\n# Data is stored as {column_name: column_values}\ndata = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]}\n\n# Get basic information\ncolumn_count(data)\n# 2\n\nrow_count(data)\n# 4\n\nshape(data)\n# (4, 2)\n\n# Preview data\nhead(data, 2)\n# {'x': [1, 2], 'y': [10, 20]}\n\ntail(data, 2)\n# {'x': [3, 4], 'y': [30, 40]}\n```\n\n### Working with Rows\n\n```python\nfrom tinytim.rows import row_dict, iterrows, row_dicts_to_data\n\ndata = {'x': [1, 2, 3], 'y': [6, 7, 8]}\n\n# Get a single row\nrow_dict(data, 1)\n# {'x': 2, 'y': 7}\n\n# Iterate over rows\nfor index, row in iterrows(data):\n    print(f\"Row {index}: {row}\")\n# Row 0: {'x': 1, 'y': 6}\n# Row 1: {'x': 2, 'y': 7}\n# Row 2: {'x': 3, 'y': 8}\n\n# Convert row dictionaries to data\nrows = [{'x': 1, 'y': 20}, {'x': 2, 'y': 21}, {'x': 3, 'y': 22}]\nresult = row_dicts_to_data(rows)\n# {'x': [1, 2, 3], 'y': [20, 21, 22]}\n```\n\n### Working with Columns\n\n```python\nfrom tinytim.edit import add_to_column, multiply_column\n\ndata = {'x': [1, 2, 3, 4], 'y': [5, 6, 7, 8]}\n\n# Add to a column\nresult = add_to_column(data, 'x', 10)\n# {'x': [11, 12, 13, 14], 'y': [5, 6, 7, 8]}\n\n# Multiply a column\nresult = multiply_column(data, 'x', 2)\n# {'x': [2, 4, 6, 8], 'y': [5, 6, 7, 8]}\n\n# Column-wise operations with sequences\nresult = add_to_column(data, 'x', [10, 20, 30, 40])\n# {'x': [11, 22, 33, 44], 'y': [5, 6, 7, 8]}\n```\n\n### Filtering and Selection\n\n```python\nfrom tinytim.filter import filter_by_column_gt, filter_by_column_isin\n\ndata = {'x': [1, 2, 3, 4, 5], 'y': [10, 20, 30, 40, 50]}\n\n# Filter rows where column value is greater than threshold\nfiltered = filter_by_column_gt(data, 'x', 2)\n# {'x': [3, 4, 5], 'y': [30, 40, 50]}\n\n# Filter rows where column value is in a list\nfiltered = filter_by_column_isin(data, 'x', [1, 3, 5])\n# {'x': [1, 3, 5], 'y': [10, 30, 50]}\n```\n\n### Handling Missing Values\n\n```python\nfrom tinytim.na import isna, dropna, fillna\n\ndata = {'x': [1, None, 3], 'y': [10, 20, None]}\n\n# Check for missing values\nisna(data)\n# {'x': [False, True, False], 'y': [False, False, True]}\n\n# Drop rows with missing values\ndropna(data)\n# {'x': [1], 'y': [10]}\n\n# Fill missing values\nfillna(data, 0)\n# {'x': [1, 0, 3], 'y': [10, 20, 0]}\n\n# Forward fill\ndata2 = {'x': [None, 2, None, 4], 'y': [10, None, None, 40]}\nfillna(data2, method='ffill')\n# {'x': [None, 2, 2, 4], 'y': [10, 10, 10, 40]}\n```\n\n### Grouping and Aggregation\n\n```python\nfrom tinytim.group import groupby, sum_groups\n\ndata = {'category': ['A', 'B', 'A', 'B'], 'value': [1, 2, 3, 4]}\n\n# Group by column\ngroups = groupby(data, 'category')\n# [('A', {'category': ['A', 'A'], 'value': [1, 3]}),\n#  ('B', {'category': ['B', 'B'], 'value': [2, 4]})]\n\n# Sum grouped data\nlabels, sums = sum_groups(groups)\n# labels: ['A', 'B']\n# sums: {'value': [4, 6]}\n```\n\n### Joining Data\n\n```python\nfrom tinytim.join import inner_join, left_join\n\nleft = {'id': [1, 2, 3], 'value': ['a', 'b', 'c']}\nright = {'id': [2, 3, 4], 'score': [10, 20, 30]}\n\n# Inner join on 'id' column\nresult = inner_join(left, right, 'id')\n# {'id': [2, 3], 'value': ['b', 'c'], 'score': [10, 20]}\n\n# Left join keeps all rows from left table\nresult = left_join(left, right, 'id')\n# {'id': [1, 2, 3], 'value': ['a', 'b', 'c'], 'score': [None, 10, 20]}\n```\n\n## More Examples\n\n### Editing Data\n\n```python\nfrom tinytim.edit import edit_row_items, drop_row, drop_column\n\ndata = {'name': ['Alice', 'Bob', 'Charlie'], \n        'age': [25, 30, 35], \n        'city': ['NYC', 'LA', 'SF']}\n\n# Edit specific row values\nresult = edit_row_items(data, 1, {'age': 31, 'city': 'Seattle'})\n# {'name': ['Alice', 'Bob', 'Charlie'], \n#  'age': [25, 31, 35], \n#  'city': ['NYC', 'Seattle', 'SF']}\n\n# Drop a row\nresult = drop_row(data, 0)\n# {'name': ['Bob', 'Charlie'], 'age': [30, 35], 'city': ['LA', 'SF']}\n\n# Drop a column\nresult = drop_column(data, 'city')\n# {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}\n```\n\n### Inserting Data\n\n```python\nfrom tinytim.insert import insert_row, insert_rows\n\ndata = {'x': [1, 2], 'y': [10, 20]}\n\n# Insert a single row\nresult = insert_row(data, {'x': 3, 'y': 30})\n# {'x': [1, 2, 3], 'y': [10, 20, 30]}\n\n# Insert multiple rows\nrows = [{'x': 4, 'y': 40}, {'x': 5, 'y': 50}]\nresult = insert_rows(data, rows)\n# {'x': [1, 2, 4, 5], 'y': [10, 20, 40, 50]}\n```\n\n### Advanced Filtering\n\n```python\nfrom tinytim.filter import (\n    filter_by_column_eq,\n    filter_by_column_ne, \n    filter_by_column_le,\n    sample\n)\n\ndata = {'product': ['A', 'B', 'A', 'C', 'B'], \n        'price': [10, 20, 15, 30, 25]}\n\n# Filter by equality\nresult = filter_by_column_eq(data, 'product', 'A')\n# {'product': ['A', 'A'], 'price': [10, 15]}\n\n# Filter by inequality\nresult = filter_by_column_ne(data, 'product', 'A')\n# {'product': ['B', 'C', 'B'], 'price': [20, 30, 25]}\n\n# Filter by less than or equal\nresult = filter_by_column_le(data, 'price', 20)\n# {'product': ['A', 'B', 'A'], 'price': [10, 20, 15]}\n\n# Random sample\nresult = sample(data, 2, random_state=42)\n# Returns 2 random rows (deterministic with random_state)\n```\n\n### Copying Data\n\n```python\nfrom tinytim.copy import copy_table, deepcopy_table\n\ndata = {'x': [1, 2, 3], 'y': [[10], [20], [30]]}\n\n# Shallow copy (copies dict and lists)\ncopy1 = copy_table(data)\n\n# Deep copy (copies everything recursively)\ncopy2 = deepcopy_table(data)\ncopy2['y'][0][0] = 999\n# Original data unchanged: data['y'][0][0] == 10\n```\n\n## Development\n\n### Setting up a development environment\n\n```bash\n# Clone the repository\ngit clone https://github.com/eddiethedean/tinytim.git\ncd tinytim\n\n# Install development dependencies\npip install -e \".[dev]\"\n\n# Or use the requirements file\npip install -r requirements_dev.txt\n```\n\n### Running Tests\n\n```bash\n# Run tests with pytest\npytest\n\n# Run tests with coverage\npytest --cov=tinytim\n\n# Run tests across multiple Python versions\ntox\n```\n\n### Linting and Type Checking\n\n```bash\n# Lint with ruff\nruff check src tests\n\n# Format code with ruff\nruff format src tests\n\n# Type check with mypy\nmypy src\n```\n\n### Pre-commit Hooks\n\n```bash\n# Install pre-commit hooks\npip install pre-commit\npre-commit install\n\n# Run hooks manually\npre-commit run --all-files\n```\n\n## Examples\n\nSee the [examples](https://github.com/eddiethedean/tinytim/tree/main/examples) directory for Jupyter notebooks demonstrating various features:\n\n- [data.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/data.ipynb) - Basic data operations\n- [rows.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/rows.ipynb) - Working with rows\n- [columns.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/columns.ipynb) - Working with columns\n- [join.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/join.ipynb) - Joining datasets\n- [group.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/group.ipynb) - Grouping and aggregation\n- [fillna.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/fillna.ipynb) - Handling missing values\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Author\n\n**Odos Matthews** - [odosmatthews@gmail.com](mailto:odosmatthews@gmail.com)\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](https://github.com/eddiethedean/tinytim/blob/main/LICENSE.md) file for details.\n\n## Why TinyTim?\n\nTinyTim is ideal for:\n\n- **Embedded systems** or environments with limited resources\n- **Lambda functions** or serverless applications where package size matters\n- **Learning** data manipulation concepts without the complexity of Pandas\n- **Scripts** where you need basic data operations without heavy dependencies\n- **Distribution** of tools where you want to minimize user installation burden\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Pure Python data table functions.",
    "version": "1.12.0",
    "project_urls": {
        "Homepage": "https://github.com/eddiethedean/tinytim",
        "Issues": "https://github.com/eddiethedean/tinytim/issues",
        "Repository": "https://github.com/eddiethedean/tinytim"
    },
    "split_keywords": [
        "data",
        " table",
        " dataframe",
        " pure-python",
        " lightweight"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d86130cd1335d30aeafca31858ab501ccb2f5c829bff197d957be7ca3634b6bd",
                "md5": "9e8d56daa1ec96b9befd5ef50005ca4d",
                "sha256": "fec2bd5054a439121547982b836c708eaabe6f7f5e4128af82007989134ad0f9"
            },
            "downloads": -1,
            "filename": "tinytim-1.12.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9e8d56daa1ec96b9befd5ef50005ca4d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 33012,
            "upload_time": "2025-10-19T00:07:04",
            "upload_time_iso_8601": "2025-10-19T00:07:04.136635Z",
            "url": "https://files.pythonhosted.org/packages/d8/61/30cd1335d30aeafca31858ab501ccb2f5c829bff197d957be7ca3634b6bd/tinytim-1.12.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4143ec22b6621f10b1f35a8f50b92d08abd861e35ebe4ef89c8c0d2547bb813f",
                "md5": "0a013413c67d8e8fcd2dcb4bb3f00cb8",
                "sha256": "6bc53b5e33cd19445107ab62f5997f5f621e9360c82287852f4f39f11162a9ee"
            },
            "downloads": -1,
            "filename": "tinytim-1.12.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0a013413c67d8e8fcd2dcb4bb3f00cb8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 44054,
            "upload_time": "2025-10-19T00:07:05",
            "upload_time_iso_8601": "2025-10-19T00:07:05.438096Z",
            "url": "https://files.pythonhosted.org/packages/41/43/ec22b6621f10b1f35a8f50b92d08abd861e35ebe4ef89c8c0d2547bb813f/tinytim-1.12.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-19 00:07:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "eddiethedean",
    "github_project": "tinytim",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "hasattrs",
            "specs": [
                [
                    ">=",
                    "0.0.2"
                ]
            ]
        }
    ],
    "tox": true,
    "lcname": "tinytim"
}
        
Elapsed time: 1.46899s