# Usage All v2 functionality is exposed through {class}`~pygleif.v2.client.GleifClient`, importable as `pygleif.GleifClient` or `pygleif.v2.GleifClient`. ```python 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`](https://www.python-httpx.org/)-based {class}`~pygleif.v2.base.Transport`, so you can freely mix sync and async usage against the same client. See "Async usage" below. ## Fetching a single LEI record ```python 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 {class}`~pygleif.compat.interfaces.RecordLike`), use `get_lei` instead: ```python record = client.get_lei("549300MLUDYVRQOOXS22") print(record.lei, record.legal_name, record.country) ``` ## Searching ```python 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: ```python client.by_bic("DEUTDEFFXXX") client.by_isin("DE0005140008") ``` Or run an arbitrary filtered search with sorting and pagination: ```python 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: ```python 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: ```python 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: ```python 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: ```python 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 {class}`~pygleif.v2.error.PyGLEIFNotFoundError` and the reason is available as a reporting exception: ```python 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. ## Related records ```python client.lei_issuer("549300MLUDYVRQOOXS22") # the issuer (LOU) record client.managing_lou("549300MLUDYVRQOOXS22") # the LOU's own LEI record client.associated_entity("549300MLUDYVRQOOXS22") # fund manager, if any client.successor_entity("549300MLUDYVRQOOXS22") # successor, if any ``` ## ISIN mappings ```python client.isins("549300MLUDYVRQOOXS22") ``` ## Field modifications (record history) Retrieve the historical changes of an LEI record, optionally filtered: ```python client.field_modifications("549300MLUDYVRQOOXS22") client.field_modifications( "549300MLUDYVRQOOXS22", modification_type="UPDATE", record_type="RR", page_size=50, ) ``` ## Completions and field metadata ```python 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 {class}`~pygleif.v2.client.SearchType`). ## LEI and vLEI issuers ```python 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: ```python 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`: ```python 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 ```python 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: ```python 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: ```python client = GleifClient() try: client.search_fulltext("Deutsche Bank") finally: client.close() ``` ## Error handling All v2 errors derive from {class}`~pygleif.v2.error.PyGLEIFError`: ```python 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 ```