Metadata-Version: 2.4
Name: haver
Version: 3.5.1
Summary: Access data and metadata from Haver Analytics databases
Author-email: Haver Analytics <tech@haver.com>
Maintainer-email: Haver Analytics <tech@haver.com>
License: Proprietary License
Project-URL: Homepage, https://www.haver.com/
Keywords: Haver,DLX
Classifier: Development Status :: 5 - Production/Stable
Classifier: Natural Language :: English
Classifier: Operating System :: Microsoft :: Windows
Classifier: Topic :: Office/Business :: Financial
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
Requires-Dist: numpy>=1.21.5
Requires-Dist: pandas>=1.4.1

Support and Documentation
-------------------------

This is the official Haver package for Python by Haver Analytics.
The package offers access to data and metadata stored in Haver
Analytics databases.

The below documentation is also available as a PDF document in the
client area of `haver.com <https://www.haver.com/>`_.
Unlike the PyPI page, the PDF document contains the output of the example Python
statements and hence may be more instructive to read.
A comprehensive, in-depth guide to the Haver package, the Haver Python
PDF reference, can also be found in the client area of haver.com.

+-------------------------------------------------------------------------------+
| **Note**                                                                      |
+===============================================================================+
| On PyPI, a different (third-party) project was hosted under the name 'haver'  |
| until February 12, 2026. It is now available under the new name               |
| `haver-api <https://pypi.org/project/haver-api/>`_.                           |
| 'haver-api' is not an official product of Haver Analytics.                    |
| It contains a package named 'haver', which clashes with                       |
| the package of the official 'haver' project. Therefore, it is not possible    |
| to install both projects at the same time.                                    |
+-------------------------------------------------------------------------------+

+--------------------------------------------------------------------+
| **Note**                                                           |
+====================================================================+
| The Haver package is only available for Windows operating systems. |
+--------------------------------------------------------------------+

For technical assistance, please contact `tech@haver.com <mailto:tech@haver.com>`_.
For other inquiries, please use the contact information listed
`here <https://www.haver.com/contact-us/>`_.

Query Setup
-----------

The statements below assume that you have executed ::

    import Haver

+-------------------------------------------------------------------+
| **Note**                                                          |
+===================================================================+
| The project name and the package name differ in casing. While the |
| project name is 'haver', your import statements must use a        |
| capital 'H'.                                                      |
+-------------------------------------------------------------------+
 
The basic operations of Haver data queries are easy and can be learned quickly.
In a nutshell, the functions that access Haver Analytics databases are called
``Haver.data()`` and ``Haver.metadata()`` . Both take as arguments
specifications for databases and time series codes to be retrieved. Data and
metadata are returned in `pandas DataFrames
<https://pypi.python.org/pypi/pandas>`_. Below, these DataFrames will be referred to as
Haver DataFrames and Haver Meta-DataFrames.

Before you can run queries, you must supply information on the location of
databases. If you are using DLX Direct to access Haver servers on the internet,
first set ::

  Haver.direct(True)

For DLX Direct, you must supply your credentials at regular intervals.
Moreover, DLX Direct mode is always switched off upon package import. That is, it is not
preserved in between Python sessions.

If your organization stores and updates databases locally, you can specify the
database location ::

  Haver.path(path_to_databases)

The statement ::

  Haver.path('auto')

tries to detect this setting without any input requirements from you.
Alternatively, if the location of your databases is stored
in an ini-file and you know the location of it, execute ::

  Haver.path(path_to_ini_file)

If you want to retain local database settings in between Python sessions, issue ::

  Haver.path(save=True)

The current setting is displayed by ::

  Haver.path()

Example Databases
-----------------

The Haver package comes with four example databases, of which we will use three
in the example queries below: 'HAVERD', 'HAVERW', and 'HAVERMQA'. They contain
daily, weekly, and monthly/quarterly/annual data, respectively. These databases
are subsequently referred to as the 'example databases', as opposed to the
'actual databases' that your institution subscribes to.

