Skip to content

Commit

Permalink
Prep for 2.2.0 (#210)
Browse files Browse the repository at this point in the history
* added rapidapi key integration

* prep for 2.1.3

* Removing get_batch_stock_quotes method (#189)

* Removing get_batch_stock_quotes method

Remove get_batch_stock_quotes method, resolving issue #184.

* remove tests for get_batch_stock_quotes

* Delete mock_batch_quotes

Was only used for the tests removed in the previous commits, which made this file dead weight.

* Add asyncio support for all components (#191)

* Add asyncio support for all components

In order to minimize the copy-paste between the async and sync
implementations, all of the non-base components are sym-linked to their
sync counterparts.  Since these import `AlphaVantage` locally, they
automatically pick up the async version, which is really nifty!

There was some refactoring in `SectorPerformance` to make the re-use
possible.

The async verison of AlphaVantage tries to re-use as much as possible
from the sync version.  The main differences are:
* a new `session` for the HTTP calls
* a new `close()` function which should be called when you're done
* `proxy` is a string instead of a dict

Using it:
```python
import asyncio
from alpha_vantage.async_support.timeseries import TimeSeries

async def get_data():
    ts = TimeSeries(key='YOUR_API_KEY')
    data, meta_data = await ts.get_intraday('GOOGL')
    await ts.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(get_data())
loop.close()
```

* Add asyncio packages to setup.py

* Issue #206: Add 'time_period' argument to 'get_bbands()' documentation. (#207)

* Fixes small documentation bugs (#208)

* fixed fx documentation

* fixed pypi badge for documentation

* prep for 2.2.0 (#209)

* fixed fx documentation

* fixed pypi badge for documentation

* prep for 2.2.0

* small documentaiton change for 2.2.0

Co-authored-by: Aaron Sanders <sandersaarond@gmail.com>
Co-authored-by: Jon Cinque <jon.cinque@gmail.com>
Co-authored-by: Peter Anderson <BWPanda@users.noreply.github.com>
  • Loading branch information
4 people committed Apr 26, 2020
1 parent 0a7a65d commit 3d8d213
Show file tree
Hide file tree
Showing 20 changed files with 912 additions and 131 deletions.
38 changes: 36 additions & 2 deletions README.md
Expand Up @@ -13,6 +13,7 @@ Vantage (http://www.alphavantage.co/). It requires a free API key, that can be r

## News

* From version 2.2.0 onwards, asyncio support now provided. See below for more information.
* From version 2.1.3 onwards, [rapidAPI](https://rapidapi.com/alphavantage/api/alpha-vantage-alpha-vantage-default) key integration is now available.
* From version 2.1.0 onwards, error logging of bad API calls has been made more apparent.
* From version 1.9.0 onwards, the urllib was substituted by pythons request library that is thread safe. If you have any error, post an issue.
Expand Down Expand Up @@ -159,7 +160,7 @@ Giving us as output:

### Foreign Exchange (FX)

The foreign exchange is just metadata, thus only available as json format (using the 'csv' or 'pandas' format will raise an Error)
The foreign exchange endpoint has no metadata, thus only available as json format and pandas (using the 'csv' format will raise an Error)

```python
from alpha_vantage.foreignexchange import ForeignExchange
Expand All @@ -182,6 +183,36 @@ Giving us as output:
}
```

### Asyncio support

From version 2.2.0 on, asyncio support will now be available. This is only for python versions 3.5+. If you do not have 3.5+, the code will break.

The syntax is simple, just mark your methods with the `async` keyword, and use the `await` keyword.

Here is an example of a for loop for getting multiple symbols asyncronously. This greatly improving the performance of a program with multiple API calls.

```python
import asyncio
from alpha_vantage.async_support.timeseries import TimeSeries

symbols = ['AAPL', 'GOOG', 'TSLA', 'MSFT']


async def get_data(symbol):
ts = TimeSeries(key='YOUR_KEY_HERE')
data, _ = await ts.get_quote_endpoint(symbol)
await ts.close()
return data

loop = asyncio.get_event_loop()
tasks = [get_data(symbol) for symbol in symbols]
group1 = asyncio.gather(*tasks)
results = loop.run_until_complete(group1)
loop.close()
print(results)
```


## Examples

I have added a repository with examples in a python notebook to better see the
Expand All @@ -207,13 +238,16 @@ Contributing is always welcome. Just contact us on how best you can contribute,
* The integration tests are not being run at the moment within travis, gotta fix them to run.
* Add test for csv calls as well.
* Add tests for incompatible parameter raise errors.
* Github actions & other items in the issues page.



## Contact:
You can reach the Alpha Vantage team on any of the following platforms:
You can reach/follow the Alpha Vantage team on any of the following platforms:
* [Slack](https://alphavantage.herokuapp.com/)
* [Twitter: @alpha_vantage](https://twitter.com/alpha_vantage)
* [Medium-Patrick](https://medium.com/@patrick.collins_58673)
* [Medium-AlphaVantage](https://medium.com/alpha-vantage)
* Email: support@alphavantage.co


Expand Down
51 changes: 48 additions & 3 deletions alpha_vantage/alphavantage.py
Expand Up @@ -3,6 +3,7 @@
from functools import wraps
import inspect
import sys
import re
# Pandas became an optional dependency, but we still want to track it
try:
import pandas
Expand Down Expand Up @@ -38,9 +39,9 @@ def __init__(self, key=None, output_format='json',
by the alpha vantage api call or 'integer' if you just want an
integer indexing on your dataframe. Only valid, when the
output_format is 'pandas'
proxy: Dictionary mapping protocol or protocol and hostname to
proxy: Dictionary mapping protocol or protocol and hostname to
the URL of the proxy.
rapidapi: Boolean describing whether or not the API key is
rapidapi: Boolean describing whether or not the API key is
through the RapidAPI platform or not
"""
if key is None:
Expand Down Expand Up @@ -159,6 +160,50 @@ def _call_wrapper(self, *args, **kwargs):
return self._handle_api_call(url), data_key, meta_data_key
return _call_wrapper

@classmethod
def _output_format_sector(cls, func, override=None):
""" Decorator in charge of giving the output its right format, either
json or pandas (replacing the % for usable floats, range 0-1.0)
Keyword Arguments:
func: The function to be decorated
override: Override the internal format of the call, default None
Returns:
A decorator for the format sector api call
"""
@wraps(func)
def _format_wrapper(self, *args, **kwargs):
json_response, data_key, meta_data_key = func(
self, *args, **kwargs)
if isinstance(data_key, list):
# Replace the strings into percentage
data = {key: {k: self.percentage_to_float(v)
for k, v in json_response[key].items()} for key in data_key}
else:
data = json_response[data_key]
# TODO: Fix orientation in a better way
meta_data = json_response[meta_data_key]
# Allow to override the output parameter in the call
if override is None:
output_format = self.output_format.lower()
elif 'json' or 'pandas' in override.lower():
output_format = override.lower()
# Choose output format
if output_format == 'json':
return data, meta_data
elif output_format == 'pandas':
data_pandas = pandas.DataFrame.from_dict(data,
orient='columns')
# Rename columns to have a nicer name
col_names = [re.sub(r'\d+.', '', name).strip(' ')
for name in list(data_pandas)]
data_pandas.columns = col_names
return data_pandas, meta_data
else:
raise ValueError('Format: {} is not supported'.format(
self.output_format))
return _format_wrapper

@classmethod
def _output_format(cls, func, override=None):
""" Decorator in charge of giving the output its right format, either
Expand Down Expand Up @@ -237,7 +282,7 @@ def set_proxy(self, proxy=None):
""" Set a new proxy configuration
Keyword Arguments:
proxy: Dictionary mapping protocol or protocol and hostname to
proxy: Dictionary mapping protocol or protocol and hostname to
the URL of the proxy.
"""
self.proxy = proxy or {}
Expand Down
Empty file.

0 comments on commit 3d8d213

Please sign in to comment.