Skip to end of metadata
Go to start of metadata

Note: The high-level Python interface is currently experimental and may change in a future release. It is provided here to solicit feedback.

New Python Classes

In addition to the low-level C-like interface, there are now Python classes that can be used to work with GRIB and BUFR messages in a more object-oriented manner.

GribFile and BufrFile: Classes that implement access to a GRIB/BUFR file.  A GribFile/BufrFile closes itself and its messages when it is no longer needed (when used with the context manager)

GribMessage and BufrMessage: Classes that implement access to a GRIB/BUFR message. A GribMessage/BufrMessage allows access to the message's key-value pairs in a dictionary-like manner and closes the message when it is no longer needed, coordinating this with its host file.

GribFiles and BufrFiles can be treated mostly as regular files and used as context managers, as can GribMessages/BufrMessages. Each of these classes destructs itself and any child instances appropriately.

Exception Class Hierarchy

We have also added a set of exception classes which allow the user to see what kind of exception was raised.  Client code that currently handles exceptions does not need to be changed because the new exceptions are subclassed from the current CodesInternalError.

Details

# A GRIB file handle meant for use in a context manager.

# One can easily iterate over each message in the file::

# Usage::
>>> with GribFile(filename) as grib:
...     # Print number of messages in file
...     len(grib)
...     # Open all messages in file
...     for msg in grib:
...         print(msg[key_name])
>>> # When the file is closed, any open messages are closed
# A GRIB message.

# Each ``GribMessage`` is stored as a key/value pair in a dictionary-like
# structure. It can be used in a context manager or by itself. When the
# ``GribFile`` it belongs to is closed, the ``GribFile`` closes any open
# ``GribMessage``s that belong to it. If a ``GribMessage`` is closed before
# its ``GribFile`` is closed, it informs the ``GribFile`` of its closure.

# Scalar and vector values are set appropriately through the same method.

# ``GribMessage``s can be instantiated from a ``GribFile``, cloned from
# other ``GribMessage``s or taken from samples. Iterating over the members
# of a ``GribFile`` extracts the ``GribMessage``s it contains until the
# ``GribFile`` is exhausted.

# Usage::
>>> with GribFile(filename) as grib:
...     # Iterate through each message in the file
...     for msg in grib:
...         # Access a key from each message
...         print(msg[key_name])
...         # Report message size in bytes
...         msg.size()
...         # Report keys in message
...         msg.keys()
...         # Set scalar value
...         msg[scalar_key] = 5
...         # Array values are set transparently
...         msg[array_key] = [1, 2, 3]
...         # Messages can be written to file
...         with open(testfile, "w") as test:
...             msg.write(test)
...         # Messages can be cloned from other messages
...         msg2 = GribMessage(clone=msg)
# A BUFR file handle meant for use in a context manager.

# One can easily iterate over each message in the file::

# Usage::
>>> with BufrFile(filename) as bufr:
...     # Print number of messages in file
...     len(bufr)
...     # Open all messages in file
...     for msg in bufr:
...         print(msg[key_name])
>>> # When the file is closed, any open messages are closed
# A BUFR message.

# Each ``BufrMessage`` is stored as a key/value pair in a dictionary-like
# structure. It can be used in a context manager or by itself. When the
# ``BufrFile`` it belongs to is closed, the ``BufrFile`` closes any open
# ``BufrMessage``s that belong to it. If a ``BufrMessage`` is closed before
# its ``BufrFile`` is closed, it informs the ``BufrFile`` of its closure.

# Scalar and vector values are set appropriately through the same method.

# ``BufrMessage``s can be instantiated from a ``BufrFile``, cloned from
# other ``BufrMessage``s or taken from samples. Iterating over the members
# of a ``BufrFile`` extracts the ``BufrMessage``s it contains until the
# ``BufrFile`` is exhausted.

# Usage::
>>> with BufrFile(filename) as bufr:
...     # Iterate through each message in the file
...     for msg in bufr:
...         # Access a key from each message
...         print(msg[key_name])
...         # Report message size in bytes
...         msg.size()
...         # Report keys in message
...         msg.keys()
...         # Set scalar value
...         msg[scalar_key] = 5
...         # Array values are set transparently
...         msg[array_key] = [1, 2, 3]
...         # Messages can be written to file
...         with open(testfile, "w") as test:
...             msg.write(test)
...         # Messages can be cloned from other messages
...         msg2 = BufrMessage(clone=msg)
# The class CodesInternalError is the base class for all the new exceptions

class WrongBitmapSizeError(CodesInternalError):
    """Size of bitmap is incorrect."""
class OutOfRangeError(CodesInternalError):
    """Value out of coding range."""
class UnsupportedEditionError(CodesInternalError):
    """Edition not supported.."""
class AttributeNotFoundError(CodesInternalError):
    """Attribute not found.."""
class TooManyAttributesError(CodesInternalError):
    """Too many attributes. Increase MAX_ACCESSOR_ATTRIBUTES."""