The path to the example databases is different than the path to the actual
databases. ``Haver.path()`` provides a convenient shortcut for setting
the path to example databases and for restoring the path to the actual
databases. This is done by the statements ::

  Haver.path('examples')
  Haver.path('restore')

You can abbreviate keywords given to ``Haver.path()``. Example:
``Haver.path('e')`` uses an abbreviation for the 'examples' keyword.

Since the example databases reside on your local network, any example code must
be executed with DLX Direct mode turned off ::

  Haver.direct(False)

Data Retrieval
--------------

The list of available example databases is ::

   Haver.path('examples')
   Haver.databases()

Data queries are very simple: You use the function ``Haver.data()``,
whose fundamental parameters are ::

   Haver.data(codes=..., database=..., ...)

where ``database`` is optional and specifies a default database. You supply the
series codes you are interested in as a Python list to the ``codes`` parameter. ::

   Haver.data(['havermqa:gdp', 'havermqa:ffed', 'havermqa:inet'])

The output is a pandas DataFrame. In the context of Haver queries, we call it
a Haver DataFrame.

The above statement used the *db:ser* series format, which specifies a full
series code as the database name, a colon, and the simple series code. Haver
functions in addition understand the *ser@db* format, which you may know from
the DLX add-in for Excel, where the simple series code comes first and the
'\@'-sign is used as the separator. Any mixture of formats is fine for input
lists. This guide uses mostly the *ser@db* format for input lists.

For all string inputs to Haver function parameters, including code lists, casing
does not matter.

The second parameter of ``Haver.data()`` specifies the default database. The
above statement did not need a default database since all elements of the
``codes`` list explicitly named a database. The following statement is
equivalent to the one above and uses a default database, which gets substituted
whenever a series code does not contain a database name::

   Haver.data(['gdp@havermqa', 'havermqa:ffed', 'inet'], 'havermqa')

Looking at the output, note that the frequency is annual. This was induced by
the 'inet' series, which is annual. If your query contains series with different
frequencies, the lowest one is chosen and higher-frequency series (here: 'gdp'
and 'ffed') are aggregated to it. You can override this using the ``frequency``
parameter. When series cannot be aggregated, they get dropped from the query ::

   Haver.data(['gdp@havermqa', 'havermqa:ffed', 'inet'], 'havermqa', frequency='quarterly')

Many parameters of Haver functions accept abbreviations. For example, in the
previous statement you could have used ``frequency='q'``.
Note that the ``codes`` parameter does not accept abbreviations. Code lists have
to be specified in an exact fashion.

You can specify start and ending dates as strings or ``datetime.date`` objects.
Strings must be supplied in the format YYYY-MM-DD. The dates are interpreted in
the resulting frequency of the query ::

   Haver.data(['gdp', 'ffed', 'inet'], 'havermqa', startdate='2000-01-01', enddate='2005-01-01')

retrieves annual data from 2000 to 2005. For the quarterly series 'gdp', for
example, all quarters of 2005 go into the calculation of the aggregated value
for 2005.

If you specify at least one code that does not exist, the query fails and a
Haver ErrorReportDictionary is returned. It contains information about the codes
that caused trouble and about the ones that did not. ::

   Haver.data(['gdp@havermqa', 'notindb@havermqa', 'inet@notaDB'])

Note that output lists, such as the ones of the Haver ErrorReportDictionary, are
by default in the *db:ser* format. You can override this using the
``codeformat`` parameter, which many Haver functions accept. ::

   Haver.data(['gdp@havermqa', 'notindb@havermqa', 'inet@notaDB'], codeformat='@')

In data queries, you can specify math functions and seasonal adjustment in the
same way as in Excel and VG3: You wrap a math function specification around a
series code. Parameter ``function`` is optional and pins down a default math
function::

   Haver.data(['diff%(gdp)', 'diff(ffed@havermqa)', 'c', 'g', 'i'], 'havermqa', function='difa%')

A query can access any number of databases::

   Haver.data(['gdp@havermqa', 'fxtwb@haverd', 'lic@haverw'], aggmode='relaxed')

