# Balancing Services Python Client
Python client library for the [Balancing Services REST API](https://api.balancing.services). Access European electricity balancing market data with a modern, type-safe Python interface.
## Features
- **Type-safe**: Full type hints for better IDE support and code quality
- **Modern Python**: Built with httpx and attrs for async support and clean data models
- **Auto-generated**: Generated from the official OpenAPI specification
- **Comprehensive**: Access to all API endpoints and data models
- **Well-documented**: Inline documentation and usage examples
## Installation
```bash
uv pip install balancing-services
```
Or with pip:
```bash
pip install balancing-services
```
For development, install from source:
```bash
cd clients/python
uv pip install -e .
```
## Quick Start
```python
from balancing_services import AuthenticatedClient
from balancing_services.api.default import get_imbalance_prices
from balancing_services.models import Area
from datetime import datetime
# Create an authenticated client
client = AuthenticatedClient(
base_url="https://api.balancing.services/v1",
token="YOUR_API_TOKEN"
)
# Get imbalance prices for Estonia
response = get_imbalance_prices.sync_detailed(
client=client,
area=Area.EE,
period_start_at=datetime.fromisoformat("2025-01-01T00:00:00Z"),
period_end_at=datetime.fromisoformat("2025-01-02T00:00:00Z")
)
if response.status_code == 200:
data = response.parsed
print(f"Query period: {data.queried_period.start_at} to {data.queried_period.end_at}")
for imbalance_prices in data.data:
print(f"Area: {imbalance_prices.area}, Direction: {imbalance_prices.direction}")
for price in imbalance_prices.prices:
print(f" {price.period.start_at}: {price.price} {imbalance_prices.currency}")
```
## Authentication
To obtain an API token:
- **Email:** info@balancing.services
- **Website:** https://balancing.services
Include your token when creating the client:
```python
from balancing_services import AuthenticatedClient
client = AuthenticatedClient(
base_url="https://api.balancing.services/v1",
token="YOUR_API_TOKEN"
)
```
## Usage Examples
### Get Balancing Energy Bids with Pagination
```python
from balancing_services import AuthenticatedClient
from balancing_services.api.default import get_balancing_energy_bids
from balancing_services.models import Area, ReserveType
from datetime import datetime
client = AuthenticatedClient(base_url="https://api.balancing.services/v1", token="YOUR_TOKEN")
# First page
response = get_balancing_energy_bids.sync_detailed(
client=client,
area=Area.EE,
period_start_at=datetime.fromisoformat("2025-01-01T00:00:00Z"),
period_end_at=datetime.fromisoformat("2025-01-02T00:00:00Z"),
reserve_type=ReserveType.AFRR,
limit=100
)
if response.status_code == 200:
data = response.parsed
print(f"Has more: {data.has_more}")
# Process first page
for bid_group in data.data:
for bid in bid_group.bids:
print(f"Bid: {bid.volume} MW @ {bid.price} {bid_group.currency}")
# Get next page if available
if data.has_more and data.next_cursor:
next_response = get_balancing_energy_bids.sync_detailed(
client=client,
area=Area.EE,
period_start_at=datetime.fromisoformat("2025-01-01T00:00:00Z"),
period_end_at=datetime.fromisoformat("2025-01-02T00:00:00Z"),
reserve_type=ReserveType.AFRR,
cursor=data.next_cursor,
limit=100
)
```
### Async Usage
```python
import asyncio
from balancing_services import AuthenticatedClient
from balancing_services.api.default import get_imbalance_prices
from balancing_services.models import Area
from datetime import datetime
async def fetch_prices():
client = AuthenticatedClient(
base_url="https://api.balancing.services/v1",
token="YOUR_TOKEN"
)
response = await get_imbalance_prices.asyncio_detailed(
client=client,
area=Area.EE,
period_start_at=datetime.fromisoformat("2025-01-01T00:00:00Z"),
period_end_at=datetime.fromisoformat("2025-01-02T00:00:00Z")
)
if response.status_code == 200:
return response.parsed
return None
# Run async function
prices = asyncio.run(fetch_prices())
```
### Error Handling
```python
from balancing_services import AuthenticatedClient
from balancing_services.api.default import get_imbalance_prices
from balancing_services.models import Area
from datetime import datetime
client = AuthenticatedClient(base_url="https://api.balancing.services/v1", token="YOUR_TOKEN")
response = get_imbalance_prices.sync_detailed(
client=client,
area=Area.EE,
period_start_at=datetime.fromisoformat("2025-01-01T00:00:00Z"),
period_end_at=datetime.fromisoformat("2025-01-02T00:00:00Z")
)
if response.status_code == 200:
data = response.parsed
# Process successful response
elif response.status_code == 400:
error = response.parsed
print(f"Bad request: {error.detail}")
elif response.status_code == 401:
print("Authentication failed - check your API token")
elif response.status_code == 429:
print("Rate limited - please retry later")
else:
print(f"Error {response.status_code}: {response.content}")
```
## Data Models
All response and request models are fully typed using attrs. Key models include:
- `ImbalancePricesResponse`, `ImbalanceTotalVolumesResponse`
- `BalancingEnergyVolumesResponse`, `BalancingEnergyPricesResponse`, `BalancingEnergyBidsResponse`
- `BalancingCapacityBidsResponse`, `BalancingCapacityPricesResponse`, `BalancingCapacityVolumesResponse`
- Enums: `Area`, `ReserveType`, `Direction`, `Currency`, `ActivationType`, `BidStatus`
## Development
### Regenerating the Client
The client is generated from the OpenAPI specification. To regenerate:
```bash
cd clients/python
./generate.sh
```
### Running Tests
```bash
# Install development dependencies
uv pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=balancing_services --cov-report=html
```
### Code Quality
```bash
# Format code
ruff format .
# Lint code
ruff check .
# Type checking
mypy balancing_services
```
### Automation Scripts
The Python client includes automation scripts for development and publishing:
#### `generate-pyproject.sh`
Generates `pyproject.toml` from the template with the current version from `openapi.yaml`.
**Note:** The version is stored in `openapi.yaml` (single source of truth). The `pyproject.toml.draft` template contains invalid TOML (`version = __VERSION__` without quotes) to prevent accidental use without proper generation.
```bash
./generate-pyproject.sh
```
This script is automatically called by `check.sh` and `test-and-publish.sh`.
#### `check.sh`
Runs all quality checks in one command:
```bash
./check.sh
```
Performs:
- Generates `pyproject.toml` from draft
- Runs tests with pytest
- Runs linting with ruff
- Runs type checking with mypy
- Verifies the package builds
#### `test-and-publish.sh`
Complete publishing workflow with TestPyPI validation:
**Setup:**
1. Copy `.env.sample` to `.env` and fill in your credentials:
```bash
cp .env.sample .env
# Edit .env and add:
# BALANCING_SERVICES_API_KEY (required - for testing against live API)
# UV_PUBLISH_TOKEN_TESTPYPI (required)
# UV_PUBLISH_TOKEN_PYPI (required)
```
2. Run the publish script:
```bash
./test-and-publish.sh
```
**Emergency option** - skip API tests if the server is down:
```bash
./test-and-publish.sh --skip-api-tests
```
⚠️ This skips testing against the live API. Use only in emergencies!
Alternatively, export variables manually:
```bash
export BALANCING_SERVICES_API_KEY="your-api-key"
export UV_PUBLISH_TOKEN_TESTPYPI="your-testpypi-token"
export UV_PUBLISH_TOKEN_PYPI="your-pypi-token"
./test-and-publish.sh
```
**What it does:**
1. Loads credentials from `.env` (if present)
2. Verifies all required environment variables are set
3. Runs quality checks
4. Publishes to TestPyPI using `UV_PUBLISH_TOKEN_TESTPYPI`
5. Creates isolated test sandbox
6. Installs package from TestPyPI
7. Runs all example scripts against live API using `BALANCING_SERVICES_API_KEY`
8. Prompts to publish to PyPI using `UV_PUBLISH_TOKEN_PYPI` if tests pass
9. Verifies production PyPI package by installing and running examples again
**Get your credentials:**
- API Key: https://balancing.services
- TestPyPI: https://test.pypi.org/manage/account/token/
- PyPI: https://pypi.org/manage/account/token/
**For maintainers:** See `../../scripts/README.md` for the complete release workflow.
## Troubleshooting
### Authentication Errors (401)
**Problem:** Receiving 401 Unauthorized responses
**Solutions:**
- Verify your API token is correct
- Check that the token is being passed to `AuthenticatedClient`
- Ensure your token hasn't expired (contact support if needed)
### Bad Request Errors (400)
**Problem:** Receiving 400 Bad Request responses
**Common causes:**
- Invalid date range (end date before start date)
- Date range too large
- Invalid area code or reserve type
- Malformed datetime strings
**Solution:** Check the error detail in the response for specific information:
```python
if response.status_code == 400:
error = response.parsed
print(f"Error detail: {error.detail}")
```
### Empty Results
**Problem:** Receiving 200 OK but no data
**Possible reasons:**
- No data available for the requested period
- Data not yet published for recent periods
- Requesting data for a period before data collection started
**Solution:** Try a different time period or check if data exists for your area
### Timeout Issues
**Problem:** Requests timing out
**Solutions:**
- Increase the client timeout:
```python
client = AuthenticatedClient(
base_url="https://api.balancing.services/v1",
token="YOUR_TOKEN",
timeout=30.0 # Increase from default
)
```
- Reduce the date range in your request
- Use pagination for large datasets
### Type Errors with Enums
**Problem:** Type errors when passing area or reserve type
**Solution:** Use the provided enum classes:
```python
from balancing_services.models import Area, ReserveType
# Correct
area=Area.EE
# Incorrect
area="EE" # String might work but not type-safe
```
## Documentation
- **API Documentation:** https://api.balancing.services/v1/documentation
- **OpenAPI Spec:** [openapi.yaml](../../openapi.yaml)
- **Main Repository:** https://github.com/balancing-services/rest-api
## Support
- **Website:** https://balancing.services
- **Email:** info@balancing.services
- **Issues:** [GitHub Issues](https://github.com/balancing-services/rest-api/issues)
## License
MIT License - see [LICENSE](../../LICENSE) for details.
## Changelog
See [CHANGELOG.md](../../CHANGELOG.md) for version history and changes.
Raw data
{
"_id": null,
"home_page": null,
"name": "balancing-services",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "FCR, aFRR, api, balancing, electricity, energy, europe, grid, imbalance, mFRR, market, openapi, power, reserves",
"author": "Balancing Services Team",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/31/96/4b619897d722e5d7b9baf61559b3b3ec72bd9f5e8191e304397c7ecba850/balancing_services-1.4.0.tar.gz",
"platform": null,
"description": "# Balancing Services Python Client\n\nPython client library for the [Balancing Services REST API](https://api.balancing.services). Access European electricity balancing market data with a modern, type-safe Python interface.\n\n## Features\n\n- **Type-safe**: Full type hints for better IDE support and code quality\n- **Modern Python**: Built with httpx and attrs for async support and clean data models\n- **Auto-generated**: Generated from the official OpenAPI specification\n- **Comprehensive**: Access to all API endpoints and data models\n- **Well-documented**: Inline documentation and usage examples\n\n## Installation\n\n```bash\nuv pip install balancing-services\n```\n\nOr with pip:\n\n```bash\npip install balancing-services\n```\n\nFor development, install from source:\n\n```bash\ncd clients/python\nuv pip install -e .\n```\n\n## Quick Start\n\n```python\nfrom balancing_services import AuthenticatedClient\nfrom balancing_services.api.default import get_imbalance_prices\nfrom balancing_services.models import Area\nfrom datetime import datetime\n\n# Create an authenticated client\nclient = AuthenticatedClient(\n base_url=\"https://api.balancing.services/v1\",\n token=\"YOUR_API_TOKEN\"\n)\n\n# Get imbalance prices for Estonia\nresponse = get_imbalance_prices.sync_detailed(\n client=client,\n area=Area.EE,\n period_start_at=datetime.fromisoformat(\"2025-01-01T00:00:00Z\"),\n period_end_at=datetime.fromisoformat(\"2025-01-02T00:00:00Z\")\n)\n\nif response.status_code == 200:\n data = response.parsed\n print(f\"Query period: {data.queried_period.start_at} to {data.queried_period.end_at}\")\n for imbalance_prices in data.data:\n print(f\"Area: {imbalance_prices.area}, Direction: {imbalance_prices.direction}\")\n for price in imbalance_prices.prices:\n print(f\" {price.period.start_at}: {price.price} {imbalance_prices.currency}\")\n```\n\n## Authentication\n\nTo obtain an API token:\n- **Email:** info@balancing.services\n- **Website:** https://balancing.services\n\nInclude your token when creating the client:\n\n```python\nfrom balancing_services import AuthenticatedClient\n\nclient = AuthenticatedClient(\n base_url=\"https://api.balancing.services/v1\",\n token=\"YOUR_API_TOKEN\"\n)\n```\n\n## Usage Examples\n\n### Get Balancing Energy Bids with Pagination\n\n```python\nfrom balancing_services import AuthenticatedClient\nfrom balancing_services.api.default import get_balancing_energy_bids\nfrom balancing_services.models import Area, ReserveType\nfrom datetime import datetime\n\nclient = AuthenticatedClient(base_url=\"https://api.balancing.services/v1\", token=\"YOUR_TOKEN\")\n\n# First page\nresponse = get_balancing_energy_bids.sync_detailed(\n client=client,\n area=Area.EE,\n period_start_at=datetime.fromisoformat(\"2025-01-01T00:00:00Z\"),\n period_end_at=datetime.fromisoformat(\"2025-01-02T00:00:00Z\"),\n reserve_type=ReserveType.AFRR,\n limit=100\n)\n\nif response.status_code == 200:\n data = response.parsed\n print(f\"Has more: {data.has_more}\")\n\n # Process first page\n for bid_group in data.data:\n for bid in bid_group.bids:\n print(f\"Bid: {bid.volume} MW @ {bid.price} {bid_group.currency}\")\n\n # Get next page if available\n if data.has_more and data.next_cursor:\n next_response = get_balancing_energy_bids.sync_detailed(\n client=client,\n area=Area.EE,\n period_start_at=datetime.fromisoformat(\"2025-01-01T00:00:00Z\"),\n period_end_at=datetime.fromisoformat(\"2025-01-02T00:00:00Z\"),\n reserve_type=ReserveType.AFRR,\n cursor=data.next_cursor,\n limit=100\n )\n```\n\n### Async Usage\n\n```python\nimport asyncio\nfrom balancing_services import AuthenticatedClient\nfrom balancing_services.api.default import get_imbalance_prices\nfrom balancing_services.models import Area\nfrom datetime import datetime\n\nasync def fetch_prices():\n client = AuthenticatedClient(\n base_url=\"https://api.balancing.services/v1\",\n token=\"YOUR_TOKEN\"\n )\n\n response = await get_imbalance_prices.asyncio_detailed(\n client=client,\n area=Area.EE,\n period_start_at=datetime.fromisoformat(\"2025-01-01T00:00:00Z\"),\n period_end_at=datetime.fromisoformat(\"2025-01-02T00:00:00Z\")\n )\n\n if response.status_code == 200:\n return response.parsed\n return None\n\n# Run async function\nprices = asyncio.run(fetch_prices())\n```\n\n### Error Handling\n\n```python\nfrom balancing_services import AuthenticatedClient\nfrom balancing_services.api.default import get_imbalance_prices\nfrom balancing_services.models import Area\nfrom datetime import datetime\n\nclient = AuthenticatedClient(base_url=\"https://api.balancing.services/v1\", token=\"YOUR_TOKEN\")\n\nresponse = get_imbalance_prices.sync_detailed(\n client=client,\n area=Area.EE,\n period_start_at=datetime.fromisoformat(\"2025-01-01T00:00:00Z\"),\n period_end_at=datetime.fromisoformat(\"2025-01-02T00:00:00Z\")\n)\n\nif response.status_code == 200:\n data = response.parsed\n # Process successful response\nelif response.status_code == 400:\n error = response.parsed\n print(f\"Bad request: {error.detail}\")\nelif response.status_code == 401:\n print(\"Authentication failed - check your API token\")\nelif response.status_code == 429:\n print(\"Rate limited - please retry later\")\nelse:\n print(f\"Error {response.status_code}: {response.content}\")\n```\n\n## Data Models\n\nAll response and request models are fully typed using attrs. Key models include:\n\n- `ImbalancePricesResponse`, `ImbalanceTotalVolumesResponse`\n- `BalancingEnergyVolumesResponse`, `BalancingEnergyPricesResponse`, `BalancingEnergyBidsResponse`\n- `BalancingCapacityBidsResponse`, `BalancingCapacityPricesResponse`, `BalancingCapacityVolumesResponse`\n- Enums: `Area`, `ReserveType`, `Direction`, `Currency`, `ActivationType`, `BidStatus`\n\n## Development\n\n### Regenerating the Client\n\nThe client is generated from the OpenAPI specification. To regenerate:\n\n```bash\ncd clients/python\n./generate.sh\n```\n\n### Running Tests\n\n```bash\n# Install development dependencies\nuv pip install -e \".[dev]\"\n\n# Run tests\npytest\n\n# Run tests with coverage\npytest --cov=balancing_services --cov-report=html\n```\n\n### Code Quality\n\n```bash\n# Format code\nruff format .\n\n# Lint code\nruff check .\n\n# Type checking\nmypy balancing_services\n```\n\n### Automation Scripts\n\nThe Python client includes automation scripts for development and publishing:\n\n#### `generate-pyproject.sh`\nGenerates `pyproject.toml` from the template with the current version from `openapi.yaml`.\n\n**Note:** The version is stored in `openapi.yaml` (single source of truth). The `pyproject.toml.draft` template contains invalid TOML (`version = __VERSION__` without quotes) to prevent accidental use without proper generation.\n\n```bash\n./generate-pyproject.sh\n```\n\nThis script is automatically called by `check.sh` and `test-and-publish.sh`.\n\n#### `check.sh`\nRuns all quality checks in one command:\n\n```bash\n./check.sh\n```\n\nPerforms:\n- Generates `pyproject.toml` from draft\n- Runs tests with pytest\n- Runs linting with ruff\n- Runs type checking with mypy\n- Verifies the package builds\n\n#### `test-and-publish.sh`\nComplete publishing workflow with TestPyPI validation:\n\n**Setup:**\n1. Copy `.env.sample` to `.env` and fill in your credentials:\n ```bash\n cp .env.sample .env\n # Edit .env and add:\n # BALANCING_SERVICES_API_KEY (required - for testing against live API)\n # UV_PUBLISH_TOKEN_TESTPYPI (required)\n # UV_PUBLISH_TOKEN_PYPI (required)\n ```\n\n2. Run the publish script:\n ```bash\n ./test-and-publish.sh\n ```\n\n**Emergency option** - skip API tests if the server is down:\n```bash\n./test-and-publish.sh --skip-api-tests\n```\n\u26a0\ufe0f This skips testing against the live API. Use only in emergencies!\n\nAlternatively, export variables manually:\n```bash\nexport BALANCING_SERVICES_API_KEY=\"your-api-key\"\nexport UV_PUBLISH_TOKEN_TESTPYPI=\"your-testpypi-token\"\nexport UV_PUBLISH_TOKEN_PYPI=\"your-pypi-token\"\n./test-and-publish.sh\n```\n\n**What it does:**\n1. Loads credentials from `.env` (if present)\n2. Verifies all required environment variables are set\n3. Runs quality checks\n4. Publishes to TestPyPI using `UV_PUBLISH_TOKEN_TESTPYPI`\n5. Creates isolated test sandbox\n6. Installs package from TestPyPI\n7. Runs all example scripts against live API using `BALANCING_SERVICES_API_KEY`\n8. Prompts to publish to PyPI using `UV_PUBLISH_TOKEN_PYPI` if tests pass\n9. Verifies production PyPI package by installing and running examples again\n\n**Get your credentials:**\n- API Key: https://balancing.services\n- TestPyPI: https://test.pypi.org/manage/account/token/\n- PyPI: https://pypi.org/manage/account/token/\n\n**For maintainers:** See `../../scripts/README.md` for the complete release workflow.\n\n## Troubleshooting\n\n### Authentication Errors (401)\n\n**Problem:** Receiving 401 Unauthorized responses\n\n**Solutions:**\n- Verify your API token is correct\n- Check that the token is being passed to `AuthenticatedClient`\n- Ensure your token hasn't expired (contact support if needed)\n\n### Bad Request Errors (400)\n\n**Problem:** Receiving 400 Bad Request responses\n\n**Common causes:**\n- Invalid date range (end date before start date)\n- Date range too large\n- Invalid area code or reserve type\n- Malformed datetime strings\n\n**Solution:** Check the error detail in the response for specific information:\n```python\nif response.status_code == 400:\n error = response.parsed\n print(f\"Error detail: {error.detail}\")\n```\n\n### Empty Results\n\n**Problem:** Receiving 200 OK but no data\n\n**Possible reasons:**\n- No data available for the requested period\n- Data not yet published for recent periods\n- Requesting data for a period before data collection started\n\n**Solution:** Try a different time period or check if data exists for your area\n\n### Timeout Issues\n\n**Problem:** Requests timing out\n\n**Solutions:**\n- Increase the client timeout:\n```python\nclient = AuthenticatedClient(\n base_url=\"https://api.balancing.services/v1\",\n token=\"YOUR_TOKEN\",\n timeout=30.0 # Increase from default\n)\n```\n- Reduce the date range in your request\n- Use pagination for large datasets\n\n### Type Errors with Enums\n\n**Problem:** Type errors when passing area or reserve type\n\n**Solution:** Use the provided enum classes:\n```python\nfrom balancing_services.models import Area, ReserveType\n\n# Correct\narea=Area.EE\n\n# Incorrect\narea=\"EE\" # String might work but not type-safe\n```\n\n## Documentation\n\n- **API Documentation:** https://api.balancing.services/v1/documentation\n- **OpenAPI Spec:** [openapi.yaml](../../openapi.yaml)\n- **Main Repository:** https://github.com/balancing-services/rest-api\n\n## Support\n\n- **Website:** https://balancing.services\n- **Email:** info@balancing.services\n- **Issues:** [GitHub Issues](https://github.com/balancing-services/rest-api/issues)\n\n## License\n\nMIT License - see [LICENSE](../../LICENSE) for details.\n\n## Changelog\n\nSee [CHANGELOG.md](../../CHANGELOG.md) for version history and changes.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Official Python client for accessing European electricity balancing market data via the Balancing Services REST API",
"version": "1.4.0",
"project_urls": {
"Changelog": "https://github.com/balancing-services/rest-api/blob/main/CHANGELOG.md",
"Documentation": "https://api.balancing.services/v1/documentation",
"Homepage": "https://balancing.services",
"Repository": "https://github.com/balancing-services/rest-api"
},
"split_keywords": [
"fcr",
" afrr",
" api",
" balancing",
" electricity",
" energy",
" europe",
" grid",
" imbalance",
" mfrr",
" market",
" openapi",
" power",
" reserves"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7a80b5052dee1eb07d2ef4ef82c3b8ef916126f565ca7c4b6f58cda2b9b6482f",
"md5": "ff03aa31a0cf2bfe9d8548e727be8abd",
"sha256": "397a55d0ab15c3ed9ed787d67b9ff52550b22380ca9c356a75a5d1b881d2acf0"
},
"downloads": -1,
"filename": "balancing_services-1.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ff03aa31a0cf2bfe9d8548e727be8abd",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 56429,
"upload_time": "2025-10-25T12:55:13",
"upload_time_iso_8601": "2025-10-25T12:55:13.403247Z",
"url": "https://files.pythonhosted.org/packages/7a/80/b5052dee1eb07d2ef4ef82c3b8ef916126f565ca7c4b6f58cda2b9b6482f/balancing_services-1.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "31964b619897d722e5d7b9baf61559b3b3ec72bd9f5e8191e304397c7ecba850",
"md5": "3e5266dee66c1851c0ded93767db5480",
"sha256": "a6c5db2e34cc0d0160955ac7fddfea9a549d83977c55bfb807a5443dd6c46351"
},
"downloads": -1,
"filename": "balancing_services-1.4.0.tar.gz",
"has_sig": false,
"md5_digest": "3e5266dee66c1851c0ded93767db5480",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 32021,
"upload_time": "2025-10-25T12:55:14",
"upload_time_iso_8601": "2025-10-25T12:55:14.909633Z",
"url": "https://files.pythonhosted.org/packages/31/96/4b619897d722e5d7b9baf61559b3b3ec72bd9f5e8191e304397c7ecba850/balancing_services-1.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-25 12:55:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "balancing-services",
"github_project": "rest-api",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "balancing-services"
}