Name | hotcore JSON |
Version |
1.2.0
JSON |
| download |
home_page | None |
Summary | A Redis-based hierarchical entity model for application data management |
upload_time | 2025-10-17 22:21:33 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | MIT License
Copyright (c) 2024 Magnus Dahl
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
|
keywords |
redis
data-model
geospatial
hierarchical
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# hotcore
A Redis-backed entity model for managing hierarchical structured data with relationship support and attribute-based search capabilities.
## Overview
Hotcore provides a clean, Redis-backed data model for applications that need hierarchical data storage with powerful querying capabilities. It organizes entities in parent-child relationships and indexes all attributes automatically for efficient searching.
### Key Features
- **Hierarchical Structure**: Organize entities in a tree-like parent-child structure
- **Attribute-Based Search**: Find entities by exact values or patterns (wildcards)
- **Geospatial Search**: Automatic geospatial indexing and bounding box search for entities with coordinates
- **Optimistic Locking**: Safely modify entities in concurrent environments
- **Automatic Indexing**: All entity attributes are automatically indexed for fast retrieval
- **Type Hinting**: Comprehensive type annotations for improved IDE support
- **Error Handling**: Robust error handling with informative messages
## Installation
### Prerequisites
- Python 3.10+
- Redis server (local or remote)
### Setup
1. Install the package:
```bash
# From PyPI (minimal installation)
pip install hotcore
# For development with all tools
pip install -r requirements-dev.txt
# From source (minimal installation)
git clone https://github.com/your-org/hotcore.git
cd hotcore
pip install -e .
# Development installation with all tools
pip install -e ".[dev]"
# Enable geospatial extras (includes Uber's h3 library)
pip install -e ".[h3]"
```
2. Make sure Redis is running:
```bash
# Local Redis server (default)
redis-server
# Or connect to a remote Redis instance in your code
```
## Quick Start
```python
from hotcore import Model
# Initialize the model (connects to Redis)
model = Model(host='localhost') # Default port is 6379
# Create a root entity
root = model.init({}) # Generates a UUID automatically
root['name'] = 'Root Entity'
root['type'] = 'container'
model.create('root', root) # 'root' is a special parent ID for root entities
# Create a child entity
child = model.init({})
child['name'] = 'Child Entity'
child['type'] = 'item'
child['status'] = 'active'
model.create(root['uuid'], child) # Root UUID as parent
# Retrieve an entity
entity = model.get(child['uuid'])
print(entity) # {'uuid': '...', 'name': 'Child Entity', 'type': 'item', 'status': 'active'}
# Update an entity
changes = {'uuid': child['uuid'], 'status': 'inactive', 'priority': 'high'}
model.apply(changes)
# Delete an entity
model.delete(child)
# Find entities by attribute values
for entity in model.find(type='item', status='active'):
print(entity)
# Find entities with pattern matching (wildcards)
for entity in model.find(name='Child*'):
print(entity)
# Geospatial search for entities within a bounding box
# (entities with 'lat' and 'long' attributes are automatically indexed)
entities_in_nyc = model.search_bounding_box(40.0, 41.0, -74.0, -73.0)
for entity in entities_in_nyc:
print(f"{entity['name']} at ({entity['lat']}, {entity['long']})")
# Get all children of a parent
for child in model.get_children(root['uuid']):
print(child)
# Get parent of an entity
parent = model.get_parent(child['uuid'])
print(parent)
```
## Project Structure
- `hotcore/model.py` – Facade that wires storage, relationships, search, geospatial, and optional H3 indexing.
- `hotcore/connection.py` – Redis connection pooling and key helpers.
- `hotcore/storage.py` – CRUD operations with attribute indexing.
- `hotcore/relationships.py` – Parent/child traversal utilities.
- `hotcore/search.py` – Attribute-based and wildcard search helpers.
- `hotcore/geospatial.py` – Redis GEO index management.
- `hotcore/h3_index.py` – Optional Uber H3 integration (requires `hotcore[h3]`).
- `hotcore/hotcore.py` – Compatibility exports for the legacy import surface.
Unit and integration tests live under `tests/`; see `tests/README.md` for an overview.
## Data Model Concepts
### Entities
An entity is a dictionary-like object with attributes:
- Must have a `uuid` attribute (automatically generated by `model.init()`)
- Can contain any number of key-value pairs (attributes)
- Values should be strings for optimal indexing and searching
- **Geospatial Support**: Entities with `lat` and `long` attributes are automatically added to a Redis geospatial index
### Relationships
- Each entity can have one parent (except root entities)
- Each entity can have multiple children
- The parent-child relationship forms a tree structure
### Indexing
- All entity attributes are automatically indexed
- Indexes enable fast lookup by attribute value
- Pattern-based searches are supported (using wildcards)
## Advanced Usage
### Optimistic Locking
The model uses optimistic locking to handle concurrent modifications:
```python
# If two processes try to modify the same entity simultaneously,
# one will succeed and the other will automatically retry (up to 3 times by default)
```
### Pattern Matching
You can use Redis pattern matching in searches:
```python
# Find entities with names starting with "A"
for entity in model.find(name='A*'):
print(entity)
# Find entities with specific pattern in type
for entity in model.find(type='user_?????'):
print(entity)
# Find entities with names containing specific characters
for entity in model.find(name='*[Aa]dmin*'):
print(entity)
```
### Combining Search Criteria
When multiple criteria are provided, all must match (logical AND):
```python
# Find active users with admin role
for entity in model.find(type='user', status='active', role='admin'):
print(entity)
```
### Geospatial Search
Hotcore automatically manages geospatial indexing for entities with `lat` and `long` attributes:
```python
# Create entities with coordinates (automatically indexed)
user1 = model.init({
'name': 'Alice Johnson',
'type': 'user',
'lat': 40.7128, # NYC latitude
'long': -74.0060 # NYC longitude
})
model.create('root', user1)
user2 = model.init({
'name': 'Bob Smith',
'type': 'user',
'lat': 34.0522, # LA latitude
'long': -118.2437 # LA longitude
})
model.create('root', user2)
# Search for entities within a bounding box by type
nyc_users = model.search_bounding_box(40.0, 41.0, -74.0, -73.0, "user")
for user in nyc_users:
print(f"{user['name']} in NYC area")
# Update coordinates (automatically updates geospatial index)
changes = {
'uuid': user1['uuid'],
'lat': 42.3601, # Boston latitude
'long': -71.0589 # Boston longitude
}
model.apply(changes)
# Search again to see updated locations
boston_users = model.search_bounding_box(42.0, 43.0, -72.0, -71.0)
```
**Key Features:**
- **Automatic Indexing**: Entities with `lat` and `long` are automatically added to the geospatial index
- **Transparent Updates**: Coordinate changes automatically update the geospatial index
- **Bounding Box Search**: Find entities within rectangular geographic areas
- **Performance**: O(log(N)) for adding/updating, O(N+log(M)) for searching
- **Validation**: Coordinates are validated to ensure they're within valid ranges (-90 to 90° lat, -180 to 180° lon)
## API Reference
### Model Class
#### Initialization
- `Model(host='localhost', port=6379, db=0)`: Initialize the model with Redis connection parameters
#### Entity Management
- `init(entity: dict) -> dict`: Add a UUID to an entity dictionary
- `create(parent_uuid: str, entity: dict) -> dict`: Create and save a new entity
- `get(entity_uuid: str) -> dict`: Retrieve an entity by its UUID
- `apply(change: dict) -> None`: Apply changes to an existing entity
- `delete(entity: dict) -> None`: Delete an entity
#### Relationships
- `get_children(parent_uuid: str) -> Generator[dict]`: Get all children of a parent entity
- `get_parent(child_uuid: str) -> dict`: Get the parent of an entity
#### Search
- `find(**kwargs) -> Generator[dict]`: Find entities matching attribute criteria
- `get_entity_from_index(index_hit: str) -> Generator[dict]`: Get entities from a specific index
- `search_bounding_box(min_lat, max_lat, min_lon, max_lon, entity_type="default") -> List[dict]`: Search for entities of a specific type within a geographic bounding box
## Best Practices
1. **Use UUIDs for entity identification**: Generate UUIDs using `model.init({})`
2. **Keep attributes as strings**: For optimal indexing and searching
3. **Manage entity lifecycle**: Create, update, and delete entities using the model API
4. **Use pattern matching judiciously**: Wildcard searches can be powerful but resource-intensive
5. **Handle errors**: Implement proper error handling for potential Redis errors
6. **Geospatial coordinates**: Use `lat` and `long` attributes for automatic geospatial indexing and search
## Performance Considerations
1. **Connection Pooling**: The model uses Redis connection pooling for optimal performance
2. **Pipelines**: Operations use Redis pipelines to minimize network roundtrips
3. **Optimistic Locking**: Helps maintain data consistency with minimal performance impact
4. **Temporary Sets**: Complex searches using wildcards create temporary sets that expire after 60 seconds
## Testing
Hotcore's test suite is designed to work without requiring a Redis server for most tests. We use fakeredis to simulate Redis functionality for unit and integration tests.
### Running Tests
```bash
# Run tests using the provided script
./run_tests.sh
# Run only unit tests
./run_tests.sh --unit
# Run only integration tests
./run_tests.sh --integration
# Run tests with coverage report
./run_tests.sh --cov
# Run with a real Redis server
./run_tests.sh --real-redis
```
#### With Virtual Environment (venv)
```bash
# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests that don't require Redis
python -m pytest tests/unit/ tests/integration/
# Run all tests including those requiring Redis
USE_REAL_REDIS=true python -m pytest
```
#### With System Python
```bash
# Install development dependencies
pip install -r requirements-dev.txt
# Run tests that don't require Redis
python -m pytest tests/unit/ tests/integration/
# Run all tests including those requiring Redis
USE_REAL_REDIS=true python -m pytest
```
### Test Organization
The tests are organized to minimize Redis server dependencies:
- `tests/unit/` - Unit tests (no Redis server needed, uses fakeredis)
- `tests/integration/` - Integration tests (no Redis server needed, uses fakeredis)
- `tests/real_redis/` - Tests that require a real Redis server (skipped by default)
For more details, see the [tests README](tests/README.md).
## Development
- Read the [contribution guide](CONTRIBUTING.md) for environment setup, coding standards, and release process.
- All contributions are covered by our [Code of Conduct](CODE_OF_CONDUCT.md).
- Security issues should be reported privately (see [SECURITY.md](SECURITY.md)).
## Testing Strategy
- Default test runs use `fakeredis` and cover both unit and integration suites (`pytest` or `./run_tests.sh`).
- Tests that require a real Redis instance live in `tests/real_redis/` and are marked with `@pytest.mark.redis_required`.
- Optional geospatial features can be exercised by installing `hotcore[h3]`; related tests skip automatically when H3 is unavailable.
- CI (planned) will enforce formatting (`black`, `isort`), linting (`flake8`), type checks (`mypy`), and the full pytest suite across supported Python versions.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Optional Dependencies
- `hotcore[h3]`: Enables H3-based geospatial indexing via Uber's [`h3`](https://github.com/uber/h3-py) library (Apache License 2.0).
## Third-Party Notices
This project distributes under the MIT License. Optional geospatial functionality depends on Uber's `h3` library, which is available under the Apache License 2.0.
## License
[MIT License](LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "hotcore",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "redis, data-model, geospatial, hierarchical",
"author": null,
"author_email": "Magnus Dahl <magnus.dahl@consistis.com>",
"download_url": "https://files.pythonhosted.org/packages/a4/cd/9c83db29921a6396975eacff2b67b5146859190caa28d4c7b87e851efbd3/hotcore-1.2.0.tar.gz",
"platform": null,
"description": "# hotcore\n\nA Redis-backed entity model for managing hierarchical structured data with relationship support and attribute-based search capabilities.\n\n## Overview\n\nHotcore provides a clean, Redis-backed data model for applications that need hierarchical data storage with powerful querying capabilities. It organizes entities in parent-child relationships and indexes all attributes automatically for efficient searching.\n\n### Key Features\n\n- **Hierarchical Structure**: Organize entities in a tree-like parent-child structure\n- **Attribute-Based Search**: Find entities by exact values or patterns (wildcards)\n- **Geospatial Search**: Automatic geospatial indexing and bounding box search for entities with coordinates\n- **Optimistic Locking**: Safely modify entities in concurrent environments\n- **Automatic Indexing**: All entity attributes are automatically indexed for fast retrieval\n- **Type Hinting**: Comprehensive type annotations for improved IDE support\n- **Error Handling**: Robust error handling with informative messages\n\n## Installation\n\n### Prerequisites\n\n- Python 3.10+\n- Redis server (local or remote)\n\n### Setup\n\n1. Install the package:\n```bash\n# From PyPI (minimal installation)\npip install hotcore\n\n# For development with all tools\npip install -r requirements-dev.txt\n\n# From source (minimal installation)\ngit clone https://github.com/your-org/hotcore.git\ncd hotcore\npip install -e .\n\n# Development installation with all tools\npip install -e \".[dev]\"\n\n# Enable geospatial extras (includes Uber's h3 library)\npip install -e \".[h3]\"\n```\n\n2. Make sure Redis is running:\n```bash\n# Local Redis server (default)\nredis-server\n\n# Or connect to a remote Redis instance in your code\n```\n\n## Quick Start\n\n```python\nfrom hotcore import Model\n\n# Initialize the model (connects to Redis)\nmodel = Model(host='localhost') # Default port is 6379\n\n# Create a root entity\nroot = model.init({}) # Generates a UUID automatically\nroot['name'] = 'Root Entity'\nroot['type'] = 'container'\nmodel.create('root', root) # 'root' is a special parent ID for root entities\n\n# Create a child entity\nchild = model.init({})\nchild['name'] = 'Child Entity'\nchild['type'] = 'item'\nchild['status'] = 'active'\nmodel.create(root['uuid'], child) # Root UUID as parent\n\n# Retrieve an entity\nentity = model.get(child['uuid'])\nprint(entity) # {'uuid': '...', 'name': 'Child Entity', 'type': 'item', 'status': 'active'}\n\n# Update an entity\nchanges = {'uuid': child['uuid'], 'status': 'inactive', 'priority': 'high'}\nmodel.apply(changes)\n\n# Delete an entity\nmodel.delete(child)\n\n# Find entities by attribute values\nfor entity in model.find(type='item', status='active'):\n print(entity)\n\n# Find entities with pattern matching (wildcards)\nfor entity in model.find(name='Child*'):\n print(entity)\n\n# Geospatial search for entities within a bounding box\n# (entities with 'lat' and 'long' attributes are automatically indexed)\nentities_in_nyc = model.search_bounding_box(40.0, 41.0, -74.0, -73.0)\nfor entity in entities_in_nyc:\n print(f\"{entity['name']} at ({entity['lat']}, {entity['long']})\")\n\n# Get all children of a parent\nfor child in model.get_children(root['uuid']):\n print(child)\n\n# Get parent of an entity\nparent = model.get_parent(child['uuid'])\nprint(parent)\n```\n\n## Project Structure\n\n- `hotcore/model.py` \u2013 Facade that wires storage, relationships, search, geospatial, and optional H3 indexing.\n- `hotcore/connection.py` \u2013 Redis connection pooling and key helpers.\n- `hotcore/storage.py` \u2013 CRUD operations with attribute indexing.\n- `hotcore/relationships.py` \u2013 Parent/child traversal utilities.\n- `hotcore/search.py` \u2013 Attribute-based and wildcard search helpers.\n- `hotcore/geospatial.py` \u2013 Redis GEO index management.\n- `hotcore/h3_index.py` \u2013 Optional Uber H3 integration (requires `hotcore[h3]`).\n- `hotcore/hotcore.py` \u2013 Compatibility exports for the legacy import surface.\n\nUnit and integration tests live under `tests/`; see `tests/README.md` for an overview.\n\n## Data Model Concepts\n\n### Entities\n\nAn entity is a dictionary-like object with attributes:\n- Must have a `uuid` attribute (automatically generated by `model.init()`)\n- Can contain any number of key-value pairs (attributes)\n- Values should be strings for optimal indexing and searching\n- **Geospatial Support**: Entities with `lat` and `long` attributes are automatically added to a Redis geospatial index\n\n### Relationships\n\n- Each entity can have one parent (except root entities)\n- Each entity can have multiple children\n- The parent-child relationship forms a tree structure\n\n### Indexing\n\n- All entity attributes are automatically indexed\n- Indexes enable fast lookup by attribute value\n- Pattern-based searches are supported (using wildcards)\n\n## Advanced Usage\n\n### Optimistic Locking\n\nThe model uses optimistic locking to handle concurrent modifications:\n\n```python\n# If two processes try to modify the same entity simultaneously,\n# one will succeed and the other will automatically retry (up to 3 times by default)\n```\n\n### Pattern Matching\n\nYou can use Redis pattern matching in searches:\n\n```python\n# Find entities with names starting with \"A\"\nfor entity in model.find(name='A*'):\n print(entity)\n\n# Find entities with specific pattern in type\nfor entity in model.find(type='user_?????'):\n print(entity)\n\n# Find entities with names containing specific characters\nfor entity in model.find(name='*[Aa]dmin*'):\n print(entity)\n```\n\n### Combining Search Criteria\n\nWhen multiple criteria are provided, all must match (logical AND):\n\n```python\n# Find active users with admin role\nfor entity in model.find(type='user', status='active', role='admin'):\n print(entity)\n```\n\n### Geospatial Search\n\nHotcore automatically manages geospatial indexing for entities with `lat` and `long` attributes:\n\n```python\n# Create entities with coordinates (automatically indexed)\nuser1 = model.init({\n 'name': 'Alice Johnson',\n 'type': 'user',\n 'lat': 40.7128, # NYC latitude\n 'long': -74.0060 # NYC longitude\n})\nmodel.create('root', user1)\n\nuser2 = model.init({\n 'name': 'Bob Smith',\n 'type': 'user',\n 'lat': 34.0522, # LA latitude\n 'long': -118.2437 # LA longitude\n})\nmodel.create('root', user2)\n\n# Search for entities within a bounding box by type\nnyc_users = model.search_bounding_box(40.0, 41.0, -74.0, -73.0, \"user\")\nfor user in nyc_users:\n print(f\"{user['name']} in NYC area\")\n\n# Update coordinates (automatically updates geospatial index)\nchanges = {\n 'uuid': user1['uuid'],\n 'lat': 42.3601, # Boston latitude\n 'long': -71.0589 # Boston longitude\n}\nmodel.apply(changes)\n\n# Search again to see updated locations\nboston_users = model.search_bounding_box(42.0, 43.0, -72.0, -71.0)\n```\n\n**Key Features:**\n- **Automatic Indexing**: Entities with `lat` and `long` are automatically added to the geospatial index\n- **Transparent Updates**: Coordinate changes automatically update the geospatial index\n- **Bounding Box Search**: Find entities within rectangular geographic areas\n- **Performance**: O(log(N)) for adding/updating, O(N+log(M)) for searching\n- **Validation**: Coordinates are validated to ensure they're within valid ranges (-90 to 90\u00b0 lat, -180 to 180\u00b0 lon)\n\n## API Reference\n\n### Model Class\n\n#### Initialization\n\n- `Model(host='localhost', port=6379, db=0)`: Initialize the model with Redis connection parameters\n\n#### Entity Management\n\n- `init(entity: dict) -> dict`: Add a UUID to an entity dictionary\n- `create(parent_uuid: str, entity: dict) -> dict`: Create and save a new entity\n- `get(entity_uuid: str) -> dict`: Retrieve an entity by its UUID\n- `apply(change: dict) -> None`: Apply changes to an existing entity\n- `delete(entity: dict) -> None`: Delete an entity\n\n#### Relationships\n\n- `get_children(parent_uuid: str) -> Generator[dict]`: Get all children of a parent entity\n- `get_parent(child_uuid: str) -> dict`: Get the parent of an entity\n\n#### Search\n\n- `find(**kwargs) -> Generator[dict]`: Find entities matching attribute criteria\n- `get_entity_from_index(index_hit: str) -> Generator[dict]`: Get entities from a specific index\n- `search_bounding_box(min_lat, max_lat, min_lon, max_lon, entity_type=\"default\") -> List[dict]`: Search for entities of a specific type within a geographic bounding box\n\n## Best Practices\n\n1. **Use UUIDs for entity identification**: Generate UUIDs using `model.init({})`\n2. **Keep attributes as strings**: For optimal indexing and searching\n3. **Manage entity lifecycle**: Create, update, and delete entities using the model API\n4. **Use pattern matching judiciously**: Wildcard searches can be powerful but resource-intensive\n5. **Handle errors**: Implement proper error handling for potential Redis errors\n6. **Geospatial coordinates**: Use `lat` and `long` attributes for automatic geospatial indexing and search\n\n## Performance Considerations\n\n1. **Connection Pooling**: The model uses Redis connection pooling for optimal performance\n2. **Pipelines**: Operations use Redis pipelines to minimize network roundtrips\n3. **Optimistic Locking**: Helps maintain data consistency with minimal performance impact\n4. **Temporary Sets**: Complex searches using wildcards create temporary sets that expire after 60 seconds\n\n## Testing\n\nHotcore's test suite is designed to work without requiring a Redis server for most tests. We use fakeredis to simulate Redis functionality for unit and integration tests.\n\n### Running Tests\n\n```bash\n# Run tests using the provided script\n./run_tests.sh\n\n# Run only unit tests\n./run_tests.sh --unit\n\n# Run only integration tests\n./run_tests.sh --integration\n\n# Run tests with coverage report\n./run_tests.sh --cov\n\n# Run with a real Redis server\n./run_tests.sh --real-redis\n```\n\n#### With Virtual Environment (venv)\n\n```bash\n# Create and activate virtual environment\npython -m venv .venv\nsource .venv/bin/activate\n\n# Install development dependencies\npip install -r requirements-dev.txt\n\n# Run tests that don't require Redis\npython -m pytest tests/unit/ tests/integration/\n\n# Run all tests including those requiring Redis\nUSE_REAL_REDIS=true python -m pytest\n```\n\n#### With System Python\n\n```bash\n# Install development dependencies\npip install -r requirements-dev.txt\n\n# Run tests that don't require Redis\npython -m pytest tests/unit/ tests/integration/\n\n# Run all tests including those requiring Redis\nUSE_REAL_REDIS=true python -m pytest\n```\n\n### Test Organization\n\nThe tests are organized to minimize Redis server dependencies:\n\n- `tests/unit/` - Unit tests (no Redis server needed, uses fakeredis)\n- `tests/integration/` - Integration tests (no Redis server needed, uses fakeredis)\n- `tests/real_redis/` - Tests that require a real Redis server (skipped by default)\n\nFor more details, see the [tests README](tests/README.md).\n\n## Development\n\n- Read the [contribution guide](CONTRIBUTING.md) for environment setup, coding standards, and release process.\n- All contributions are covered by our [Code of Conduct](CODE_OF_CONDUCT.md).\n- Security issues should be reported privately (see [SECURITY.md](SECURITY.md)).\n\n## Testing Strategy\n\n- Default test runs use `fakeredis` and cover both unit and integration suites (`pytest` or `./run_tests.sh`).\n- Tests that require a real Redis instance live in `tests/real_redis/` and are marked with `@pytest.mark.redis_required`.\n- Optional geospatial features can be exercised by installing `hotcore[h3]`; related tests skip automatically when H3 is unavailable.\n- CI (planned) will enforce formatting (`black`, `isort`), linting (`flake8`), type checks (`mypy`), and the full pytest suite across supported Python versions.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Optional Dependencies\n\n- `hotcore[h3]`: Enables H3-based geospatial indexing via Uber's [`h3`](https://github.com/uber/h3-py) library (Apache License 2.0).\n\n## Third-Party Notices\n\nThis project distributes under the MIT License. Optional geospatial functionality depends on Uber's `h3` library, which is available under the Apache License 2.0.\n\n## License\n\n[MIT License](LICENSE)\n",
"bugtrack_url": null,
"license": "MIT License\n \n Copyright (c) 2024 Magnus Dahl\n \n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n \n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n \n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n ",
"summary": "A Redis-based hierarchical entity model for application data management",
"version": "1.2.0",
"project_urls": {
"Homepage": "https://github.com/Consistis-R-D/hotcore",
"Repository": "https://github.com/Consistis-R-D/hotcore"
},
"split_keywords": [
"redis",
" data-model",
" geospatial",
" hierarchical"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b8e551bfacc8d858d625449ae28b0a8dfa49a00dc178f122ecf70c157848f49d",
"md5": "6c65e966d0f797067e88a7546b57610e",
"sha256": "9a13e16f880450c6ae5de8df4d79ca9c02aba6252d0e357f55477c033e826f87"
},
"downloads": -1,
"filename": "hotcore-1.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6c65e966d0f797067e88a7546b57610e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 23880,
"upload_time": "2025-10-17T22:21:32",
"upload_time_iso_8601": "2025-10-17T22:21:32.433370Z",
"url": "https://files.pythonhosted.org/packages/b8/e5/51bfacc8d858d625449ae28b0a8dfa49a00dc178f122ecf70c157848f49d/hotcore-1.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a4cd9c83db29921a6396975eacff2b67b5146859190caa28d4c7b87e851efbd3",
"md5": "ac77e4eb9df3b804fc8d287dfaafb23a",
"sha256": "48d3c54bf7074fcceaf339e624356cf67fbf691d9dabd474294cfd2943e06ba2"
},
"downloads": -1,
"filename": "hotcore-1.2.0.tar.gz",
"has_sig": false,
"md5_digest": "ac77e4eb9df3b804fc8d287dfaafb23a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 45997,
"upload_time": "2025-10-17T22:21:33",
"upload_time_iso_8601": "2025-10-17T22:21:33.947950Z",
"url": "https://files.pythonhosted.org/packages/a4/cd/9c83db29921a6396975eacff2b67b5146859190caa28d4c7b87e851efbd3/hotcore-1.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-17 22:21:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Consistis-R-D",
"github_project": "hotcore",
"github_not_found": true,
"lcname": "hotcore"
}