asxshorts


Nameasxshorts JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryLightweight Python client to download official ASX short position daily CSVs with local caching
upload_time2025-10-23 02:34:35
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT
keywords asx australia csv data finance short-selling
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # asxshorts

[![PyPI version](https://badge.fury.io/py/asxshorts.svg)](https://badge.fury.io/py/asxshorts)
[![Python versions](https://img.shields.io/pypi/pyversions/asxshorts.svg)](https://pypi.org/project/asxshorts/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/ay-mich/asxshorts/workflows/CI/badge.svg)](https://github.com/ay-mich/asxshorts/actions)

Lightweight Python client to download official ASIC short position daily CSVs across a date range, with local caching.

## Features

- 🚀 **Simple API**: Fetch short selling data with just a few lines of code
- 💾 **Local Caching**: Automatic file-based caching with atomic operations
- 🔄 **Retry Logic**: Built-in exponential backoff for robust data fetching
- 📊 **Multiple Formats**: Typed models + dicts, optional pandas/polars adapters
- 🖥️ **CLI Interface**: Command-line tool for quick data access
- 🛡️ **Type Safe**: Full type hints and mypy compatibility
- ⚡ **Minimal Dependencies**: Only requires `requests`, `python-dateutil`, and `typer`

## Installation

```bash
# Basic installation
pip install asxshorts

# With pandas support
pip install asxshorts[pandas]

# With polars support
pip install asxshorts[polars]

# Development installation
pip install asxshorts[dev]
```

## Quick Start

### Python API

```python
from datetime import date
from asxshorts import ShortsClient

# Create client
client = ShortsClient()

# Fetch data for a specific date
res = client.fetch_day(date(2024, 1, 15))
print(f"Found {res.record_count} records (from_cache={res.from_cache})")

# Fetch data for a date range
rng = client.fetch_range(
    start=date(2024, 1, 15),
    end=date(2024, 1, 19)
)
print(f"Total records: {rng.total_records}")

# Each record is a dictionary with normalized fields
for record in res.records[:3]:
    d = record.report_date
    print(f"{d}: {record.asx_code} - {record.percent_short}")
```

### Pandas Integration

```python
from asxshorts.adapters import create_pandas_adapter, to_pandas

# Create pandas adapter
adapter = create_pandas_adapter()

# Fetch as DataFrame via adapter
df = adapter.fetch_day_df(date(2024, 1, 15))
print(df.head())

# Or convert existing records
df2 = to_pandas([r.model_dump() for r in res.records])

# Date range as DataFrame
df = adapter.fetch_range_df(
    start=date(2024, 1, 15),
    end=date(2024, 1, 19)
)
```

### Polars Integration

```python
from asxshorts.adapters import create_polars_adapter, to_polars

# Create polars adapter
adapter = create_polars_adapter()

# Fetch as Polars DataFrame
df = adapter.fetch_day_df(date(2024, 1, 15))
print(df.head())

# Or convert existing records
df2 = to_polars([r.model_dump() for r in res.records])
```

### Command Line Interface

```bash
# Fetch data for a specific date
asxshorts fetch 2024-01-15

# Fetch yesterday's data
asxshorts fetch yesterday

# Fetch date range and save to file
asxshorts range 2024-01-15 2024-01-19 --output data.json

# Show cache statistics
asxshorts cache stats

# Clear cache
asxshorts cache clear

# Clean up old cache files
asxshorts cache cleanup --max-age 30
```

## Configuration

### Environment Variables

```bash
# Custom cache directory
export asxshorts_CACHE_DIR="/path/to/cache"

# Custom base URL
export asxshorts_BASE_URL="https://download.asic.gov.au"

# Custom user agent
export asxshorts_USER_AGENT="MyApp/1.0"
```

### Client Configuration

```python
from asxshorts import ShortsClient

client = ShortsClient(
    cache_dir="/custom/cache/path",
    timeout=30.0,
    retries=5,
    backoff=1.0
)
```

## Data Format

Each record contains the following normalized fields:

```python
{
    "report_date": "2024-01-15",   # date
    "asx_code": "ABC",            # ASX code
    "company_name": "…",          # optional
    "short_sold": 1000000,         # int
    "issued_shares": 10000000,     # int
    "percent_short": 10.0          # float
}
```

## Caching

- Files are cached in `~/.cache/asxshorts/` by default
- Cache uses atomic writes with file locking for thread safety
- Cached files are named by date: `2024-01-15.csv`
- Use `force=True` to bypass cache and fetch fresh data

## Error Handling

```python
from asxshorts import ShortsClient
from asxshorts.errors import NotFoundError, FetchError, RateLimitError

client = ShortsClient()

try:
    records = client.fetch_day(date(2024, 1, 15))
except NotFoundError:
    print("No data available for this date")
except RateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after} seconds")
except FetchError as e:
    print(f"Failed to fetch data: {e}")
```

## Contributing

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

## License

MIT License - see LICENSE file for details.

---

**Note**: This package resolves daily CSV URLs via the official ASIC short-selling index. Please respect ASIC/ASX terms and usage limits.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "asxshorts",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "ay-mich <aydenmich@gmail.com>",
    "keywords": "asx, australia, csv, data, finance, short-selling",
    "author": null,
    "author_email": "ay-mich <aydenmich@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/6f/bd/5639f6f273def5ca540f511f884f4bd1eb22d29a679fdb8b454f57b8ad1c/asxshorts-0.1.1.tar.gz",
    "platform": null,
    "description": "# asxshorts\n\n[![PyPI version](https://badge.fury.io/py/asxshorts.svg)](https://badge.fury.io/py/asxshorts)\n[![Python versions](https://img.shields.io/pypi/pyversions/asxshorts.svg)](https://pypi.org/project/asxshorts/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![CI](https://github.com/ay-mich/asxshorts/workflows/CI/badge.svg)](https://github.com/ay-mich/asxshorts/actions)\n\nLightweight Python client to download official ASIC short position daily CSVs across a date range, with local caching.\n\n## Features\n\n- \ud83d\ude80 **Simple API**: Fetch short selling data with just a few lines of code\n- \ud83d\udcbe **Local Caching**: Automatic file-based caching with atomic operations\n- \ud83d\udd04 **Retry Logic**: Built-in exponential backoff for robust data fetching\n- \ud83d\udcca **Multiple Formats**: Typed models + dicts, optional pandas/polars adapters\n- \ud83d\udda5\ufe0f **CLI Interface**: Command-line tool for quick data access\n- \ud83d\udee1\ufe0f **Type Safe**: Full type hints and mypy compatibility\n- \u26a1 **Minimal Dependencies**: Only requires `requests`, `python-dateutil`, and `typer`\n\n## Installation\n\n```bash\n# Basic installation\npip install asxshorts\n\n# With pandas support\npip install asxshorts[pandas]\n\n# With polars support\npip install asxshorts[polars]\n\n# Development installation\npip install asxshorts[dev]\n```\n\n## Quick Start\n\n### Python API\n\n```python\nfrom datetime import date\nfrom asxshorts import ShortsClient\n\n# Create client\nclient = ShortsClient()\n\n# Fetch data for a specific date\nres = client.fetch_day(date(2024, 1, 15))\nprint(f\"Found {res.record_count} records (from_cache={res.from_cache})\")\n\n# Fetch data for a date range\nrng = client.fetch_range(\n    start=date(2024, 1, 15),\n    end=date(2024, 1, 19)\n)\nprint(f\"Total records: {rng.total_records}\")\n\n# Each record is a dictionary with normalized fields\nfor record in res.records[:3]:\n    d = record.report_date\n    print(f\"{d}: {record.asx_code} - {record.percent_short}\")\n```\n\n### Pandas Integration\n\n```python\nfrom asxshorts.adapters import create_pandas_adapter, to_pandas\n\n# Create pandas adapter\nadapter = create_pandas_adapter()\n\n# Fetch as DataFrame via adapter\ndf = adapter.fetch_day_df(date(2024, 1, 15))\nprint(df.head())\n\n# Or convert existing records\ndf2 = to_pandas([r.model_dump() for r in res.records])\n\n# Date range as DataFrame\ndf = adapter.fetch_range_df(\n    start=date(2024, 1, 15),\n    end=date(2024, 1, 19)\n)\n```\n\n### Polars Integration\n\n```python\nfrom asxshorts.adapters import create_polars_adapter, to_polars\n\n# Create polars adapter\nadapter = create_polars_adapter()\n\n# Fetch as Polars DataFrame\ndf = adapter.fetch_day_df(date(2024, 1, 15))\nprint(df.head())\n\n# Or convert existing records\ndf2 = to_polars([r.model_dump() for r in res.records])\n```\n\n### Command Line Interface\n\n```bash\n# Fetch data for a specific date\nasxshorts fetch 2024-01-15\n\n# Fetch yesterday's data\nasxshorts fetch yesterday\n\n# Fetch date range and save to file\nasxshorts range 2024-01-15 2024-01-19 --output data.json\n\n# Show cache statistics\nasxshorts cache stats\n\n# Clear cache\nasxshorts cache clear\n\n# Clean up old cache files\nasxshorts cache cleanup --max-age 30\n```\n\n## Configuration\n\n### Environment Variables\n\n```bash\n# Custom cache directory\nexport asxshorts_CACHE_DIR=\"/path/to/cache\"\n\n# Custom base URL\nexport asxshorts_BASE_URL=\"https://download.asic.gov.au\"\n\n# Custom user agent\nexport asxshorts_USER_AGENT=\"MyApp/1.0\"\n```\n\n### Client Configuration\n\n```python\nfrom asxshorts import ShortsClient\n\nclient = ShortsClient(\n    cache_dir=\"/custom/cache/path\",\n    timeout=30.0,\n    retries=5,\n    backoff=1.0\n)\n```\n\n## Data Format\n\nEach record contains the following normalized fields:\n\n```python\n{\n    \"report_date\": \"2024-01-15\",   # date\n    \"asx_code\": \"ABC\",            # ASX code\n    \"company_name\": \"\u2026\",          # optional\n    \"short_sold\": 1000000,         # int\n    \"issued_shares\": 10000000,     # int\n    \"percent_short\": 10.0          # float\n}\n```\n\n## Caching\n\n- Files are cached in `~/.cache/asxshorts/` by default\n- Cache uses atomic writes with file locking for thread safety\n- Cached files are named by date: `2024-01-15.csv`\n- Use `force=True` to bypass cache and fetch fresh data\n\n## Error Handling\n\n```python\nfrom asxshorts import ShortsClient\nfrom asxshorts.errors import NotFoundError, FetchError, RateLimitError\n\nclient = ShortsClient()\n\ntry:\n    records = client.fetch_day(date(2024, 1, 15))\nexcept NotFoundError:\n    print(\"No data available for this date\")\nexcept RateLimitError as e:\n    print(f\"Rate limited, retry after {e.retry_after} seconds\")\nexcept FetchError as e:\n    print(f\"Failed to fetch data: {e}\")\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT License - see LICENSE file for details.\n\n---\n\n**Note**: This package resolves daily CSV URLs via the official ASIC short-selling index. Please respect ASIC/ASX terms and usage limits.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Lightweight Python client to download official ASX short position daily CSVs with local caching",
    "version": "0.1.1",
    "project_urls": {
        "Changelog": "https://github.com/ay-mich/asxshorts/blob/main/CHANGELOG.md",
        "Documentation": "https://ay-mich.github.io/asxshorts/asxshorts.html",
        "Homepage": "https://github.com/ay-mich/asxshorts",
        "Issues": "https://github.com/ay-mich/asxshorts/issues",
        "Repository": "https://github.com/ay-mich/asxshorts"
    },
    "split_keywords": [
        "asx",
        " australia",
        " csv",
        " data",
        " finance",
        " short-selling"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8692fbedc64781ec17fd056391d563de775f6c88a8a055077721038a1db1abe3",
                "md5": "c39130856be50b611c46bcad17467840",
                "sha256": "d6f3ca6599b383279f2f5439dec0643b12f205f040e4cbe80e214ef4dea76f65"
            },
            "downloads": -1,
            "filename": "asxshorts-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c39130856be50b611c46bcad17467840",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 27110,
            "upload_time": "2025-10-23T02:34:33",
            "upload_time_iso_8601": "2025-10-23T02:34:33.695093Z",
            "url": "https://files.pythonhosted.org/packages/86/92/fbedc64781ec17fd056391d563de775f6c88a8a055077721038a1db1abe3/asxshorts-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6fbd5639f6f273def5ca540f511f884f4bd1eb22d29a679fdb8b454f57b8ad1c",
                "md5": "96a6ca6e2286bf6cfe0db0509e71fe90",
                "sha256": "2ab1c918914573edd0d36b0b1fa5071ef5681bf9cd717b7ae70a93aa545f680b"
            },
            "downloads": -1,
            "filename": "asxshorts-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "96a6ca6e2286bf6cfe0db0509e71fe90",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 49652,
            "upload_time": "2025-10-23T02:34:35",
            "upload_time_iso_8601": "2025-10-23T02:34:35.138470Z",
            "url": "https://files.pythonhosted.org/packages/6f/bd/5639f6f273def5ca540f511f884f4bd1eb22d29a679fdb8b454f57b8ad1c/asxshorts-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-23 02:34:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ay-mich",
    "github_project": "asxshorts",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "asxshorts"
}
        
Elapsed time: 0.49752s