soracom-lib
A lightweight Python client library for SORACOM Harvest Files.
Provides authentication, iterative file listing, download, upload, and related helpers.
Core implementation lives in soracomlib/soracom_harvest_files.py; the top-level soracomlib package re-exports everything, so you only need import soracomlib.
No dependencies beyond the standard library and requests.
Features
- Credential loading from
.netrc(no credentials in source code) - Authentication via SORACOM SAM user — calls
POST /authand returns a reusable token dict - Iterative directory traversal with optional time-range filter and pagination
- Per-file download with skip-existing and overwrite options
- File upload with automatic
Content-Typedetection - Recency helper for filtering by last-modified time
Requirements
| Python | 3.8 + |
| requests | >= 2.28 |
Installation
Install from PyPI:
pip install soracom-lib
Credentials setup
soracomlib never reads credentials from source code or environment variables.
It uses the standard netrc mechanism so secrets stay out of your repository.
1. Create a SORACOM SAM user
Generate an Auth Key in the SORACOM User Console under Security → SAM Users.
2. Write the netrc file
Windows — create %USERPROFILE%\.netrc:
machine api.soracom.io
login keyId-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
password secret-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Linux / macOS — create ~/.netrc and restrict permissions:
cat >> ~/.netrc << 'EOF'
machine api.soracom.io
login keyId-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
password secret-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EOF
chmod 600 ~/.netrc
3. Add netrc to .gitignore
.netrc
Quick start
import soracomlib as sl
# Load credentials (returns AuthInfo; raises RuntimeError on failure)
auth_info = sl.read_auth_keys()
# Call POST /auth and get a session token dict
token = sl.authenticate(auth_info)
# List all files under a path (returns list[FileEntry])
files = sl.list_files_iterative("logs/XXXXXXXXXXXXXXXXX/", token)
print([e.path for e in files])
# Download each file individually
import os
for entry in files:
local_path = os.path.join("./download", os.path.basename(entry.path))
sl.download_and_save(entry.path, local_path, token)
# Upload a file
sl.upload_file_to_soracom(
file_path="./results/output.log",
upload_path="logs/XXXXXXXXXXXXXXXX/output.log",
token=token,
)
API reference
Constants
| Name | Value | Description |
|---|---|---|
API_BASE |
"https://api.soracom.io/v1" |
Base URL for all API calls |
NETRC_HOST |
"api.soracom.io" |
machine name looked up in .netrc |
NETRC_PATHS |
(os.path.expanduser("~/.netrc"),) |
Default netrc search paths |
LEVEL_INFO / LEVEL_WARN / LEVEL_ERROR |
"INFO" / "WARN" / "ERROR" |
Log level constants used internally by log_status(); can also be passed directly when calling it |
read_auth_keys(base_dir=None) -> AuthInfo
Load credentials from .netrc and return an AuthInfo object.
| Parameter | Type | Description |
|---|---|---|
base_dir |
str | None |
When provided, also searches for .netrc in this directory (takes priority over the home directory). |
Raises RuntimeError if no valid credentials are found.
AuthInfo
Frozen dataclass holding the loaded credentials.
@dataclass(frozen=True)
class AuthInfo:
api_key: str # authKeyId from netrc login field
api_token: str # authKey from netrc password field
authenticate(auth: AuthInfo) -> dict
Call POST /auth with the credentials in auth and return the session token dict issued by the server.
token = sl.authenticate(auth_info)
# → {"apiKey": "...", "token": "..."}
Raises RuntimeError if the request fails or the server returns a non-200 status.
list_files_iterative(base_path, token, limit=None, page_size=100, start_time=None, end_time=None) -> list[FileEntry]
Iteratively traverse directories and list all files under base_path in Harvest Files.
| Parameter | Type | Description |
|---|---|---|
base_path |
str |
Root path in Harvest Files, e.g. "logs/XXXXX.../" |
token |
dict |
Token dict from authenticate() |
limit |
int | None |
Cap on total results; None = no limit |
page_size |
int |
Number of entries per API request (default 100, max 100) |
start_time |
datetime | None |
Exclude files modified before this time. Naive datetimes are treated as UTC. |
end_time |
datetime | None |
Exclude files modified after this time. Naive datetimes are treated as UTC. |
Returns a list of FileEntry objects. Each entry has a path attribute (full remote path string) and a last_modified attribute (UTC-aware datetime, or None when absent from the API response).
download_and_save(remote_path, local_path, token, overwrite=False, chunk_size=1048576) -> bool
Download a single file from Harvest Files and save it to the local filesystem.
| Parameter | Type | Description |
|---|---|---|
remote_path |
str |
File path in Harvest Files (e.g. "logs/XXXXX.../file.log") |
local_path |
str |
Destination path on local filesystem |
token |
dict |
Token dict from authenticate() |
overwrite |
bool |
If False (default) and the local file already exists, the download is skipped and True is returned |
chunk_size |
int |
Streaming chunk size in bytes (default 1 MiB) |
Returns True on success (including skip), False on failure.
Parent directories are created automatically.
upload_file_to_soracom(file_path, upload_path, token) -> bool
Upload a local file to Harvest Files via HTTP PUT.
Content-Type is detected automatically from the file extension; falls back to application/octet-stream.
Returns True on success (HTTP 200 or 204), False on failure.
get_with_auth(url, token) -> requests.Response | None
Authenticated GET. Returns the response object on success (status < 400), or None on error.
delete_with_auth(url, token) -> requests.Response | None
Authenticated DELETE. Returns the response object on success (status < 400), or None on error.
is_recent(last_modified_ms, within_seconds, now=None) -> bool
Return True if last_modified_ms (milliseconds since epoch, as returned by the Harvest Files API) falls within the past within_seconds seconds.
| Parameter | Type | Description |
|---|---|---|
last_modified_ms |
int |
Milliseconds since epoch |
within_seconds |
int |
Threshold in seconds |
now |
datetime | None |
Reference time (UTC). Defaults to datetime.now(timezone.utc) |
if sl.is_recent(entry["lastModifiedTime"], within_seconds=7 * 86_400):
print("Modified within the last week")
resolve_entry_timestamp(entry: FileEntry, tz=timezone.utc) -> datetime | None
Resolve the best available timestamp for a FileEntry. Currently returns entry.last_modified converted to tz, or None if it is absent.
| Parameter | Type | Description |
|---|---|---|
entry |
FileEntry |
An entry returned by list_files_iterative() |
tz |
timezone |
Timezone for the returned datetime (default: UTC) |
Bulk download pattern
download_and_save() operates on one file at a time, giving you full control over size limits, delete-after-download, and error handling per file.
import os
import soracomlib as sl
auth_info = sl.read_auth_keys()
token = sl.authenticate(auth_info)
files = sl.list_files_iterative("logs/XXXXXXXXXXXXXXXX/", token)
save_dir = "./download/XXXXXXXXXXXXXXXX"
os.makedirs(save_dir, exist_ok=True)
LIMIT_BYTES = 200 * 1024 * 1024 # 200 MB
downloaded_bytes = 0
for entry in sorted(files, key=lambda e: e.path):
if downloaded_bytes >= LIMIT_BYTES:
break
local_path = os.path.join(save_dir, os.path.basename(entry.path))
ok = sl.download_and_save(entry.path, local_path, token)
if ok:
downloaded_bytes += os.path.getsize(local_path)
# Optionally delete from Harvest Files after download:
# sl.delete_with_auth(f"{sl.API_BASE}/files/private/{entry.path}", token)
Logging
The library uses Python's standard logging module under the logger name soracomlib.soracom_harvest_files.
By default a NullHandler is attached, so no output appears unless your application configures logging.
To integrate with your own logging config:
import logging
# Show INFO and above from this library on stderr
logging.basicConfig(level=logging.INFO)
logging.getLogger("soracomlib.soracom_harvest_files").propagate = True
# Or suppress all output from this library
logging.getLogger("soracomlib.soracom_harvest_files").setLevel(logging.CRITICAL)
License
Copyright (c) 2025-2026 tkxu
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Release files for soracom-lib 0.1.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| soracom_lib-0.1.9.tar.gz | 9.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| soracom_lib-0.1.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.2 kB
Release files / soracom_lib-0.1.9.tar.gz
| Download URL | soracom_lib-0.1.9.tar.gz |
|---|---|
| Size | 9.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5488c0931427388255c8e5fd69854c145c3828d4dec5a1d0a072f83be6e0944
|
|
BLAKE2b-256 checksum How to use checksums |
87f92b4003da090b9fd9347b2b7ffb3f19449e715b15e532caf8ae34c08a386d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency logRelease files / soracom_lib-0.1.9-py3-none-any.whl
| Download URL | soracom_lib-0.1.9-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0a11af50622885d0829a6150848c4a45fe97c2143a9b36f55e088afd1f5d0d5c
|
|
BLAKE2b-256 checksum How to use checksums |
bb049917e98995dfc3fa92cba888c2eab40d33e7801a957e652fbfc7563dd577
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.
Transparency log