Friday, 3 January 2020

react django yahoo_fin

pick ticker

analysts

balance sheet

cash flow

holders

income

quote

stats

yahoo_fin

#views

from django.http import  HttpResponse
from yahoo_fin import stock_info as si
from django.views.decorators.csrf import csrf_exempt
import io
import json
from contextlib import redirect_stdout

@csrf_exempt
def tickers(request):
    dow = si.tickers_dow()
    nasdaq = si.tickers_nasdaq()
    sp500 = si.tickers_sp500()
    other = si.tickers_other()

    all = json.dumps({'dow': dow,
                         'nasdaq': nasdaq,
                         'sp500': sp500,
                         'other': other})

    return HttpResponse(all)

@csrf_exempt
def analysts(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_analysts_info(ticker)
        #print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def balance(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_balance_sheet(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def cash(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_cash_flow(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def holder(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_holders(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def income(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_income_statement(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def quote(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_quote_table(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def stats(request):
    ticker = json.loads(request.body)['ticker']

    if not ticker:
        return HttpResponse('ticker not received')
    else:
        info = si.get_stats(ticker)
        # print info to a text buffer
        with io.StringIO() as buf, redirect_stdout(buf):
            print(info)
            output = buf.getvalue()

        return HttpResponse(output)

@csrf_exempt
def about_yahoo_fin(request):
    help = '<a href="http://theautomatic.net/yahoo_fin-documentation/">YAHOO_FIN DOCUMENTATION</a><br/>' \
           '<b>stock_info module</b><br/>get_analysts_info<br/>get_balance_sheet<br/>get_cash_flow<br/>get_data<br/>' \
           'get_day_gainers<br/>get_day_losers<br/>get_day_most_active<br/>get_holders<br/>' \
           'get_income_statement<br/>get_live_price<br/>get_quote_table<br/>get_top_crypto<br/>get_stats<br/>' \
           'tickers_dow<br/>tickers_nasdaq<br/>tickers_other<br/>tickers_sp500<br/>'
    return HttpResponse(help)

---------------------------------------
#yahoo_fin/urls

from django.urls import path
from . import views

urlpatterns = [
    path('tickers/', views.tickers, name='tickers'),
    path('about_yahoo_fin/', views.about_yahoo_fin, name='about_yahoo_fin'),
    path('analysts/', views.analysts, name='analysts'),
    path('balance/', views.balance, name='balance'),
    path('cash/', views.cash, name='cash'),
    path('holder/', views.holder, name='holder'),
    path('income/', views.income, name='income'),
    path('quote/', views.quote, name='quote'),
    path('stats/', views.stats, name='stats'),
]

//app.js

import React, { useState, useEffect } from 'react';
import './App.css';
import { Button, Tabs, Progress, Menu, Radio, Input } from 'antd';
import ReactHtmlParser from 'react-html-parser';
import StickyHeader from 'react-sticky-header';
const axios = require('axios');
const { TabPane } = Tabs;
const { SubMenu } = Menu;

function App() {
  const [tickers, settickers] = useState(null)
  const [ticker_loaded, setticker_loaded] = useState(0)
  const [ticker_radio, setticker_radio] = useState('AAPL')
  const [about_api, setabout_api] = useState(null)
  const [active_menu, setactive_menu] = useState('dow')
  const [analyst_info, setanalyst_info] = useState(null)
  const [balance_sheet, setbalance_sheet] = useState(null)
  const [cash_flow, setcash_flow] = useState(null)
  const [holder, setholder] = useState(null)
  const [income, setincome] = useState(null)
  const [quote, setquote] = useState(null)
  const [stats, setstats] = useState(null)

  //load once when mounted = componentdidmount
  useEffect(() => {
    document.title = "yahoo_fin"

    //load all tickers
    axios({
      method: 'get',
      url: 'http://127.0.0.1:8000/stocks/tickers/',
      onDownloadProgress: progressEvent => {
        setticker_loaded(parseInt(progressEvent.loaded / progressEvent.total * 100))

      },
    })
      .then((response) => {
        settickers(response.data)
        console.log(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }, [])

  const about_yahoo_fin = () => {
    //yahoo_fin api page
    axios({
      method: 'get',
      url: 'http://127.0.0.1:8000/stocks/about_yahoo_fin/',
    })
      .then((response) => {
        setabout_api(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_analysts_info = () => {
    //get_analysts_info
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/analysts/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setanalyst_info(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_balance_sheet = () => {
    //get_balance_sheet
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/balance/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setbalance_sheet(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_cash_flow = () => {
    //get_cash_flow
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/cash/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setcash_flow(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_holders = () => {
    //get_holders
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/holder/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setholder(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_income_statement = () => {
    //get_income_statement
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/income/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setincome(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_quote_table = () => {
    //get_quote_table
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/quote/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setquote(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  const get_stats = () => {
    //get_stats
    axios({
      method: 'post',
      url: 'http://127.0.0.1:8000/stocks/stats/',
      data: {
        'ticker': ticker_radio,
      }
    })
      .then((response) => {
        setstats(response.data)
      })
      .catch((error) => {
        console.log(error)
      })
  }

  //left tab click event
  const tabChange = (key) => {
    switch (key) {
      case '2':
        get_analysts_info()
        break
      case '3':
        about_yahoo_fin()
        break
      case '4':
        get_balance_sheet()
        break
      case '5':
        get_cash_flow()
        break
      case '6':
        get_holders()
        break
      case '7':
        get_income_statement()
        break
      case '8':
        get_quote_table()
        break
      case '9':
        get_stats()
        break
      default:
        break
    }
  }
  //Tickers tab menu click event
  const menuClick = (e) => {
    setactive_menu(e.key)
  }
  //Tickers radio select event
  const radioSelect = (e) => {
    setticker_radio(e.target.value)
  }

  return (
    <div style={{ padding: '10px' }}>

      <Tabs tabPosition='left' defaultActiveKey="1" onChange={(key) => tabChange(key)}>
        <TabPane tab="Tickers" key="1">
          Loading tickers
          <StickyHeader
            header={<span style={{ float: 'right', backgroundColor: 'white', padding: '10px' }}>
              Selected ticker: {ticker_radio}</span>}>
          </StickyHeader>

          <Progress percent={ticker_loaded} size='small' />

          <Menu onClick={(e) => menuClick(e)} selectedKeys={[active_menu]} mode='horizontal'>
            <Menu.Item key='dow'>Dow</Menu.Item>
            <Menu.Item key='nasdaq'>Nasdaq</Menu.Item>
            <Menu.Item key='sp500'>SP500</Menu.Item>
            <Menu.Item key='other'>Other</Menu.Item>
          </Menu><br />

          {tickers ?
            <Radio.Group onChange={(e) => radioSelect(e)}>
              {
                tickers[active_menu].map((item, index) => {
                  return <Radio value={item} key={index}>{item}</Radio>
                })
              }
            </Radio.Group>
            : null}
        </TabPane>
        <TabPane tab="Analyst" key="2">
          Ticker: {ticker_radio}<br />
          <pre>{analyst_info}</pre>
        </TabPane>
        <TabPane tab="Balance" key="4">
          Ticker: {ticker_radio}<br />
          <pre>{balance_sheet}</pre>
        </TabPane>
        <TabPane tab="Cash" key="5">
          Ticker: {ticker_radio}<br />
          <pre>{cash_flow}</pre>
        </TabPane>
        <TabPane tab="Holder" key="6">
          Ticker: {ticker_radio}<br />
          <pre>{holder}</pre>
        </TabPane>
        <TabPane tab="Income" key="7">
          Ticker: {ticker_radio}<br />
          <pre>{income}</pre>
        </TabPane>
        <TabPane tab="Quote" key="8">
          Ticker: {ticker_radio}<br />
          <pre>{quote}</pre>
        </TabPane>
        <TabPane tab="Stats" key="9">
          Ticker: {ticker_radio}<br />
          <pre>{stats}</pre>
        </TabPane>
        <TabPane tab="Yahoo_fin" key="3">
          {ReactHtmlParser(about_api)}
        </TabPane>
      </Tabs>

    </div>
  );
}

export default App;

---------------------------------------------
//index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'antd/dist/antd.css';
import 'react-sticky-header/styles.css';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

-------------------------------
//package.json

{
  "name": "react-yahoo-fin",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.4.0",
    "@testing-library/user-event": "^7.2.1",
    "antd": "^3.26.6",
    "axios": "^0.19.0",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-html-parser": "^2.0.2",
    "react-scripts": "3.3.0",
    "react-sticky-header": "^0.2.0",
    "reactstrap": "^8.2.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}


reference:
https://stackoverflow.com/questions/46160461/how-do-you-set-the-document-title-in-react

cors
https://stackoverflow.com/questions/35760943/how-can-i-enable-cors-on-django-rest-framework

axios csrf
https://stackoverflow.com/questions/17716624/django-csrf-cookie-not-set

html parser
https://stackoverflow.com/questions/39758136/render-html-string-as-real-html-in-a-react-component

print to buf
https://stackoverflow.com/questions/1218933/can-i-redirect-the-stdout-in-python-into-some-sort-of-string-buffer

No comments:

Post a Comment