EarthScope miniSEED data can be read directly from S3. There are two buckets depending on which network you need:
| Data | Networks | S3 location |
|---|---|---|
| AWS Open Data Program | AK, II, IU, N4, PB, TA, UU, UW | s3://earthscope-geophysical-data |
| EarthScope Repository | All other networks | s3://earthscope-mseed-v2-4fdodyzpsz8u8uyi3pa9qsw9oid1suse2a-s3alias |
Data in both buckets use the same object key layout: miniseed/NETWORK/YEAR/DAYOFYEAR/STATION.NETWORK.YEAR.DAYOFYEAR
Prerequisites¶
An EarthScope account: https://
www .earthscope .org /user Account approved for S3 direct access
Retrieving data from the Repository bucket must occur within AWS
us-east-2Retrieving data from Open Data Program is allowed everywhere
from earthscope_sdk import EarthScopeClient
client = EarthScopeClient()Well-behaved Clients¶
When calling the credentials API from long-running jobs or bulk downloads, follow these rules:
Reuse the
EarthScopeClientinstance.Create one client and keep it for the lifetime of the process. A new client per request discards the SDK’s in-memory credential cache and forces unnecessary OAuth and token-exchange traffic.
Reuse credentials for the whole S3 prefix until they expire (or are near expiration).
Credentials from
client.user.get_aws_credentials(...)(or a boto session built from them) authorize every object under that network — or network+year — prefix. Do not request new credentials for each object.Do not retry unretriable errors (
400,403,404). Those are verdicts on the request, not transient failures:400Bad Request — the request itself is invalid.A common case is asking for a temporary network without a
year. Temporary FDSN codes are reused across experiments, so EarthScope must authorize at the network+year level.403Forbidden — your account does not have access to that network or network+year.404Not Found — the FDSN network code (or network+year) you requested was not found.
Obtaining Credentials¶
Request credentials without network for Open Data Program bucket access and Repository listing. See API documentation.
boto3 is the AWS SDK for Python. The earthscope-sdk’s client.user.get_boto3_session(...) wraps the credentials endpoint and returns a refreshable boto3 session.
session = client.user.get_boto3_session(role="s3-miniseed-v2")
s3_client = session.client("s3")
ODP_BUCKET = "earthscope-geophysical-data"
REPO_BUCKET = "earthscope-mseed-v2-4fdodyzpsz8u8uyi3pa9qsw9oid1suse2a-s3alias"
PREFIX = "miniseed/"Read AWS Open Data Program (ODP) networks¶
Networks AK, II, IU, N4, PB, TA, UU, UW are published through the AWS Open Data Program as Sponsored Open Data on AWS. Read them from the bucket earthscope-geophysical-data.
list_resp = s3_client.list_objects_v2(
Bucket=ODP_BUCKET,
Prefix=PREFIX,
Delimiter="/",
)
odp_networks = [c["Prefix"].split("/", 1)[1] for c in list_resp["CommonPrefixes"]]
print(odp_networks)
object_key = "miniseed/TA/2004/365/A04A.TA.2004.365"
response = s3_client.get_object(Bucket=ODP_BUCKET, Key=object_key)
data = response["Body"].read()
print(f"Downloaded {len(data)} bytes from s3://{ODP_BUCKET}/{object_key}")['AK/', 'II/', 'IU/', 'N4/', 'PB/', 'TA/', 'UU/', 'UW/']
Downloaded 2740224 bytes from s3://earthscope-geophysical-data/miniseed/TA/2004/365/A04A.TA.2004.365
Repository direct access¶
For networks not published to the Open Data Program, request credentials with an explicit FDSN network — for example network="FDSN:UO". Credentials for permanent networks authorize GetObject to objects under miniseed/<NETWORK>/*.
NETWORK = "FDSN:UO"
repo_session = client.user.get_boto3_session(
role="s3-miniseed-v2",
network=NETWORK,
)
repo_s3 = repo_session.client("s3")Temporary networks¶
Temporary FDSN networks reuse classical 2-character FDSN network codes so credentials must be scoped to a specific network-year prefix: miniseed/<NETWORK>/<YEAR>/*.
When requesting credentials for a temporary FDSN network (i.e. it starts with digits 0-9 or letters X, Y or Z), you must include year in the credential request:
repo_session = client.user.get_boto3_session(
role="s3-miniseed-v2",
network="FDSN:1E",
year=2024,
)Repository data is exposed via an S3 Access Point (S3AP). The access point alias is used in place of the bucket name in all S3 operations.
Credentials allow listing the entire miniseed/ prefix on the access point, including all network “subdirectories”. All networks appear in listings but cannot be downloaded unless your credentials were issued for that network (and year, if applicable).
list_resp = repo_s3.list_objects_v2(
Bucket=REPO_BUCKET,
Prefix=PREFIX,
Delimiter="/",
)
nets = [c["Prefix"].split("/", 1)[1] for c in list_resp["CommonPrefixes"]]
print(nets)['12/', '14/', '16/', '17/', '1A/', '1B/', '1C/', '1D/', '1E/', '1F/', '1G/', '1H/', '1J/', '1K/', '1L/', '1M/', '1O/', '1P/', '1Q/', '1R/', '1T/', '1U/', '1V/', '1W/', '1Z/', '22/', '24/', '28/', '29/', '2A/', '2B/', '2C/', '2D/', '2E/', '2F/', '2G/', '2H/', '2I/', '2J/', '2K/', '2L/', '2M/', '2O/', '2P/', '2Q/', '2T/', '2U/', '2V/', '34/', '3A/', '3B/', '3C/', '3D/', '3E/', '3F/', '3H/', '3J/', '3K/', '3L/', '3R/', '3U/', '3W/', '3Y/', '4A/', '4B/', '4E/', '4F/', '4H/', '4I/', '4J/', '4K/', '4N/', '4O/', '4P/', '4Q/', '4R/', '4S/', '4T/', '4U/', '4Y/', '4Z/', '5A/', '5B/', '5C/', '5E/', '5F/', '5G/', '5H/', '5I/', '5J/', '5K/', '5L/', '5O/', '5P/', '5Q/', '5S/', '5W/', '5X/', '6A/', '6B/', '6C/', '6D/', '6E/', '6F/', '6G/', '6H/', '6I/', '6J/', '6K/', '6L/', '6M/', '6N/', '6O/', '6P/', '6Q/', '6R/', '6W/', '7A/', '7B/', '7C/', '7D/', '7E/', '7F/', '7G/', '7I/', '7J/', '7K/', '7L/', '7O/', '7P/', '7Q/', '7S/', '7T/', '7U/', '8A/', '8B/', '8E/', '8F/', '8G/', '8H/', '8I/', '8J/', '8L/', '8M/', '8P/', '8Q/', '8S/', '8U/', '8W/', '9A/', '9B/', '9C/', '9D/', '9F/', '9G/', '9H/', '9K/', '9L/', '9M/', '9P/', '9R/', 'A0/', 'A2/', 'A7/', 'AB/', 'AC/', 'AE/', 'AF/', 'AG/', 'AI/', 'AK/', 'AL/', 'AM/', 'AO/', 'AP/', 'AR/', 'AS/', 'AT/', 'AU/', 'AV/', 'AX/', 'AY/', 'AZ/', 'B6/', 'BC/', 'BE/', 'BF/', 'BI/', 'BK/', 'BL/', 'BV/', 'BX/', 'C/', 'C0/', 'C1/', 'C8/', 'CA/', 'CB/', 'CC/', 'CD/', 'CH/', 'CI/', 'CK/', 'CM/', 'CN/', 'CO/', 'CS/', 'CT/', 'CU/', 'CW/', 'CY/', 'CZ/', 'DA/', 'DE/', 'DK/', 'DR/', 'DT/', 'DU/', 'DW/', 'EC/', 'EI/', 'EM/', 'EO/', 'EP/', 'ER/', 'ET/', 'FA/', 'G/', 'GB/', 'GD/', 'GE/', 'GF/', 'GG/', 'GH/', 'GI/', 'GM/', 'GO/', 'GR/', 'GS/', 'GT/', 'GY/', 'H2/', 'HG/', 'HK/', 'HL/', 'HT/', 'HV/', 'HW/', 'HZ/', 'I0/', 'IC/', 'ID/', 'IE/', 'II/', 'IL/', 'IM/', 'IN/', 'IO/', 'IP/', 'IU/', 'IV/', 'IW/', 'JM/', 'JP/', 'JW/', 'K5/', 'KC/', 'KG/', 'KN/', 'KO/', 'KP/', 'KR/', 'KS/', 'KW/', 'KY/', 'KZ/', 'LB/', 'LD/', 'LH/', 'LI/', 'LM/', 'LO/', 'LX/', 'M8/', 'MB/', 'MC/', 'MG/', 'MH/', 'MI/', 'MM/', 'MN/', 'MP/', 'MR/', 'MS/', 'MU/', 'MX/', 'MY/', 'MZ/', 'N0/', 'N4/', 'NA/', 'NB/', 'NC/', 'NE/', 'NI/', 'NJ/', 'NK/', 'NL/', 'NM/', 'NN/', 'NO/', 'NP/', 'NQ/', 'NR/', 'NT/', 'NU/', 'NV/', 'NW/', 'NX/', 'NY/', 'NZ/', 'O2/', 'OC/', 'OE/', 'OH/', 'OI/', 'OK/', 'ON/', 'OO/', 'OQ/', 'OV/', 'OW/', 'OX/', 'OZ/', 'PA/', 'PB/', 'PE/', 'PI/', 'PL/', 'PM/', 'PN/', 'PO/', 'PQ/', 'PR/', 'PS/', 'PT/', 'PY/', 'QC/', 'QN/', 'QZ/', 'RC/', 'RE/', 'RI/', 'RM/', 'RO/', 'RS/', 'RU/', 'RV/', 'S1/', 'S8/', 'SB/', 'SC/', 'SE/', 'SF/', 'SG/', 'SH/', 'SN/', 'SP/', 'SR/', 'SS/', 'SV/', 'SY/', 'TA/', 'TC/', 'TD/', 'TF/', 'TJ/', 'TM/', 'TO/', 'TR/', 'TT/', 'TW/', 'TX/', 'TZ/', 'UF/', 'UH/', 'UI/', 'UK/', 'UM/', 'UO/', 'US/', 'UT/', 'UU/', 'UW/', 'VD/', 'VE/', 'VU/', 'WA/', 'WC/', 'WF/', 'WI/', 'WM/', 'WU/', 'WW/', 'WY/', 'X1/', 'X2/', 'X3/', 'X4/', 'X5/', 'X6/', 'X7/', 'X8/', 'X9/', 'XA/', 'XB/', 'XC/', 'XD/', 'XE/', 'XF/', 'XG/', 'XH/', 'XI/', 'XJ/', 'XK/', 'XL/', 'XM/', 'XN/', 'XO/', 'XP/', 'XQ/', 'XR/', 'XS/', 'XT/', 'XU/', 'XV/', 'XW/', 'XX/', 'XY/', 'XZ/', 'Y1/', 'Y2/', 'Y3/', 'Y4/', 'Y5/', 'Y6/', 'Y7/', 'Y8/', 'Y9/', 'YA/', 'YB/', 'YC/', 'YD/', 'YE/', 'YF/', 'YG/', 'YH/', 'YI/', 'YJ/', 'YK/', 'YL/', 'YM/', 'YN/', 'YO/', 'YP/', 'YQ/', 'YR/', 'YS/', 'YT/', 'YU/', 'YV/', 'YW/', 'YX/', 'YY/', 'YZ/', 'Z1/', 'Z2/', 'Z3/', 'Z4/', 'Z5/', 'Z6/', 'Z7/', 'Z8/', 'Z9/', 'ZA/', 'ZB/', 'ZC/', 'ZD/', 'ZE/', 'ZF/', 'ZG/', 'ZH/', 'ZI/', 'ZJ/', 'ZK/', 'ZL/', 'ZM/', 'ZN/', 'ZO/', 'ZP/', 'ZQ/', 'ZR/', 'ZS/', 'ZT/', 'ZU/', 'ZV/', 'ZW/', 'ZX/', 'ZY/', 'ZZ/']
Objects under the FDSN network (and year) associated with your credentials download successfully — including unrestricted data and restricted data you have access to.
The cell below lists one object under the requested network and reads it. Adjust the year/day prefix if needed for your network.
network_code = NETWORK.split(":", 1)[1]
list_prefix = f"{PREFIX}{network_code}/2024/300/"
list_resp = repo_s3.list_objects_v2(Bucket=REPO_BUCKET, Prefix=list_prefix, MaxKeys=1)
object_key = list_resp["Contents"][0]["Key"]
response = repo_s3.get_object(Bucket=REPO_BUCKET, Key=object_key)
data = response["Body"].read()
print(f"Downloaded {len(data)} bytes from s3://{REPO_BUCKET}/{object_key}")Downloaded 57044480 bytes from s3://earthscope-mseed-v2-4fdodyzpsz8u8uyi3pa9qsw9oid1suse2a-s3alias/miniseed/UO/2024/300/ADEL.UO.2024.300#2
Access denied outside your FDSN network scope¶
Credentials are scoped to the requested FDSN network (and year for temporary networks). Downloading an object outside that scope returns a standard S3 AccessDenied error.
try:
repo_s3.get_object(
Bucket=REPO_BUCKET,
Key=f"{PREFIX}1E/2024/089/BCH1A.1E.2024.089#2",
)
raise RuntimeError("Should not reach this line")
except Exception as e:
print("Expected failure for an object outside the credential's scope:")
print(e)Expected failure for an object outside the credential's scope:
An error occurred (AccessDenied) when calling the GetObject operation: User: arn:aws:sts::457219964709:assumed-role/earthscope-idm-mseed-v2/euid=Z29vZ2xlLW9hdXRoMnwxMTg0MDM1MDYxNTQ5NDI4NDI1ODM is not authorized to perform: s3:GetObject on resource: "arn:aws:s3:us-east-2:457219964709:accesspoint/earthscope-mseed-v2/object/miniseed/1E/2024/089/BCH1A.1E.2024.089#2" because no session policy allows the s3:GetObject action
Additional credential retrieval methods¶
Above, we demonstrate using the AWS boto3 python SDK for classical synchronous python programming. The following sections demonstrate how to retrieve temporary AWS credentials for additional use cases.
Asynchronous python with aioboto3¶
The aioboto3 library wraps boto3 in async interfaces for running code in an event loop.
The AsyncEarthScopeClient provides a method to retrieve a refreshable aioboto3 session.
from earthscope_sdk import AsyncEarthScopeClient
async_client = AsyncEarthScopeClient()
session = await async_client.user.get_aioboto3_session(
role="s3-miniseed-v2",
network=NETWORK,
)
async with session.client("s3") as async_s3:
response = await async_s3.get_object(Bucket=REPO_BUCKET, Key=object_key)
async with response["Body"] as stream:
data = await stream.read()
print(f"Downloaded {len(data)} bytes from s3://{REPO_BUCKET}/{object_key}")Downloaded 57044480 bytes from s3://earthscope-mseed-v2-4fdodyzpsz8u8uyi3pa9qsw9oid1suse2a-s3alias/miniseed/UO/2024/300/ADEL.UO.2024.300#2
Non-boto use-cases¶
The methods EarthScopeClient.user.get_boto3_session(...) and AsyncEarthScopeClient.user.get_aioboto3_session(...) are convenience methods that return boto sessions that transparently handle credential expiration and refresh on your behalf.
However, there are many non-boto libraries for interacting with S3 that need credentials as well. To work with your library of choice using EarthScope direct access, you can retrieve AWS credentials directly.
creds = client.user.get_aws_credentials(
role="s3-miniseed-v2",
network=NETWORK,
)
# pass credentials to your library of choice
print(creds.expiration)
print(creds.aws_access_key_id)
print(creds.aws_secret_access_key) # use creds.aws_secret_access_key.get_secret_value() to access the plaintext key
print(creds.aws_session_token) # use creds.aws_session_token.get_secret_value() to access the plaintext session token2026-08-26 21:45:23+00:00
ASIAWU5DO74SQVW7DUAK
**********
**********
Use the Open Data Program without an EarthScope account¶
Data in the Open Data Program is freely readable without authentication using an unsigned S3 client or the AWS CLI with --no-sign-request. That path does not attribute usage to your EarthScope user ID.
See Sponsored Open Data on AWS for details.