Lightweight Python client to download official ASX short position daily CSVs with local caching
Project description
asxshorts
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, andtyper
Installation
# 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
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
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
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
# 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
# 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
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:
{
"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=Trueto bypass cache and fetch fresh data
Error Handling
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file asxshorts-0.1.1.tar.gz.
File metadata
- Download URL: asxshorts-0.1.1.tar.gz
- Upload date:
- Size: 49.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ab1c918914573edd0d36b0b1fa5071ef5681bf9cd717b7ae70a93aa545f680b
|
|
| MD5 |
96a6ca6e2286bf6cfe0db0509e71fe90
|
|
| BLAKE2b-256 |
6fbd5639f6f273def5ca540f511f884f4bd1eb22d29a679fdb8b454f57b8ad1c
|
Provenance
The following attestation bundles were made for asxshorts-0.1.1.tar.gz:
Publisher:
publish.yml on ay-mich/asxshorts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asxshorts-0.1.1.tar.gz -
Subject digest:
2ab1c918914573edd0d36b0b1fa5071ef5681bf9cd717b7ae70a93aa545f680b - Sigstore transparency entry: 631300046
- Sigstore integration time:
-
Permalink:
ay-mich/asxshorts@48b87c4a7eb06a4af6ea20f885f462078a65e1bf -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ay-mich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@48b87c4a7eb06a4af6ea20f885f462078a65e1bf -
Trigger Event:
push
-
Statement type:
File details
Details for the file asxshorts-0.1.1-py3-none-any.whl.
File metadata
- Download URL: asxshorts-0.1.1-py3-none-any.whl
- Upload date:
- Size: 27.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6f3ca6599b383279f2f5439dec0643b12f205f040e4cbe80e214ef4dea76f65
|
|
| MD5 |
c39130856be50b611c46bcad17467840
|
|
| BLAKE2b-256 |
8692fbedc64781ec17fd056391d563de775f6c88a8a055077721038a1db1abe3
|
Provenance
The following attestation bundles were made for asxshorts-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on ay-mich/asxshorts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
asxshorts-0.1.1-py3-none-any.whl -
Subject digest:
d6f3ca6599b383279f2f5439dec0643b12f205f040e4cbe80e214ef4dea76f65 - Sigstore transparency entry: 631300048
- Sigstore integration time:
-
Permalink:
ay-mich/asxshorts@48b87c4a7eb06a4af6ea20f885f462078a65e1bf -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ay-mich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@48b87c4a7eb06a4af6ea20f885f462078a65e1bf -
Trigger Event:
push
-
Statement type: