Usage¶
All v2 functionality is exposed through GleifClient,
importable as pygleif.GleifClient or pygleif.v2.GleifClient.
from pygleif import GleifClient
client = GleifClient()
Every method has an async counterpart prefixed with a (e.g. search /
asearch, get_lei / aget_lei, fields / afields). Both share the same
httpx-based
Transport, so you can freely mix sync and async
usage against the same client. See “Async usage” below.
Fetching a single LEI record¶
response = client.get_lei_record("549300MLUDYVRQOOXS22")
print(response.data.attributes.entity.legal_name.name)
# prints UK EQUITY FUND (OFFSHORE)
For a normalized, generation-agnostic view (a RecordLike),
use get_lei instead:
record = client.get_lei("549300MLUDYVRQOOXS22")
print(record.lei, record.legal_name, record.country)
Searching¶
results = client.search_fulltext("Deutsche Bank")
for item in results.data:
print(item.attributes.lei, item.attributes.entity.legal_name.name)
Look up records by BIC or ISIN:
client.by_bic("DEUTDEFFXXX")
client.by_isin("DE0005140008")
Or run an arbitrary filtered search with sorting and pagination:
from pygleif import SearchType
client.search(
filters={SearchType.LEGAL_NAME: "Deutsche Bank"},
sort="entity.legalName",
page_number=1,
page_size=15,
)
Filter operators¶
Filter values are passed through verbatim, so the API’s documented search operators work directly:
client.search(filters={"entity.legalAddress.country": "!GB"}) # NOT
client.search(filters={"entity.legalName": "facebook,twitter"}) # IN
client.search(filters={"entity.expiration.date": "19900101..19950101"}) # range
client.search(filters={"entity.expiration.date": ">=20190723"}) # comparison
Multiple filters combine as a logical AND. To find relationship data via
search, use the owns (“who owns X?” — returns parents) and ownedBy
(“who is owned by X?” — returns children) filters:
client.search(filters={"owns": "549300MLUDYVRQOOXS22"})
client.search(filters={"ownedBy": "549300MLUDYVRQOOXS22"})
Level 2 relationship data¶
Fetch parent and child LEI records through the dedicated relationship endpoints:
client.direct_parent("549300MLUDYVRQOOXS22") # single LEI record
client.ultimate_parent("549300MLUDYVRQOOXS22") # single LEI record
client.direct_children("549300MLUDYVRQOOXS22") # paginated LEI records
client.ultimate_children("549300MLUDYVRQOOXS22") # paginated LEI records
The relationship records themselves (reporting periods, corroboration, relationship status) are available too:
client.direct_parent_relationship("549300MLUDYVRQOOXS22")
client.ultimate_parent_relationship("549300MLUDYVRQOOXS22")
client.direct_child_relationships("549300MLUDYVRQOOXS22")
client.ultimate_child_relationships("549300MLUDYVRQOOXS22")
When an entity reports no parent, the parent lookups raise
PyGLEIFNotFoundError and the reason is available
as a reporting exception:
from pygleif.v2.error import PyGLEIFNotFoundError
try:
client.direct_parent("9845001B2AD43E664E58")
except PyGLEIFNotFoundError:
exception = client.direct_parent_reporting_exception("9845001B2AD43E664E58")
print(exception.data.attributes.reason) # e.g. NON_CONSOLIDATING
ultimate_parent_reporting_exception works the same way for the ultimate
parent.
ISIN mappings¶
client.isins("549300MLUDYVRQOOXS22")
Field modifications (record history)¶
Retrieve the historical changes of an LEI record, optionally filtered:
client.field_modifications("549300MLUDYVRQOOXS22")
client.field_modifications(
"549300MLUDYVRQOOXS22",
modification_type="UPDATE",
record_type="RR",
page_size=50,
)
Completions and field metadata¶
client.fuzzy_completions("Deutche Bank") # approximate matches, typo-tolerant
client.autocompletions("Deutsche") # suggested search terms
client.fields() # technical metadata about API fields
client.get_field("LEIREC_FULLTEXT") # metadata for one field
Both completion endpoints accept a field argument (fulltext,
entity.legalName, owns, ownedBy — see
SearchType).
LEI and vLEI issuers¶
client.lei_issuers() # accredited LOUs
client.get_lei_issuer("5299000J2N45DDNE4Y28") # one LOU by its LEI
client.lei_issuer_jurisdictions("5299000J2N45DDNE4Y28")
client.vlei_issuers() # qualified vLEI issuers
client.get_vlei_issuer("549300O897ZC5H7CY412")
Reference data¶
Each code list has a paginated list method and a get_* detail lookup:
client.countries() # ISO 3166 country codes
client.get_country("US")
client.entity_legal_forms() # ISO 20275 ELF codes
client.get_entity_legal_form("10UR")
client.official_organizational_roles() # ISO 5009 OOR codes
client.get_official_organizational_role("01D0O4")
client.jurisdictions() # legal jurisdictions
client.get_jurisdiction("US-DE")
client.regions() # ISO 3166 sub-regions
client.get_region("AD-07")
client.registration_authorities() # GLEIF RA code list
client.get_registration_authority("RA000001")
client.registration_agents()
client.get_registration_agent("5d10d4dc929ab6.72309473")
Exporting LEI records¶
Download up to 5000 LEI records as a file (csv, xlsx or json),
narrowed by the same filters as search:
from pygleif import ExportFormat
payload = client.export_lei_records(
export_format=ExportFormat.CSV,
filters={"entity.legalAddress.country": "SE"},
)
with open("lei-records.csv", "wb") as handle:
handle.write(payload)
Health check¶
if not client.healthcheck():
... # API is unreachable
Async usage¶
Every method described above has an a-prefixed async counterpart that
takes the same arguments and returns the same response model:
import asyncio
from pygleif import GleifClient
async def main() -> None:
async with GleifClient() as client:
record = await client.aget_lei("549300MLUDYVRQOOXS22")
results = await client.asearch_fulltext("Deutsche Bank")
print(record.legal_name, len(results.data))
asyncio.run(main())
Using async with (or with for sync-only code) ensures the underlying
httpx connection pool is closed when you’re done. Without a context
manager, call client.close() or await client.aclose() explicitly:
client = GleifClient()
try:
client.search_fulltext("Deutsche Bank")
finally:
client.close()
Error handling¶
All v2 errors derive from PyGLEIFError:
from pygleif.v2.error import PyGLEIFNotFoundError, PyGLEIFRateLimitError
try:
client.get_lei_record("does-not-exist")
except PyGLEIFNotFoundError:
... # HTTP 404
except PyGLEIFRateLimitError:
... # HTTP 429 - 60 requests/minute limit exceeded