Skip to content
This repository has been archived by the owner on Jan 17, 2024. It is now read-only.

Commit

Permalink
Fixed param duplication in stock module, new version 2.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelPHartmann committed Feb 8, 2022
1 parent 23038d1 commit d8ef722
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 7 deletions.
2 changes: 1 addition & 1 deletion FinMesh.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: FinMesh
Version: 2.0
Version: 2.0.1
Summary: A Python wrapper to bring together various financial APIs.
Home-page: UNKNOWN
Author: Michael and Josh Hartmann
Expand Down
2 changes: 1 addition & 1 deletion FinMesh/iex/stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def balance_sheet(symbol, external=False, vprint=False, **queries):
url += '?'
for key, value in queries.items():
url += (f"&{key}={value}")
return get_iex_json_request(url, external=external, external=external, vprint=vprint)
return get_iex_json_request(url, external=external, vprint=vprint)


# Batch Requests
Expand Down
133 changes: 133 additions & 0 deletions build/lib/FinMesh/iex/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
import requests

# Simple string comprehension to allow setting of states through environment variables.
# REFACTORED!
def arg_to_bool(string):
affirmative = ['True','TRUE','true','Yes','YES','yes','On','ON','on']
if string in affirmative:
return True
else:
return False

# This may not be needed
# REFACTORED
def prepend_iex_url(section, external=False):
sandboxState = arg_to_bool(os.getenv('SANDBOX'))
if sandboxState is True:
Expand Down Expand Up @@ -45,3 +48,133 @@ def replace_url_var(url, **kwargs):
for key, value in kwargs.items():
url = url.replace('{' + key + '}', value)
return url

class iexCommon():
"""
A class that wraps all the common methods used in the IEX requests.
A class is not / was not strictly neccesary at the beginning of this project.
Adding support for external tokens meant that code was being repeatedly passed as arguments between functions.
A class means that these attributes can be shared easily, and it offers some streamlining solutions.
Certain functions can be done away with completely and others can be broken up more.
It also means that creating new functions for new endpoints is much easier and could be implemented by an end user.
:param endpoint: The endpoint you want to access. Specifically this must be the exact string used in the url that points to the desired endpoint.
:type endpoint: String, required
:param symbol: The symbol for the stock you would like to request data for.
:type symbol: String, required
:param external: Whether you want to use environment variables or not for the token and sandbox settings.
:type external: Boolean or String. Default is False, insert token here to bypass using environment variables.
"""

def __init__(self, endpoint, symbol, external=False):
self.url = f'iexapis.com/stable/{section}/{symbol}/{endpoint}?'
if external not False:
self.token = external
self.parse_token_sandbox(self.token)
else:
self.sandbox_state = self.get_env_sandbox()
self.token = self.get_env_token()
if sandbox_state is True:
self.url = 'https://sandbox.' + self.url
else:
self.url = 'https://cloud.' + self.url

# Simple string comprehension and conversion for use with environment variable settings
def arg_to_bool(self, string):
"""Turns a text string into a boolean response, not fancy.
:param string: The string you would like to convert to boolean.
:type string: String, required
"""
affirmative = ['True','TRUE','true','Yes','YES','yes','On','ON','on']
if string in affirmative:
return True
else:
return False

# Takes a token string and sets the sandbox state accordingly.
# All IEX tokens use a 'T' as the first char for sandbox tokens
def parse_token_sandbox(self, token):
"""Takes a token string and sets the sandbox state accordingly.
All IEX tokens use a 'T' as the first char of a token to indicate whether it is a sandbox token.
This method just looks for that T.
:param token: The token you would like to parse.
:type token: String, required
"""
if self.token[0] == 'T':
setattr(self, 'sandbox_state', True)
else:
setattr(self, 'sandbox_state', False)

# Gets the sandbox state from environment variable string and parses it into a boolean
def get_env_sandbox(self):
"""Returns a boolean from the environment variable 'SANDBOX'
When using system level tokens this will determine whether to call the dummy sandbox environment or the production API
"""
sandbox_state = self.arg_to_bool(os.getenv('SANDBOX'))
return sandbox_state

# Gets the IEX token from environment variables based on whether sandbox state is enabled.
def get_env_token(self):
"""Returns a token from the appropriate environment variable.
Variable name is either 'IEX_SANDBOX_TOKEN' or 'IEX_TOKEN'
Whether the sandbox or production token is retrieved is determined by the environment SANDBOX state.
"""
if sandboxState:
token = os.getenv('IEX_SANDBOX_TOKEN')
else:
token = os.getenv('IEX_TOKEN')
return token

# Adds query paramters to the url
def add_query_params_to_url(self, **query_params):
"""Appends query parameters onto the target URL.
Performs operations on the url attribute.
Returns the URL with query parameters attached to the end.
:param query_params: Catchall for keyword arguments. Will be appended to url like "&key=value".
:type query_params: Keyword arguments, required.
"""
for key, value in query_params.items():
self.url += (f"&{key}={value}")
return self.url

# Finalizes the url with the appropriate token - method does not determine which token to append
def append_token_to_url(self):
"""Appends the appropriate token to the end of the url.
If using environment variables this token is chosen depending on sandbox state.
If token has been supplied in initialization then that exact token is used.
Sets attribute url_final for class instance.
Returns the final URL.
"""
setattr(self, "url_final", f"{self.url}&token={self.token}")
return self.url_final

# Make and handle the request to IEX Cloud with verbose error message
def make_iex_request(self):
"""Performs request to IEX Cloud from the URL defined in url_final.
If request does not return a 200 response then a verbose error statement is raised.
Returns JSON object of response.
"""
response = requests.get(self.url_final)
if response.status_code != 200:
error_response = (F"There was an error with the request to IEX!\n"
+ F"{response.status_code}:{response.reason} in {round(response.elapsed.microseconds/1000000,4)} seconds\n"
+ F"URL: {response.url}\n"
+ "Response Content:\n"
+ F"{response.text}")
raise Exception(error_response)
result = response.json()
return result

# Step One
# Execution of class is split into two parts so that changes to the url can be made halfway through
def pre_execute(self, query_params):
self.add_query_params_to_url(self, query_params=None)

# Step Two
# Final execution step where token is added and request is made.
def execute(self):
self.append_token_to_url()
self.make_iex_request()
Binary file added dist/FinMesh-2.0.1-py3-none-any.whl
Binary file not shown.
Binary file added dist/FinMesh-2.0.1.tar.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setuptools.setup(
name = "FinMesh",
version = "2.0.1",
version = "2.0.2",
author = "Michael and Josh Hartmann",
author_email = "[email protected]",
description = "A Python wrapper to bring together various financial APIs.",
Expand Down
4 changes: 2 additions & 2 deletions testupdate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ echo Uploading new version to Pypi...
twine upload --repository testpypi dist/*

echo Upgrading FinMesh...
pip3 install --upgrade --force-reinstall --index-url https://test.pypi.org/simple/ FinMesh
pip install --force-reinstall --index-url https://test.pypi.org/simple/ FinMesh
sleep 2s
pip3 install --upgrade --force-reinstall --index-url https://test.pypi.org/simple/ FinMesh
pip install --force-reinstall --index-url https://test.pypi.org/simple/ FinMesh
4 changes: 2 additions & 2 deletions update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ echo Pushing to GitHub repository...
git push

echo Upgrading FinMesh...
pip3 install --upgrade --force-reinstall FinMesh
pip3 install --force-reinstall FinMesh
sleep 2s
pip3 install --upgrade --force-reinstall FinMesh
pip3 install --force-reinstall FinMesh

0 comments on commit d8ef722

Please sign in to comment.