Skip to content

Commit

Permalink
Merge pull request #3 from Tauffer-Consulting/alphavantage
Browse files Browse the repository at this point in the history
Alphavantage
  • Loading branch information
luiztauffer authored Nov 17, 2023
2 parents ebbdf78 + 59c59ac commit 2a7f4d8
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 9 deletions.
6 changes: 3 additions & 3 deletions .domino/compiled_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@
"title": "SecretsModel",
"type": "object"
},
"source_url": "https://github.com/Tauffer-Consulting/news_domino_pieces/tree/main/pieces/NewsApiArticlesPiece"
"source_url": "https://github.com/Tauffer-Consulting/data_apis_domino_pieces/tree/main/pieces/NewsApiArticlesPiece"
},
"NewsApiHeadlinesPiece": {
"name": "NewsApiHeadlinesPiece",
Expand Down Expand Up @@ -475,7 +475,7 @@
"title": "SecretsModel",
"type": "object"
},
"source_url": "https://github.com/Tauffer-Consulting/news_domino_pieces/tree/main/pieces/NewsApiHeadlinesPiece"
"source_url": "https://github.com/Tauffer-Consulting/data_apis_domino_pieces/tree/main/pieces/NewsApiHeadlinesPiece"
},
"NasaEarthImagePiece": {
"name": "NasaEarthImagePiece",
Expand Down Expand Up @@ -572,6 +572,6 @@
"title": "SecretsModel",
"type": "object"
},
"source_url": "https://github.com/Tauffer-Consulting/news_domino_pieces/tree/main/pieces/NasaEarthImagePiece"
"source_url": "https://github.com/Tauffer-Consulting/data_apis_domino_pieces/tree/main/pieces/NasaEarthImagePiece"
}
}
2 changes: 1 addition & 1 deletion .domino/dependencies_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"NASA_API_KEY",
"NEWSAPI_API_KEY"
],
"source_image": "ghcr.io/tauffer-consulting/data_apis_domino_pieces:development-group0"
"source_image": "ghcr.io/tauffer-consulting/data_apis_domino_pieces:0.2.0-group0"
}
}
4 changes: 2 additions & 2 deletions .github/workflows/validate-and-organize.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.

- name: Set up Python 3.8
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.8"
python-version: "3.10"

- name: Pip install packages
run: |
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Domino Pieces for a variety of Data APIs:

