pyfdb ===== .. py:module:: pyfdb Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/pyfdb/pyfdb/index /autoapi/pyfdb/pyfdb_iterator/index /autoapi/pyfdb/pyfdb_type/index Attributes ---------- .. autoapisummary:: pyfdb.MarsSelection Classes ------- .. autoapisummary:: pyfdb.URI pyfdb.DataHandle pyfdb.ControlAction pyfdb.ControlIdentifier pyfdb.FDB pyfdb.ListElement pyfdb.StatusElement pyfdb.WipeElement pyfdb.PurgeElement pyfdb.StatsElement pyfdb.ControlElement pyfdb.IndexAxis Package Contents ---------------- .. py:class:: URI(uri: str | pathlib.Path, scheme: str = '', allow_fragments=True) Class describing a unique resource identifier. :param None: .. rubric:: Examples >>> uri = URI("scheme://user:secretpass@example.com:8443/path/to/resource?query=search&sort=asc#section-2") .. py:attribute:: _uri :type: urllib.parse.SplitResult .. py:method:: __eq__(value: object, /) -> bool .. py:method:: __ne__(value: object, /) -> bool .. py:method:: _to_internal() .. py:method:: netloc() -> str .. py:method:: scheme() -> str .. py:method:: username() -> str | None .. py:method:: password() -> str | None .. py:method:: hostname() -> str | None .. py:method:: port() -> int | None .. py:method:: path() -> str .. py:method:: query() -> str .. py:method:: fragment() -> str .. py:method:: __repr__() -> str .. py:class:: DataHandle(dataHandle: pyfdb._internal._DataHandle, *, _internal=False) DataHandle class for lazy reading from a data source. :param None: .. note:: *This class can't be instantiated / is only returned from the underlying FDB calls* :rtype: `DataHandle` class .. rubric:: Examples >>> request = { >>> "type": "an", >>> "class": "ea", >>> "domain": "g", >>> "expver": "0001", >>> "stream": "oper", >>> "date": "20200101", >>> "levtype": "sfc", >>> "step": "0", >>> "param": ["167", "165", "166"], >>> "time": "1800", >>> } >>> data_handle = fdb.retrieve(request) >>> data_handle.open() >>> data_handle.read(4) == b"GRIB" >>> data_handle.close() >>> # OR >>> with fdb.retrieve(request) as data_handle: >>> data_handle.read(4) == b"GRIB" .. py:attribute:: dataHandle :type: pyfdb._internal._DataHandle .. py:attribute:: opened :value: False .. py:method:: __enter__() -> DataHandle .. py:method:: __exit__(exc_type, exc_value, exc_traceback) .. py:method:: open() -> None Open the DataHandle object for reading. :param None: :rtype: None .. rubric:: Examples >>> data_handle = fdb.retrieve(request) >>> data_handle.open() >>> data_handle.read(4) == b"GRIB" >>> data_handle.close() .. py:method:: close() -> None Close the DataHandle object after reading. :param None: :rtype: None .. rubric:: Examples >>> data_handle = fdb.retrieve(request) >>> data_handle.open() >>> data_handle.read(4) == b"GRIB" >>> data_handle.close() .. py:method:: size() -> int Return the size of a data handle in bytes. :param None: :rtype: `int` describing the size of the datahandle in bytes. .. rubric:: Examples >>> with fdb.retrieve(selection) as data_handle: >>> data_handle.size() # Returns the size of the datahandle in bytes .. py:method:: read(len: int = -1) -> bytes Read a given amount of bytes from the `DataHandle`. This method copies the data from the underlying memory. :param `len`: Number of bytes to read. Defaults to -1, which reads the entire buffer. If the requested size exceeds the available data, the result is zero-padded to match the requested size. :type `len`: int :rtype: `bytes` object resembling the read data. :raises RuntimeError: .. rubric:: Examples >>> with fdb.retrieve(request) as data_handle >>> data_handle.read(4) == b"GRIB" >>> #or >>> data_handle.read(-1) # Read the entire file .. py:method:: readinto(buffer: memoryview) -> int Read a given amount of bytes from the `DataHandle` into a `memoryview`. This is a zero-copy method. :param `buffer`: Memory view for the buffer in which the bytes should be read :type `buffer`: `memoryview` :rtype: `int` size of bytes which have been read :raises RuntimeError: .. rubric:: Examples >>> dst_read_into = io.BytesIO(b"") >>> with fdb.retrieve(selection) as data_handle: >>> assert data_handle >>> shutil.copyfileobj(data_handle, dst_read_into) >>> # Reset position in file >>> dst_read_into.seek(0) .. py:method:: readall(buffer_size: int = 1024) -> bytes Read all bytes from the DataHandle into memory. This method copies the data from the underlying memory. :param `buffer_size`: The size of the buffer which is used for reading :type `buffer_size`: `int` .. note:: *There is no need to open the DataHandle before*. This is handled by the function. The default chunk size is 1024 bytes. :rtype: `bytes` object resembling the read data .. rubric:: Examples >>> data_handle = fdb.retrieve(request) >>> data_handle.readall() # Returns all content of a datahandle b"GRIB..." .. py:method:: __repr__() -> str .. py:class:: ControlAction Bases: :py:obj:`enum.IntEnum` Specify which action should be executed, e.g. `DISABLE` or `ENABLE`. Values ------ - NONE - DISABLE - ENABLE Initialize self. See help(type(self)) for accurate signature. .. py:attribute:: NONE :value: 0 .. py:attribute:: DISABLE .. py:attribute:: ENABLE .. py:method:: _from_raw(en: pyfdb._internal._ControlAction) :classmethod: .. py:method:: _to_raw() .. py:method:: __repr__() -> str Return repr(self). .. py:method:: __str__() -> str Return str(self). .. py:class:: ControlIdentifier Bases: :py:obj:`enum.IntFlag` Specify which functionality of the FDB should be addressed, e.g. RETRIEVE or LIST. Values ------ - NONE - LIST - RETRIEVE - ARCHIVE - WIPE - UNIQUEROOT Initialize self. See help(type(self)) for accurate signature. .. py:attribute:: NONE :value: 0 .. py:attribute:: LIST .. py:attribute:: RETRIEVE .. py:attribute:: ARCHIVE .. py:attribute:: WIPE .. py:attribute:: UNIQUEROOT .. py:method:: _from_raw(en: pyfdb._internal._ControlIdentifier) :classmethod: .. py:method:: _to_raw() .. py:method:: __repr__() -> str Return repr(self). .. py:method:: __str__() -> str Return str(self). .. py:data:: MarsSelection Selection part of a MARS request. This is a key-value map, with the data types allowed below .. py:class:: FDB(config: str | dict | pathlib.Path | None = None, user_config: str | dict | pathlib.Path | None = None) Constructor for FDB object. :param `config`: Config object for setting up the FDB. See Notes. :type `config`: `str` | `dict` | `Path` | `None`, *optional* :param `user_config`: Config object for setting up user specific options, e.g., enabling sub-TOCs. See Notes. :type `user_config`: `str` | `dict` | `Path` | `None`, *optional* :rtype: returns: FDB object .. note:: Every config parameter but is converted accordingly depending on its type: - `str` is used as a yaml representation to parse the config - `dict` is interpreted as hierarchical format to represent a config, see example - `Path` is interpreted as a location of the config and read as a YAML file - `None` is the fallback. The default config in `$FDB_HOME` is loaded Using a single PyFDB instance per individual threads is safe. Sharing the instances across threads isn't supported. However, the underlying FDB and its methods are thread-safe; the caller needs to be aware that flush acts on all archive calls, including archived messages from other threads. A call to flush will persist all archived messages regardless from which thread the message has been archived. In case the caller wants a finer control it is advised to instantiate one FDB object per thread to ensure only messages are flushed that have been archived on the same FDB object. .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> config = { ... "type":"local", ... "engine":"toc", ... "schema":"", ... "spaces":[ ... { ... "handler":"Default", ... "roots":[ ... {"path": ""}, ... ], ... } ... ], ... } >>> fdb = pyfdb.FDB(config) Or leveraging the context manager: >>> with pyfdb.FDB(fdb_config_path) as fdb: ... # Call methods of fdb ... pass .. py:attribute:: logger .. py:method:: __enter__() .. py:method:: __exit__(exc_type, exc_value, exc_traceback) .. py:method:: archive(data: bytes, identifier: pyfdb.pyfdb_type.MarsIdentifier | None = None) Archive binary data into the underlying FDB. In case an identifier is supplied, that identifier is used to archive the data. *No consistency checks are applied. The caller needs to ensure the provided identifier matches metadata present in data.* If no identifier is supplied, `data` is interpreted as GRIB data and the metadata is taken from the GRIB messages. In any case, the supplied or derived metadata needs to provide values for all required keys of the FDB schema. :param `data`: The binary data to be archived. If no key is provided this is interpreted by `eccodes` and may contain multiple GRIB messages. :type `data`: `bytes` :param `identifier`: A unique identifier for the archived data. - If provided, the data will be stored under this identifier. - If None, the data will be archived without an explicit identifier, metadata has to be derivable from the data, which is interpreted as GRIB data. :type `identifier`: `Identifier` | None, optional .. note:: Sometimes an identifier is also referred to as a Key. :rtype: None .. rubric:: Examples >>> fdb = pyfdb.FDB() >>> filename = data_path / "x138-300.grib" >>> fdb.archive(data=filename.read_bytes()) # Archive >>> fdb.archive(identifier=Identifier([("key-1", "value-1")]), data=filename.read_bytes()) >>> fdb.flush() # Sync the archive call .. py:method:: flush() Flush all buffers and close all data handles of the underlying FDB into a consistent DB state. *Always safe to call* :param None: :rtype: None .. rubric:: Examples >>> fdb = pyfdb.FDB() >>> filename = data_path / "x138-300.grib" >>> fdb.archive(bytes=filename.read_bytes()) # Archive >>> fdb.flush() # Data is synced .. py:method:: retrieve(mars_selection: pyfdb.pyfdb_type.MarsSelection) -> pyfdb.pyfdb_type.DataHandle Retrieve data which is specified by a MARS selection. :param `mars_selection`: MARS selection which describes the data which should be retrieved .. note:: The returned data handle doesn't guarantee the order of the GRIB messages. :returns: A data handle which contains unordered GRIB messages and can be read like a `BytesLike` object. :rtype: DataHandle .. rubric:: Examples >>> mars_selection = {"key-1": "value-1", ...} >>> data_handle = pyfdb.retrieve(mars_selection) >>> data_handle.open() >>> data_handle.read(4) >>> data_handle.close() Or leveraging the context manager: >>> with pyfdb.retrieve(selection) as data_handle: >>> assert data_handle >>> assert data_handle.read(4) == b"GRIB" .. py:method:: list(mars_selection: pyfdb.pyfdb_type.MarsSelection, include_masked: bool = False, level: int = 3) -> collections.abc.Generator[pyfdb.pyfdb_iterator.ListElement, None, None] List data present at the underlying fdb archive and which can be retrieved. :param `mars_selection`: A MARS selection which describes the data which can be listed. If `None` is given, all data will be listed. :type `mars_selection`: `MarsSelection` :param `include_masked`: If True, the returned iterator lists masked data, if False the elements are unique. :type `include_masked`: bool, *optional* :param `level`: Specifies the FDB schema level of the elements which are matching the selection. A level of 1 means return a level 1 key (of the FDB schema) which is matching the MARS selection. :type `level`: int [1-3], *optional* :returns: A generator for `ListElement` describing FDB entries containing data of the MARS selection :rtype: Generator[ListElement, None, None] .. note:: *this call lists masked elements if `include_masked` is `True`.* .. rubric:: Examples >>> selection = { >>> "type": "an", >>> "class": "ea", >>> "domain": "g", >>> "expver": "0001", >>> "stream": "oper", >>> "date": "20200101", >>> "levtype": "sfc", >>> "step": "0", >>> "time": "1800", >>> } >>> list_iterator = pyfdb.list(selection) # level == 3 >>> elements = list(list_iterator) >>> print(elements[0]) {class=ea,expver=0001,stream=oper,date=20200101,time=1800,domain=g} {type=an,levtype=sfc} {step=0,param=131}, tocfieldlocation[uri=uri[scheme=file,name=],offset=10732,length=10732,remapkey={}], length=10732, timestamp=176253515 >>> list_iterator = pyfdb.list(selection, level=2) >>> elements = list(list_iterator) >>> print(elements[0]) {class=ea,expver=0001,stream=oper,date=20200101,time=1800,domain=g} {type=an,levtype=sfc}, length=0, timestamp=0 >>> list_iterator = pyfdb.list(selection, level=1) >>> elements = list(list_iterator) >>> print(elements[0]) {class=ea,expver=0001,stream=oper,date=20200101,time=1800,domain=g}, length=0, timestamp=0 .. py:method:: inspect(mars_selection: pyfdb.pyfdb_type.MarsSelection) -> collections.abc.Generator[pyfdb.pyfdb_iterator.ListElement, None, None] Inspects the content of the underlying FDB and returns a generator of list elements describing which field was part of the MARS selection. :param `mars_selection`: An MARS selection for which the inspect should be executed :type `mars_selection`: `MarsSelection` :returns: A generator for `ListElement` describing FDB entries containing data of the MARS selection :rtype: Generator[ListElement, None, None] .. rubric:: Examples >>> selection = { >>> "type": "an", >>> "class": "ea", >>> "domain": "g", >>> "expver": "0001", >>> "stream": "oper", >>> "date": "20200101", >>> "levtype": "sfc", >>> "step": "0", >>> "param": "167", >>> "time": "1800", >>> } >>> list_iterator = pyfdb.inspect(selection) >>> elements = list(list_iterator) # single element in iterator >>> elements[0] {class=ea,expver=0001,stream=oper,date=20200101,time=1800,domain=g} {type=an,levtype=sfc} {param=167,step=0}, TocFieldLocation[ uri=URI[scheme=], offset=0, length=10732, remapKey={} ], length=10732, timestamp=1762537447 .. py:method:: status(mars_selection: pyfdb.pyfdb_type.MarsSelection) -> collections.abc.Generator[pyfdb.pyfdb_iterator.StatusElement, None, None] List the status of all FDB entries with their control identifiers, e.g., whether a certain database was locked for retrieval. :param `mars_selection`: An MARS selection which specifies the queried data :type `mars_selection`: `MarsSelection` :returns: A generator for `StatusElement` describing FDB entries and their control identifier :rtype: Generator[StatusElement, None, None] .. rubric:: Examples >>> selection = { >>> "type": "an", >>> "class": "ea", >>> "domain": "g", >>> }, >>> ) >>> status_iterator = pyfdb.status(selection) >>> elements = list(status_iterator) >>> elements[0] StatusElement( control_identifiers=[], key={ 'class': ['ea'], 'type': ['an'], 'date': ['20200104'], 'domain': ['g'], 'expver': ['0001'], 'stream': ['oper'], 'time': ['2100'] }, location=//ea:0001:oper:20200104:2100:g ) .. py:method:: wipe(mars_selection: pyfdb.pyfdb_type.MarsSelection, doit: bool = False, porcelain: bool = False, unsafe_wipe_all: bool = False) -> collections.abc.Generator[pyfdb.pyfdb_iterator.WipeElement, None, None] Wipe data from the database. Delete FDB databases and the data therein contained. Use the passed selection to identify the database to delete. This is equivalent to a UNIX rm command. This function deletes either whole databases, or whole indexes within databases :param `mars_selection`: An MARS selection which specifies the affected data :type `mars_selection`: `MarsSelection` :param `doit`: If true the wipe command is executed, per default there are only dry-run :type `doit`: `bool`, *optional* :param `porcelain`: Restricts the output to the wiped files :type `porcelain`: `bool`, *optional* :param `unsafe_wipe_all`: Flag for disabling all security checks and force a wipe :type `unsafe_wipe_all`: `bool`, *optional* :returns: A generator for `WipeElement` :rtype: Generator[WipeElement, None, None] .. note:: Wipe elements are not directly corresponding to the wiped files. This can be a cause for confusion. The individual wipe elements strings of the wipe output. .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> wipe_iterator = fdb.wipe({"class": "ea"}) >>> wiped_elements = list(wipe_iterator) ... Toc files to delete: /toc ... .. py:method:: purge(mars_selection: pyfdb.pyfdb_type.MarsSelection, doit: bool = False, porcelain: bool = False) -> collections.abc.Generator[pyfdb.pyfdb_iterator.PurgeElement, None, None] Remove duplicate data from the database. Purge duplicate entries from the database and remove the associated data if the data is owned and not adopted. Data in the FDB5 is immutable. It is masked, but not removed, when overwritten with new data using the same key. Masked data can no longer be accessed. Indexes and data files that only contains masked data may be removed. If an index refers to data that is not owned by the FDB (in particular data which has been adopted from an existing FDB5), this data will not be removed. :param `mars_selection`: A MARS selection which describes the data which is purged. :type `mars_selection`: `MarsSelection` :param `doit`: If true the wipe command is executed, per default there are only dry-run :type `doit`: `bool`, *optional* :param `porcelain`: Restricts the output to the wiped files :type `porcelain`: `bool`, *optional* :returns: A generator for `PurgeElement` :rtype: Generator[PurgeElement, None, None] .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> purge_iterator = fdb.purge({"class": "ea"}), doit=True) >>> purged_elements = list(purge_iterator) >>> print(purged_elements[0]) {class=ea,expver=0001,stream=oper,date=20200104,time=1800,domain=g} {type=an,levtype=sfc} {step=0,param=167}, TocFieldLocation[ uri=URI[ scheme=file, name= ], offset=32196, length=10732, remapKey={} ], length=10732, timestamp=176253976 .. py:method:: stats(mars_selection: pyfdb.pyfdb_type.MarsSelection) -> collections.abc.Generator[pyfdb.pyfdb_iterator.StatsElement, None, None] Print information about FDB databases, aggregating the information over all the databases visited into a final summary. :param `mars_selection`: A MARS selection which specifies the affected data. :type `mars_selection`: `MarsSelection` :returns: A generator for `StatsElement` :rtype: Generator[StatsElement, None, None] .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> stats_iterator = fdb.stats(selection) >>> for el list(stats_iterator): >>> print(el) Index Statistics: Fields : 3 Size of fields : 32,196 (31.4414 Kbytes) Reacheable fields : 3 Reachable size : 32,196 (31.4414 Kbytes) DB Statistics: Databases : 1 TOC records : 2 Size of TOC files : 2,048 (2 Kbytes) Size of schemas files : 228 (228 bytes) TOC records : 2 Owned data files : 1 Size of owned data files : 32,196 (31.4414 Kbytes) Index files : 1 Size of index files : 131,072 (128 Kbytes) Size of TOC files : 2,048 (2 Kbytes) Total owned size : 165,544 (161.664 Kbytes) Total size : 165,544 (161.664 Kbytes) .. py:method:: control(mars_selection: pyfdb.pyfdb_type.MarsSelection, control_action: pyfdb.pyfdb_type.ControlAction, control_identifiers: collections.abc.Collection[pyfdb.pyfdb_type.ControlIdentifier]) -> collections.abc.Generator[pyfdb.pyfdb_iterator.ControlElement, None, None] Enable certain features of FDB databases, e.g., disables or enables retrieving, list, etc. :param `mars_selection`: A MARS selection which specifies the affected data. :type `mars_selection`: `MarsSelection` :param `control_action`: Which action should be modified, e.g., ControlAction.RETRIEVE :type `control_action`: `ControlAction` :param `control_identifiers`: Should an action be enabled or disabled, e.g., ControlIdentifier.ENABLE or ControlIdentifier.DISABLE :type `control_identifiers`: `list[ControlIdentifier]` :returns: A generator for `ControlElement` :rtype: Generator[ControlElement, None, None] .. note:: Disabling of an ControlAction, e.g., ControlAction.RETRIEVE leads to the creation of a `retrieve.lock` in the corresponding FDB database. This is true for all actions. The file is removed after the Action has been disabled. **It's important to consume the iterator, otherwise the lock file isn't deleted which can cause unexpected behavior. Also, due to internal reuse of databases, create a new FDB object before relying on the newly set control_identifier, to propagate the status.** .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> selection = { >>> "class": "ea", >>> "domain": "g", >>> "expver": "0001", >>> "stream": "oper", >>> "date": "20200101", >>> "time": "1800", >>> } >>> control_iterator = fdb.control( >>> selection, >>> ControlAction.DISABLE, >>> [ControlIdentifier.RETRIEVE], >>> ) >>> elements = list(control_iterator) >>> print(elements[0]) ControlElement( control_identifiers=[RETRIEVE], key={ 'class': ['ea'], 'date': ['20200104'], 'domain': ['g'], 'expver': ['0001'], 'stream': ['oper'], 'time': ['2100'] }, location=//ea:0001:oper:20200104:2100:g ) .. py:method:: axes(mars_selection: pyfdb.pyfdb_type.MarsSelection, level: int = 3) -> pyfdb.pyfdb_iterator.IndexAxis Return the 'axes' and their extent of a MARS selection for a given level of the schema in an IndexAxis object. If a key isn't specified the entire extent (all values) are returned. :param `mars_selection`: A MARS selection which specifies the affected data. :type `mars_selection`: `MarsSelection` :param `level`: Level of the FDB Schema. Only keys of the given level are returned. :type `level`: int [1-3], *optional* :returns: A map containing Key-Value pairs of the axes and their extent :rtype: IndexAxis .. rubric:: Examples >>> fdb = pyfdb.FDB(fdb_config_path) >>> selection = { ... "type": "an", ... "class": "ea", ... "domain": "g", ... "expver": "0001", ... "stream": "oper", ... "levtype": "sfc", ... "step": "0", ... "time": "1800", ... } >>> index_axis: IndexAxis = fdb.axes(selection) # level == 3 >>> for k, v in index_axis.items(): ... print(f"k={k} | v={v}") k=class | v=['ea'] k=date | v=['20200101', '20200102', '20200103', '20200104'] k=domain | v=['g'] k=expver | v=['0001'] k=levelist | v=[''] k=levtype | v=['sfc'] k=param | v=['131', '132', '167'] k=step | v=['0'] k=stream | v=['oper'] k=time | v=['1800'] k=type | v=['an'] .. py:method:: enabled(control_identifier: pyfdb.pyfdb_type.ControlIdentifier) -> bool Check whether a specific control identifier is enabled :param `control_identifier`: A given control identifier :type `control_identifier`: `ControlIdentifier` :returns: `True` if the given control identifier is set, `False` otherwise. :rtype: `bool` .. rubric:: Examples >>> fdb_config = yaml.safe_load(fdb_config_path) >>> fdb_config["writable"] = False >>> fdb = pyfdb.FDB(fdb_config) >>> fdb.enabled(ControlIdentifier.NONE) # == True >>> fdb.enabled(ControlIdentifier.LIST) # == True >>> fdb.enabled(ControlIdentifier.RETRIEVE) # == True >>> fdb.enabled(ControlIdentifier.ARCHIVE) # == False, default True >>> fdb.enabled(ControlIdentifier.WIPE) # == False, default True >>> fdb.enabled(ControlIdentifier.UNIQUEROOT) # == True .. py:method:: dirty() Return whether a flush of the FDB is needed, for example if data was archived since the last flush. :param None: :returns: `True` if an archive happened and a flush is needed, `False` otherwise. :rtype: `bool` .. rubric:: Examples >>> fdb = FDB(fdb_config_file) >>> filename = >>> fdb.archive(open(filename, "rb").read()) >>> fdb.dirty() # == True >>> fdb.flush() >>> fdb.dirty() # == False .. py:method:: config() -> tuple[dict[str, Any], dict[str, Any]] Return the system and user configuration of the underlying FDB. :param None: :returns: Python dictionaries describing the system and user configuration :rtype: `tuple[dict[str, Any], dict[str, Any]]` .. rubric:: Examples >>> fdb = FDB(config_file) >>> system_config, user_config = fdb.config() >>> print(system_config) >>> print(user_config) .. py:method:: __repr__() -> str .. py:class:: ListElement(list_element: pyfdb._internal.ListElement, *, _internal=False) Element returned from a listing command .. py:attribute:: _element :type: pyfdb._internal.ListElement .. py:method:: has_location() -> bool Does the `ListElement` have a location :returns: `True` if this element has a location, `False` otherwise. :rtype: `bool` .. note:: Only for `ListElement`s which are on the third level of the schema. .. py:method:: offset() -> Optional[int] Offset within the file associated with the `ListElement` :returns: Offset in bytes in the data file of the FDB, if `ListElement` is on `level` 3, None otherwise. :rtype: `Optional[int]` .. note:: Only for `ListElement`s which are on the third level of the schema. .. py:method:: length() -> Optional[int] Size of the `ListElement` within the file associated. :returns: Size in bytes in the data file of the FDB, if `ListElement` is on `level` 3, None otherwise. :rtype: `Optional[int]` .. note:: Only for `ListElement`s which are on the third level of the schema. .. py:method:: combined_key() -> dict[str, str] Return the MARS keys of the `ListElement` :returns: Dictionary containing all metadata for the `ListElement` :rtype: `dict[str, str]` .. note:: Depending on the `level` specified in the `list` command, the returned dictionary contains all available keys from schema levels up to and including the requested level; keys that exist only at deeper levels are omitted. .. rubric:: Examples >>> list_iterator = fdb.list(selection, level=3) >>> assert list_iterator >>> elements = list(list_iterator) >>> for element in elements: >>> print(element.combined_key()) Output: `` ... { 'class': 'ea', 'date': '20200104', ... , 'type': 'an' } ... `` .. py:method:: keys() -> list[dict[str, str]] Return the MARS keys of the `ListElement` separated by their level in the schema. :returns: List containing MARS keys and their values for the `ListElement`. The keys are split by their level in the schema :rtype: `list[dict[str, str]]` .. note:: Depending on the `level` specified in the `list` command, the returned dictionary contains all available keys from schema levels up to and including the requested level; keys that exist only at deeper levels are omitted. .. rubric:: Examples >>> list_iterator = fdb.list(selection, level=3) >>> assert list_iterator >>> elements = list(list_iterator) >>> for element in elements: >>> print(element.keys()) Output: `` ... [{'class': 'ea', ... , 'time': '2100'}, {'levtype': 'sfc', 'type': 'an'}, {'param': '167', 'step': '0'}] ... `` .. py:property:: data_handle :type: Optional[pyfdb.pyfdb_type.DataHandle] Access the `DataHandle` :returns: Data Handle for accessing the data of the list element :rtype: `DataHandle` .. rubric:: Examples >>> data_handle = list_element.data_handle >>> if data_handle is not None: >>> data_handle.open() >>> data_handle.read(4) >>> data_handle.close() Output: ``b"GRIB"`` .. py:property:: uri :type: Optional[pyfdb.pyfdb_type.URI] Access the URI of the list element :returns: URI of the data :rtype: `URI` .. rubric:: Examples >>> uri = list_element.uri >>> print(uri) Output: ```` .. py:method:: __repr__() -> str .. py:class:: StatusElement(control_element: pyfdb._internal.ControlElement, *, _internal=False) .. py:attribute:: element :type: pyfdb._internal.ControlElement .. py:method:: __eq__(other: object, /) -> bool .. py:method:: __ne__(value: object, /) -> bool .. py:method:: location() -> pyfdb.pyfdb_type.URI .. py:method:: controlIdentifiers() -> list[pyfdb.pyfdb_type.ControlIdentifier] .. py:method:: key() -> pyfdb.pyfdb_type.MarsSelection .. py:method:: __repr__() -> str .. py:class:: WipeElement(wipe_element: str, *, _internal=False) .. py:attribute:: _element :type: pyfdb._internal.WipeElement .. py:method:: type() -> WipeElementType .. py:method:: msg() -> str .. py:method:: uris() -> list[pyfdb.pyfdb_type.URI] .. py:method:: __repr__() -> str .. py:class:: PurgeElement(purge_element: str, *, _internal=False) .. py:attribute:: element :type: pyfdb._internal.PurgeElement .. py:method:: __repr__() -> str .. py:class:: StatsElement(stats_element: pyfdb._internal.StatsElement, *, _internal=False) .. py:attribute:: element :type: pyfdb._internal.StatsElement .. py:method:: db_statistics() -> str .. py:method:: index_statistics() -> str .. py:method:: __repr__() -> str .. py:class:: ControlElement(control_element: pyfdb._internal.ControlElement, *, _internal=False) .. py:attribute:: element :type: pyfdb._internal.ControlElement .. py:method:: __eq__(other: object, /) -> bool .. py:method:: __ne__(value: object, /) -> bool .. py:method:: location() -> pyfdb.pyfdb_type.URI .. py:method:: controlIdentifiers() -> list[pyfdb.pyfdb_type.ControlIdentifier] .. py:method:: key() -> pyfdb.pyfdb_type.MarsSelection .. py:method:: __repr__() -> str .. py:class:: IndexAxis(index_axis: pyfdb._internal.IndexAxis | pyfdb.pyfdb_type.MarsSelection) Bases: :py:obj:`pyfdb._internal.pyfdb_internal.InternalMarsSelection` `IndexAxis` class representing axes and their extent. The class implements all Dictionary functionalities. Key are the corresponding FDB keys (axes) and values are the values defining the extent of an axis. .. py:method:: __repr__() -> str .. py:method:: __getitem__(key: str) -> collections.abc.Collection[str] .. py:method:: __setitem__(key, value) .. py:method:: __delitem__(key) .. py:method:: clear() .. py:method:: __len__() -> int .. py:method:: __iter__() -> collections.abc.Iterator[str] .. py:method:: __eq__(value) -> bool .. py:method:: __ne__(value: object, /) -> bool .. py:method:: has_key(k) -> bool .. py:method:: keys() -> collections.abc.KeysView[str] .. py:method:: values() -> collections.abc.ValuesView[collections.abc.Collection[str]] .. py:method:: items() -> collections.abc.ItemsView[str, collections.abc.Collection[str]] .. py:method:: __contains__(item: object)