%run ../../code/version_check.py

"""
Explanation: Table of Contents
<p><div class="lev1 toc-item"><a href="#Summary" data-toc-modified-id="Summary-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Summary</a></div><div class="lev1 toc-item"><a href="#Version-Control" data-toc-modified-id="Version-Control-2"><span class="toc-item-num">2&nbsp;&nbsp;</span>Version Control</a></div><div class="lev1 toc-item"><a href="#Change-Log" data-toc-modified-id="Change-Log-3"><span class="toc-item-num">3&nbsp;&nbsp;</span>Change Log</a></div><div class="lev1 toc-item"><a href="#Setup" data-toc-modified-id="Setup-4"><span class="toc-item-num">4&nbsp;&nbsp;</span>Setup</a></div><div class="lev1 toc-item"><a href="#Secure-Credentials-File" data-toc-modified-id="Secure-Credentials-File-5"><span class="toc-item-num">5&nbsp;&nbsp;</span>Secure Credentials File</a></div><div class="lev1 toc-item"><a href="#Inspect-the-XML-returned" data-toc-modified-id="Inspect-the-XML-returned-6"><span class="toc-item-num">6&nbsp;&nbsp;</span>Inspect the XML returned</a></div><div class="lev3 toc-item"><a href="#Data-inspection-(root)" data-toc-modified-id="Data-inspection-(root)-601"><span class="toc-item-num">6.0.1&nbsp;&nbsp;</span>Data inspection (root)</a></div><div class="lev3 toc-item"><a href="#Get-data--(token)" data-toc-modified-id="Get-data--(token)-602"><span class="toc-item-num">6.0.2&nbsp;&nbsp;</span>Get data  (token)</a></div><div class="lev1 toc-item"><a href="#Client" data-toc-modified-id="Client-7"><span class="toc-item-num">7&nbsp;&nbsp;</span>Client</a></div>

# Summary

 * Master post for the blog series that holds all the links related to making web service calls to Eoddata.com. Overview of the web service can be found [here](http://ws.eoddata.com/data.asmx)
 * Download the [class definition file](https://adriantorrie.github.io/downloads/code/eoddata.py) for an easy to use client, which is demonstrated below
 * This post shows you how to create a secure credentials file to hold the username and password so you don't have to keep entering it, and will allow for automation later.
 * A quick overview is given below of establishing a session using the `requests` module, and parsing the xml response using `xml.etree.cElementTree`. Then a quick inspection of the objects created follows.

The following links were used to help get these things working.

* http://stackoverflow.com/a/17378332/893766
* http://stackoverflow.com/a/1912483/893766
* hidden password entry: https://docs.python.org/2/library/getpass.html

# Version Control
End of explanation
"""


%run ../../code/eoddata.py

from getpass import getpass
import json
import os
import os.path
import requests as r
import stat
import xml.etree.cElementTree as etree

ws = 'http://ws.eoddata.com/data.asmx'
ns='http://ws.eoddata.com/Data'
session = r.Session()

username = getpass()

password = getpass()

"""
Explanation: Change Log
Date Created: 2017-03-25

Date of Change    Change Notes
--------------    ----------------------------------------------------------------
2017-03-25        Initial draft
2017-04-02        Added "file saved: &lt;location&gt;" output

[Top]
Setup
End of explanation
"""


# gather credentials
credentials = {'username': username, 'password': password}

# set filename variables
credentials_dir = os.path.join(os.path.expanduser("~"), '.eoddata')
credentials_file_name = 'credentials'
credentials_path = os.path.join(credentials_dir, credentials_file_name)

# set security variables
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL  # Refer to "man 2 open".
mode = stat.S_IRUSR | stat.S_IWUSR  # This is 0o600 in octal and 384 in decimal.

# create directory for file if not exists
if not os.path.exists(credentials_dir):
    os.makedirs(credentials_dir)

# for security, remove file with potentially elevated mode
try:
    os.remove(credentials_path)
except OSError:
    pass

# open file descriptor
umask_original = os.umask(0)
try:
    fdesc = os.open(credentials_path, flags, mode)
finally:
    os.umask(umask_original)

# save credentials in secure file
with os.fdopen(fdesc, 'w') as f:
    json.dump(credentials, f)
    f.write("\n")
    
print("file saved: {}".format(credentials_path))

"""
Explanation: [Top]
Secure Credentials File
Create credentials file for later usage. The file will have permissions created so only the current user can access the file. The following SO post was followed.
The following directory will be created if it doesn't exist:
 * Windows: %USERPROFILE%/.eoddata
 * Linux:   ~/.eoddata
End of explanation
"""


call = 'Login'
url = '/'.join((ws, call))

payload = {'Username': username, 'Password': password}

response = session.get(url, params=payload, stream=True)

if response.status_code == 200:
    root = etree.parse(response.raw).getroot()

"""
Explanation: [Top]
Inspect the XML returned
End of explanation
"""


dir(root)

for child in root.getchildren():
    print (child.tag, child.attribute)

for item in root.items():
    print (item)

for key in root.keys():
    print (key)

print (root.get('Message'))
print (root.get('Token'))
print (root.get('DataFormat'))
print (root.get('Header'))
print (root.get('Suffix'))

"""
Explanation: Data inspection (root)
End of explanation
"""


token = root.get('Token')

"""
Explanation: Get data  (token)
End of explanation
"""


# client can be opened using a with statement
with (Client()) as eoddata:
    print('token: {}'.format(eoddata.get_token()))

# initialise using secure credentials file
eoddata = Client()

# client field accessors
ws = eoddata.get_web_service()
ns = eoddata.get_namespace()
token = eoddata.get_token()
session = eoddata.get_session()

print('ws: {}'.format(ws))
print('ns: {}'.format(ns))
print('token: {}'.format(token))
print(session)

# the client has a list of exchange codes avaiable once intialised
eoddata.get_exchange_codes()

# client must be closed if opened outside a with block
session.close()
eoddata.close_session()

"""
Explanation: [Top]
Client
End of explanation
"""