- **NewsApiArticlesPiece** - Retrieves articles using [News API](https://newsapi.org/)
- **NewsApiArticlesPiece** - Retrieves articles using [News API](https://newsapi.org)
- **NewsApiHeadlinesPiece** - Retrieves headlines using [News API](https://newsapi.org/)
- **NasaEarthImagePiece** - Retrieves images of Earth using [NASA's EPIC API](https://epic.gsfc.nasa.gov/about/api)
- **AlphaVantageDailyPiece** - Retrieves daily stock data using [Alpha Vantage API](https://www.alphavantage.co)
2 changes: 1 addition & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ REGISTRY_NAME = "tauffer-consulting"
REPOSITORY_NAME = "data_apis_domino_pieces"
REPOSITORY_LABEL = "Data APIs Domino Pieces"

VERSION = "0.2.0"
VERSION = "0.3.0"
4 changes: 3 additions & 1 deletion dependencies/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
newsapi-python==0.2.7
beautifulsoup4==4.12.2
beautifulsoup4==4.12.2
pandas==2.1.3
plotly==5.18.0
21 changes: 21 additions & 0 deletions pieces/AlphaVantageDailyPiece/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "AlphaVantageDailyPiece",
"description": "This Piece uses the AlphaVantage API to get daily stock data.\n- https://www.alphavantage.co/",
"dependency": {
"requirements_file": "requirements.txt"
},
"container_resources": {
"requests": {
"cpu": "100m",
"memory": "128Mi"
},
"limits": {
"cpu": "500m",
"memory": "512Mi"
}
},
"style": {
"node_label": "AlphaVantage Daily",
"icon_class_name": "ant-design:stock-outlined"
}
}
35 changes: 35 additions & 0 deletions pieces/AlphaVantageDailyPiece/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from pydantic import BaseModel, Field
from enum import Enum


class OutputSizeTypes(str, Enum):
compact = "compact"
full = "full"


class InputModel(BaseModel):
symbol: str = Field(
default="AAPL",
description="The stock symbol."
)
output_size: OutputSizeTypes = Field(
default=OutputSizeTypes.compact,
description="The size of the output data. Options are `compact` (100 data points) and full (full-length data). Default is `compact`."
)
max_data_points: int = Field(
default=-1,
description="The maximum number of data points to return. Default is -1, which returns all data points."
)


class OutputModel(BaseModel):
data_file_path: str = Field(
default="",
description='Path to the data file.'
)


class SecretsModel(BaseModel):
ALPHA_VANTAGE_API_KEY: str = Field(
description="API key for Alpha Vantage data API."
)
97 changes: 97 additions & 0 deletions pieces/AlphaVantageDailyPiece/piece.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from domino.base_piece import BasePiece
from .models import InputModel, OutputModel, SecretsModel
import pandas as pd
import requests
import json
import plotly
import plotly.graph_objects as go


def make_plotly_fig(df: pd.DataFrame, symbol: str):
fig = go.Figure()
trace_candlestick = go.Candlestick(
x=df['Date'],
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Close'],
name='Candlestick'
)
fig.add_trace(trace_candlestick)
fig.update_layout(
xaxis=dict(
rangeslider=dict(visible=True),
showgrid=True, # Show gridlines for the x-axis
gridcolor='lightgray' # Set the grid color to gray
),
yaxis=dict(
showgrid=True,
gridcolor='lightgray',
fixedrange=False
),
title=f'{symbol} Daily Stock Data',
xaxis_title='Date',
yaxis_title='Price',
height=600,
width=800,
plot_bgcolor='white',
)
return fig


class AlphaVantageDailyPiece(BasePiece):
"""
This Piece uses the AlphaVantage API to get daily stock data.
- https://www.alphavantage.co/
"""
def piece_function(self, input_data: InputModel, secrets_data: SecretsModel):

api_key = secrets_data.ALPHA_VANTAGE_API_KEY
if not api_key:
raise Exception("Alpha Vantage API key is required.")

symbol = input_data.symbol
output_size = input_data.output_size.value
number_of_points = input_data.max_data_points

endpoint = 'https://www.alphavantage.co/query'
params = {
'function': 'TIME_SERIES_DAILY',
'symbol': symbol,
'outputsize': output_size,
'apikey': api_key
}

data_file_path = f"{self.results_path}/results_daily_data.csv"

try:
response = requests.get(endpoint, params=params)
if response.status_code == 200:
data = response.json()
daily_data = data['Time Series (Daily)']
df = pd.DataFrame(daily_data).T
if number_of_points > 0 and number_of_points < len(df):
df = df[:number_of_points]
df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
df.index = pd.to_datetime(df.index)
df.reset_index(inplace=True)
df.rename(columns={'index': 'Date'}, inplace=True)
df.to_csv(data_file_path, index=False)
else:
raise Exception(f'Error: {response.status_code} - {response.text}')
except Exception as e:
raise Exception(f'Error: {e}')

# Save image to results
fig = make_plotly_fig(df, symbol)
fig_json = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
with open(f"{self.results_path}/results_plotly.json", "w") as f:
f.write(fig_json)
self.display_result = {
"file_type": "plotly-json",
"file_path": f"{self.results_path}/results_plotly.json",
}

return OutputModel(
data_file_path=data_file_path
)
22 changes: 22 additions & 0 deletions pieces/AlphaVantageDailyPiece/test_alphavantage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from domino.testing import piece_dry_run
from pathlib import Path
import os


def test_alphavantage():
ALPHA_VANTAGE_API_KEY = os.environ.get("ALPHA_VANTAGE_API_KEY", None)
if not ALPHA_VANTAGE_API_KEY:
raise Exception("ALPHA_VANTAGE_API_KEY environment variable is required.")
input_data = dict(
symbol="AAPL",
output_size="compact",
max_data_points=-1
)
piece_output = piece_dry_run(
piece_name="AlphaVantageDailyPiece",
input_data=input_data,
secrets_data=dict(
ALPHA_VANTAGE_API_KEY=ALPHA_VANTAGE_API_KEY
),
)
assert Path(piece_output["data_file_path"]).exists()

0 comments on commit 2a7f4d8

Please sign in to comment.