The 'relaxed' argument to the optional parameter ``aggmode`` is oftentimes
useful when aggregating daily or weekly series (here: 'fxtwb' and 'ffed') to
lower frequencies. If the default 'strict' is used, a single missing observation
in the original data will cause a missing value in the aggregated span, which is
often unintended.

Metadata Queries
----------------

Each series in DLX databases has metadata attached, which you can query using
``Haver.metadata()``. Its syntax is ::

     Haver.metadata(codes=..., database=..., ...)

It shares the ``codes`` and ``database`` parameters with ``Haver.data()``.
They can be specified in an almost identical way. ::

   Haver.metadata(['gdp@havermqa', 'fxtwb@haverd', 'lic@haverw'])
   Haver.metadata(['gdp', 'c', 'g', 'i'], database='havermqa')

The output is again a pandas DataFrame. In the context of Haver queries, we call
it a Haver Meta-DataFrame. The individual fields (columns) of a Haver
Meta-DataFrame contain, among other things, start date, end date, and frequency. ::

   hmd = Haver.metadata(['gdp', 'c', 'g', 'i'], database='havermqa')
   hmd.columns

There is one difference to ``Haver.data()`` with respect to the ``database``
parameter: ``Haver.metadata()`` retrieves metadata for an entire database if the
``codes`` parameter is left unspecified. ::

   hmd_mqa = Haver.metadata(database='havermqa')
   hmd_mqa.iloc[:,0:5]

For ``Haver.data()``, this would result in a syntax error.

One usage of Haver Meta-DataFrames is to query metadata, filter according to
some criteria, and use the filtered frame as an input to ``Haver.data()``. For
example, the following statements query all codes from HAVERMQA whose labels
contain 'Treasury'. ::

   hmd_treas = hmd_mqa[hmd_mqa.descriptor.str.contains('Treasury')]
   hmd_treas.loc[:,['code', 'descriptor']]

Be careful with filtering on series descriptors, however, as they may contain
abbreviations. We can use the filtered Haver Meta-DataFrame as an input for a
data query::

   hd = Haver.data(hmd_treas, function='difa')
   hd

By default, metadata are in fact attached to all data queries via the haverinfo
member dictionary. ::

   hd = Haver.data(hmd_treas, function='difa')
   hd.haverinfo.keys()
   hd.haverinfo['vardescription']

The 'vardescription' entry holds the series descriptors, which is particularly
useful if you have applied math functions.

The entry 'metadata' contains the entire Haver Meta-DataFrame that corresponds
to the data query::

   hd.haverinfo['metadata'].iloc[:,0:5]

If you prefer, you can separate out the different pieces of information by using
the ``rtype`` parameter of ``Haver.data()``::

   [hd, hmd, info] = Haver.data(['c', 'g', 'i'], 'havermqa', rtype='3tuple')
   hd
   hmd
   info

After you are done experimenting with example databases, you can easily set your
database path back to the actual database::

  Haver.path('restore')

or, using abbreviations, ::

  Haver.path('r')

Alternatively, if you work with DLX Direct, you can switch DLX Direct mode back
on::

  Haver.direct(True)

Further Features and Documentation
----------------------------------

The comprehensive Haver Python PDF Reference available in the client area 
of haver.com provides more details on all of the above package features.
In also treats a number of features that have not been mentioned in this brief
introduction. These include:

* ``Haver.databases()`` prints or returns a list of available Haver Analytics databases.
* ``Haver.dbcodes()`` returns a list of codes contained in a Haver Analytics database.
* ``Haver.codelists()`` extracts lists of Haver series codes from various objects,
  such as Haver DataFrames or Haver ErrorReportDictionaries. This eases your
  overall workflow with Haver Analytics data.
* ``Haver.fmtcodes()`` formats lists of Haver series codes. For example, it
  converts *ser@db* and *db:ser* formats, or strips a code list from math functions.

Furthermore, for clients with a suitable subscription, database and time series
creation and management using the Haver Data Manager (HDM) from within Python is
documented.