class AttributeClashError(CodesInternalError):
    """Attribute is already present, cannot add."""
class NullPointerError(CodesInternalError):
    """Null pointer."""
class MissingBufrEntryError(CodesInternalError):
    """Missing BUFR table entry for descriptor."""
class WrongConversionError(CodesInternalError):
    """Wrong type conversion."""
class StringTooSmallError(CodesInternalError):
    """String is smaller than requested."""
class InvalidKeyValueError(CodesInternalError):
    """Invalid key value."""
class ValueDifferentError(CodesInternalError):
    """Value is different."""
class DifferentEditionError(CodesInternalError):
    """Edition of two messages is different."""
class InvalidBitsPerValueError(CodesInternalError):
    """Invalid number of bits per value."""
class CorruptedIndexError(CodesInternalError):
    """Index is corrupted."""
class MessageMalformedError(CodesInternalError):
    """Message malformed."""
class UnderflowError(CodesInternalError):
    """Underflow."""
class SwitchNoMatchError(CodesInternalError):
    """Switch unable to find a matching case."""
class ConstantFieldError(CodesInternalError):
    """Constant field."""
class MessageTooLargeError(CodesInternalError):
    """Message is too large for the current architecture."""
class InternalArrayTooSmallError(CodesInternalError):
    """An internal array is too small."""
class PrematureEndOfFileError(CodesInternalError):
    """End of resource reached when reading message."""
class NullIndexError(CodesInternalError):
    """Null index."""
class EndOfIndexError(CodesInternalError):
    """End of index reached."""
class WrongGridError(CodesInternalError):
    """Grid description is wrong or inconsistent."""
class NoValuesError(CodesInternalError):
    """Unable to code a field without values."""
class EndError(CodesInternalError):
    """End of resource."""
class WrongTypeError(CodesInternalError):
    """Wrong type while packing."""
class NoDefinitionsError(CodesInternalError):
    """Definitions files not found."""
class HashArrayNoMatchError(CodesInternalError):
    """Hash array no match."""
class ConceptNoMatchError(CodesInternalError):
    """Concept no match."""
class OutOfAreaError(CodesInternalError):
    """The point is out of the grid area."""
class MissingKeyError(CodesInternalError):
    """Missing a key from the fieldset."""
class InvalidOrderByError(CodesInternalError):
    """Invalid order by."""
class InvalidNearestError(CodesInternalError):
    """Invalid nearest id."""
class InvalidKeysIteratorError(CodesInternalError):
    """Invalid keys iterator id."""
class InvalidIteratorError(CodesInternalError):
    """Invalid iterator id."""
class InvalidIndexError(CodesInternalError):
    """Invalid index id."""
class InvalidGribError(CodesInternalError):
    """Invalid grib id."""
class InvalidFileError(CodesInternalError):
    """Invalid file id."""
class WrongStepUnitError(CodesInternalError):
    """Wrong units for step (step must be integer)."""
class WrongStepError(CodesInternalError):
    """Unable to set step."""
class InvalidTypeError(CodesInternalError):
    """Invalid key type."""
class WrongLengthError(CodesInternalError):
    """Wrong message length."""
class ValueCannotBeMissingError(CodesInternalError):
    """Value cannot be missing."""
class InvalidSectionNumberError(CodesInternalError):
    """Invalid section number."""
class NullHandleError(CodesInternalError):
    """Null handle."""
class InvalidArgumentError(CodesInternalError):
    """Invalid argument."""
class ReadOnlyError(CodesInternalError):
    """Value is read only."""
class MemoryAllocationError(CodesInternalError):
    """Memory allocation error."""
class GeocalculusError(CodesInternalError):
    """Problem with calculation of geographic attributes."""
class NoMoreInSetError(CodesInternalError):
    """Code cannot unpack because of string too small."""
class EncodingError(CodesInternalError):
    """Encoding invalid."""
class DecodingError(CodesInternalError):
    """Decoding invalid."""
class MessageInvalidError(CodesInternalError):
    """Message invalid."""
class IOProblemError(CodesInternalError):
    """Input output problem."""
class KeyValueNotFoundError(CodesInternalError):
    """Key/value not found."""
class WrongArraySizeError(CodesInternalError):
    """Array size mismatch."""
class CodeNotFoundInTableError(CodesInternalError):
    """Code not found in code table."""
class FileNotFoundError(CodesInternalError):
    """File not found."""
class ArrayTooSmallError(CodesInternalError):
    """Passed array is too small."""
class MessageEndNotFoundError(CodesInternalError):
    """Missing 7777 at end of message."""
class FunctionNotImplementedError(CodesInternalError):
    """Function not yet implemented."""
class BufferTooSmallError(CodesInternalError):
    """Passed buffer is too small."""
class InternalError(CodesInternalError):
    """Internal error."""
class EndOfFileError(CodesInternalError):
    """End of resource reached."""

 

This feature is a contribution from DWD for which we are very thankful.

 

  • No labels