# Exporting openHistorian data to Python

**URL:** <http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851>\
**Category:** openHistorian\
**Created:** [March 12, 2021, 3:14am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851 "2021-03-12T03:14:36Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Datta](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/d/50afbb/32.png) [@Datta](http://discussions.gridprotectionalliance.org/u/Datta)\
**Post date:** [March 12, 2021, 3:14am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/1 "2021-03-12T03:14:36Z")

</div>

Is there any way to extract open Historian data into Python for better analytics using openHistorian.db instance?

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [March 12, 2021, 3:42am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/2 "2021-03-12T03:42:53Z")

</div>

> **[openhistorian](https://pypi.org/project/openhistorian/)**
>
> openHistorian Python API

---

<div class="post-metadata">

**Author:** ![Datta](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/d/50afbb/32.png) [@Datta](http://discussions.gridprotectionalliance.org/u/Datta)\
**Post date:** [March 12, 2021, 6:02am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/3 "2021-03-12T06:02:04Z")

</div>

Thanks Ritchie for providing the openHistorian Python API. Just a quick question do we need to configure snapDB separately as when I am running the code to connect to my localhost server where openHistorian is hosted I am getting this error : -

_ **Connecting to openHistorian…** _  
_ **Failed to connect: Unexpected server response: 72** _

which is actually an exception thrown after this execution:

def readTest():

```
# Create historian connection (the root API object)

historian = historianConnection("localhost:8182")

instance: Optional[historianInstance] = None

try:

    print("Connecting to openHistorian...")

    historian.Connect()
```

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [March 12, 2021, 6:08am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/4 "2021-03-12T06:08:13Z")

</div>

Try leaving the port number out:

```auto
historian = historianConnection("localhost")

```

The openHistorian API, by default, listens on `38402` not `8182`.

Thanks,  
Ritchie

---

<div class="post-metadata">

**Author:** ![Datta](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/d/50afbb/32.png) [@Datta](http://discussions.gridprotectionalliance.org/u/Datta)\
**Post date:** [March 12, 2021, 6:55am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/5 "2021-03-12T06:55:48Z")

</div>

Hi Rithcie,  
Thanks for your response. I implemented this too by opening the port 38402 on my system too but then too I am receiving this message:

_ **Connecting to openHistorian…** _  
_**Failed to connect: [WinError 10061] No connection could be made because the target machine actively refused it**_

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [March 12, 2021, 6:58am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/6 "2021-03-12T06:58:10Z")

</div>

Check the following:  
(1) openHistorian service is running  
(2) Windows firewall is turned off (or allow openHistorian.exe or ports as an exception)

---

<div class="post-metadata">

**Author:** ![a\_r](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/a/f475e1/32.png) [@a\_r](http://discussions.gridprotectionalliance.org/u/a_r)\
**Post date:** [April 21, 2021, 11:34pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/7 "2021-04-21T23:34:18Z")

</div>

Does the openHistorian Python API allow us to read statistics (STAT) values such as average latency?

I’ve tried running “readTest.py” and was able to get PPA type values, but was unable to read STAT values. Here is the code I modified for this:

records = metadata.GetMeasurementsBySignalType(SignalType.STAT, instance.Name)

I currently have 2 Historian instances (PPA, STAT) under “Manage Historian Instances”, both of which are local.

 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/1X/2842d147a4e150848184db173d0456f5d3519ed7.png)

I noticed that in the “readTest.py” code when I try to change the index for initialInstance = historian.InstanceNames[0] to anything greater than 0, I receive the exception “Failed to connect: list index out of range”.

---

<div class="post-metadata">

**Author:** ![Datta](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/d/50afbb/32.png) [@Datta](http://discussions.gridprotectionalliance.org/u/Datta)\
**Post date:** [April 21, 2021, 11:48pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/8 "2021-04-21T23:48:44Z")

</div>

As far as I know we can only extract the PPA historian instance. Secondly STAT is not a signal type and hence it would not return any value.

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [April 21, 2021, 11:55pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/9 "2021-04-21T23:55:07Z")

</div>

No, statistics are archived in a separate local repository (e.g., `C:\Program Files\openHistorian\Statistics`) - however, there is a REST-based web-service for getting these values which should be easy to query from python (see below). FYI - examples are small subset of functions available, see [IMetadataService.cs](https://github.com/GridProtectionAlliance/gsf/blob/master/Source/Libraries/GSF.Historian/DataServices/IMetadataService.cs) and [ITimeSeriesDataService.cs](https://github.com/GridProtectionAlliance/gsf/blob/master/Source/Libraries/GSF.Historian/DataServices/ITimeSeriesDataService.cs) for full REST method listing.

For **metadata** use: [http://localhost:6055/](http://localhost:6055/) - examples:

- Read all metadata in XML format:  
`http://localhost:6055/historian/metadata/read/xml`

- Read all metadata in JSON format:  
` http://localhost:6055/historian/metadata/read/json`

- Read metadata points from 10 to 100 in XML format:  
`http://localhost:6055/historian/metadata/read/10-100/xml`

- Read metadata points from 10 to 100 in JSON format:  
`http://localhost:6055/historian/metadata/read/10-100/json`

- Read metadata points 10, 11 and 20 in XML format:  
`http://localhost:6055/historian/metadata/read/10;11;20/xml`

- Read metadata points 10, 11 and 20 in JSON format:  
`http://localhost:6055/historian/metadata/read/10;11;20/json`

For **data** use: [http://localhost:6056/](http://localhost:6056/) - examples:

- Read current value for data points from 10 to 100 in XML format:  
`http://localhost:6056/historian/timeseriesdata/read/current/10-100/xml`

- Read current value for data points from 10 to 100 in JSON format:  
`http://localhost:6056/historian/timeseriesdata/read/current/10-100/json`

- Read current value for data points 10, 11, and 20 in XML format:  
`http://localhost:6056/historian/timeseriesdata/read/current/10;11;20/xml`

- Read current value for data points 10, 11, and 20 in JSON format:  
`http://localhost:6056/historian/timeseriesdata/read/current/10;11;20/json`

- Read archived values for data points from 10 to 100 and specified start/end times in XML format:  
`http://localhost:6056/historian/timeseriesdata/read/historic/10-100/2021-04-21%2023:50:00/2021-04-21%2023:51:00/xml`

- Read archived values for data points from 10 to 100 and specified start/end times in JSON format:  
`http://localhost:6056/historian/timeseriesdata/read/historic/10-100/2021-04-21%2023:50:00/2021-04-21%2023:51:00/json`

- Read archived values for data points 10, 11, and 20 for specified start/end times in XML format:  
`http://localhost:6056/historian/timeseriesdata/read/historic/10;11;20/2021-04-21%2023:50:00/2021-04-21%2023:51:00/xml`

- Read archived values for data points 10, 11, and 20 for specified start/end times in JSON format:  
`http://localhost:6056/historian/timeseriesdata/read/historic/10;11;20/2021-04-21%2023:50:00/2021-04-21%2023:51:00/json`

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [April 22, 2021, 12:24am UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/10 "2021-04-22T00:24:54Z")

</div>

FYI - some history:

The `STAT` archive is an instance of the older openHistorian 1.0 that was deployed with the original openPDC (see [GSF.Historian](https://github.com/GridProtectionAlliance/gsf/tree/master/Source/Libraries/GSF.Historian) and [LocalOutputAdapter](https://github.com/GridProtectionAlliance/gsf/blob/master/Source/Libraries/Adapters/HistorianAdapters/LocalOutputAdapter.cs)) - fast writes, not as fast reads.

The `PPA` archive is an instance of the newer openHistorian 2.0 based on [SNAPdb](https://github.com/GridProtectionAlliance/openHistorian/blob/master/Source/Libraries/GSF.SortedTreeStore/Snap/README.md) (see [GSF.SortedTreeStore](https://github.com/GridProtectionAlliance/openHistorian/tree/master/Source/Libraries/GSF.SortedTreeStore), [openHistorian.Core](https://github.com/GridProtectionAlliance/openHistorian/tree/master/Source/Libraries/openHistorian.Core) and [LocalOutputAdapter](https://github.com/GridProtectionAlliance/openHistorian/blob/master/Source/Libraries/Adapters/openHistorian.Adapters/LocalOutputAdapter.cs)) - fast writes and fast reads.

Here was a good presentation explaining some of technical differences:

> **[(07)%20openHistorian%202.0%20and%20Use.pdf](https://gridprotectionalliance.org/UserForum/2015/Day%201/(07)%20openHistorian%202.0%20and%20Use.pdf)**
>
> 1506.07 KB

---

<div class="post-metadata">

**Author:** ![a\_r](http://discussions.gridprotectionalliance.org/letter_avatar_proxy/v4/letter/a/f475e1/32.png) [@a\_r](http://discussions.gridprotectionalliance.org/u/a_r)\
**Post date:** [April 22, 2021, 8:29pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/11 "2021-04-22T20:29:29Z")

</div>

Thank you Ritchie, the information was very much helpful. I am able to get the data that I was looking for now.

---

<div class="post-metadata">

**Author:** ![ricardlira](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ricardlira/32/1314_2.png) [@ricardlira](http://discussions.gridprotectionalliance.org/u/ricardlira)\
**Post date:** [June 28, 2024, 6:40pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/12 "2024-06-28T18:40:48Z")

</div>

Hello! In order to avoid opening another trend of this topic, I will write in here:

Can you tell me what is the compatible versions of openHistorian releases that works with python code available here: [openhistorian · PyPI](https://pypi.org/project/openhistorian/) (openhistorian 1.0.5)

We were able to successfully download data based on **OH v2.8.395** , but on the stable release ( **v2.8.383** ) I received the message

 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/d/d3ef54920ff911a80cb13f9137ae1cf94772fa35.png)

Is there any special configuration were made in OH side? Both OHs are in the same LAN with no firewall restrictions.

Thanks!

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [June 28, 2024, 6:51pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/13 "2024-06-28T18:51:28Z")

</div>

No specific version requirements for Python API, looks like you are seeing a connection issue. Could be related to firewall, non-standard port configuration or incorrect IP/hostname for OH instance. Also make sure OH service is running

Thanks!  
Ritchie

---

<div class="post-metadata">

**Author:** ![ricardlira](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ricardlira/32/1314_2.png) [@ricardlira](http://discussions.gridprotectionalliance.org/u/ricardlira)\
**Post date:** [July 1, 2024, 1:22pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/14 "2024-07-01T13:22:45Z")

</div>

Understood, thanks for the guidance. But still I don’t see this failure point yet… While I’ve verified the IP addresses are correct, there seems to be an issue with the connection itself. Here’s what I’ve investigated so far:

- Configuration: I’ve double-checked the configurations of both HIS1 and HIS2, and they appear identical. However, it’s possible there might be a subtle difference causing the issue.  
Logs: I haven’t found any relevant error messages related to the connection failure in the HIS logs.
- Python Code: The error originates from the `sttpSocket` line in the Python code.  
 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/b/b54678de0bbb17c517522b4f0138c16869bab458.png)

To assist in debugging further:

- Port Verification: How can we confirm if port 7175 is indeed the standard port used for HIS communication?
- Configuration Comparison: how to perform a more meticulous side-by-side comparison of the HIS1 and HIS2 configurations to identify any potential discrepancies, even minor ones?

The connection attempt occurs within the same sub-network, so firewall rules are unlikely to be the issue, but I will double check this again.

Thanks!

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [July 1, 2024, 1:48pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/15 "2024-07-01T13:48:36Z")

</div>

You can verify that the openHistorian STTP port is on 7175 by running the “XML Configuration Editor” (from the openHIstorian application group on the Windows start menu). Expand the `sttpdatapublisher` section and check the `ConfigurationString` setting:

 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/b/bee46db09961bc18aa9f9355b64b5fb4a3d8c36e.png)

You can also try re-initializing the STTP Publisher adapter. Open the manager application for the openHistorian and navigate to “Actons \> Manage Custom Actions”. Next, select the `STTP!DATAPUBLISHER` adapter and click the “Initiaize” button.

Optionally, you can try restarting the openHistorian service - or - as a last resort, trying restarting the host machine.

There is always the possibility that another application has the port locked. Check the Task Manager to verify there is only one openHistorian executable instance running (technically, only one is allowed, but it is possible a rogue instance is still running).

To verify which application has port 7175 in use, run this command from a command prompt that has administrator permissions:

```plaintext
netstat -abnp tcp

```

---

<div class="post-metadata">

**Author:** ![ricardlira](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ricardlira/32/1314_2.png) [@ricardlira](http://discussions.gridprotectionalliance.org/u/ricardlira)\
**Post date:** [July 1, 2024, 5:31pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/16 "2024-07-01T17:31:06Z")

</div>

Indeed the port was different in HIS1 installation (stable build), using port 7177. HIS2 is the nightly build, using port 7175. While this worked at the the attempt (yey!) it started generated another error claiming that “an existing connection was forcibly closed”.

 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/3/35e42b1671ad47d683a9f020c68ce7390c3d399c.png)

HIS1 netstat result:  
 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/7/750eacb8b00bd39ddcc4d3ee6eddf20e2ede8b40.png)

HIS1 is in production and reseting it should be avoided.

Any next tip to progress towards the resolution?

---

<div class="post-metadata">

**Author:** ![ritchiecarroll](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ritchiecarroll/32/2_2.png) [@ritchiecarroll](http://discussions.gridprotectionalliance.org/u/ritchiecarroll)\
**Post date:** [July 1, 2024, 8:57pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/17 "2024-07-01T20:57:33Z")

</div>

This is commonly associated with a TLS connection issue. Port 7177, by default, is associated with the TLS instance of STTP, or “STTPS” found in the `sttpsdatapublisher` section in the config file, not the `sttpdatapublisher`. This is a subtle, but important, difference. Can you verify the port number for the standard, non-TLS configuration section that should be labeled without the “s” suffix on STTP, i.e., `sttpdatapublisher`:

 ![image](http://discussions.gridprotectionalliance.org/uploads/default/original/2X/8/8bd355d23afc357122f68ac4cbf2d0bca53bf602.png)

Additionally, corresponding to the `sttpdatapublisher`, there should be a custom action called `STTP!DATAPUBLISHER` - can you let me know its configuration string from the manager application? Can you verify the record is enabled?

Thanks!  
Ritchie

---

<div class="post-metadata">

**Author:** ![ricardlira](http://discussions.gridprotectionalliance.org/user_avatar/discussions.gridprotectionalliance.org/ricardlira/32/1314_2.png) [@ricardlira](http://discussions.gridprotectionalliance.org/u/ricardlira)\
**Post date:** [July 2, 2024, 5:18pm UTC](http://discussions.gridprotectionalliance.org/t/exporting-openhistorian-data-to-python/851/18 "2024-07-02T17:18:51Z")

</div>

Good news! Now it is sorted. Indeed I made a mistake looking at the wrong field but also HIS1 has a different port than HIS2. Now both are working. Thank you for the support here!
