GithubHelp home page GithubHelp logo

upstox-python's Introduction

Upstox Python SDK for API v2

PyPI

Introduction

The official Python client for communicating with the Upstox API.

Upstox API is a set of rest APIs that provide data required to build a complete investment and trading platform. Execute orders in real time, manage user portfolio, stream live market data (using Websocket), and more, with the easy to understand API collection.

  • API version: v2
  • Package version: 2.6.0
  • Build package: io.swagger.codegen.v3.generators.python.PythonClientCodegen

This Python package is automatically generated by the Swagger Codegen project.

Documentation.

Upstox API Documentation

Requirements.

Python 2.7 and 3.4+

Installation & Usage

pip install

If the python package is hosted on Github, you can install directly from Github

pip install upstox-python-sdk

(you may need to run pip with root permission: sudo pip install upstox-python-sdk)

Then import the package:

import upstox_client 

Setuptools

Install via Setuptools.

python setup.py install --user

(or sudo python setup.py install to install the package for all users)

Then import the package:

import upstox_client

Examples

Sample Implementations can be found within /examples folder.

Documentation for API Endpoints

All URIs are relative to https://api.upstox.com/v2/

Class Method HTTP request Description
ChargeApi get_brokerage GET /v2/charges/brokerage Brokerage details
HistoryApi get_historical_candle_data GET /v2/historical-candle/{instrumentKey}/{interval}/{to_date} Historical candle data
HistoryApi get_historical_candle_data1 GET /v2/historical-candle/{instrumentKey}/{interval}/{to_date}/{from_date} Historical candle data
HistoryApi get_intra_day_candle_data GET /v2/historical-candle/intraday/{instrumentKey}/{interval} Intra day candle data
LoginApi authorize GET /v2/login/authorization/dialog Authorize API
LoginApi logout DELETE /v2/logout Logout
LoginApi token POST /v2/login/authorization/token Get token API
MarketHolidaysAndTimingsApi get_exchange_timings GET /v2/market/timings/{date} Get Exchange Timings on particular date
MarketHolidaysAndTimingsApi get_holiday GET /v2/market/holidays/{date} Get Holiday on particular date
MarketHolidaysAndTimingsApi get_holidays GET /v2/market/holidays Get Holiday list of current year
MarketHolidaysAndTimingsApi get_market_status GET /v2/market/status/{exchange} Get Market status for particular exchange
MarketQuoteApi get_full_market_quote GET /v2/market-quote/quotes Market quotes and instruments - Full market quotes
MarketQuoteApi get_market_quote_ohlc GET /v2/market-quote/ohlc Market quotes and instruments - OHLC quotes
MarketQuoteApi ltp GET /v2/market-quote/ltp Market quotes and instruments - LTP quotes.
OptionsApi get_option_contracts GET /v2/option/contract Get option contracts
OptionsApi get_put_call_option_chain GET /v2/option/chain Get option chain
OrderApi cancel_order DELETE /v2/order/cancel Cancel order
OrderApi get_order_book GET /v2/order/retrieve-all Get order book
OrderApi get_order_details GET /v2/order/history Get order history
OrderApi get_trade_history GET /v2/order/trades/get-trades-for-day Get trades
OrderApi get_trades_by_order GET /v2/order/trades Get trades for order
OrderApi modify_order PUT /v2/order/modify Modify order
OrderApi place_order POST /v2/order/place Place order
PortfolioApi convert_positions PUT /v2/portfolio/convert-position Convert Positions
PortfolioApi get_holdings GET /v2/portfolio/long-term-holdings Get Holdings
PortfolioApi get_positions GET /v2/portfolio/short-term-positions Get Positions
TradeProfitAndLossApi get_profit_and_loss_charges GET /v2/trade/profit-loss/charges Get profit and loss on trades
TradeProfitAndLossApi get_trade_wise_profit_and_loss_data GET /v2/trade/profit-loss/data Get Trade-wise Profit and Loss Report Data
TradeProfitAndLossApi get_trade_wise_profit_and_loss_meta_data GET /v2/trade/profit-loss/metadata Get profit and loss meta data on trades
UserApi get_profile GET /v2/user/profile Get profile
UserApi get_user_fund_margin GET /v2/user/get-funds-and-margin Get User Fund And Margin
WebsocketApi get_market_data_feed GET /v2/feed/market-data-feed Market Data Feed
WebsocketApi get_market_data_feed_authorize GET /v2/feed/market-data-feed/authorize Market Data Feed Authorize
WebsocketApi get_portfolio_stream_feed GET /v2/feed/portfolio-stream-feed Portfolio Stream Feed
WebsocketApi get_portfolio_stream_feed_authorize GET /v2/feed/portfolio-stream-feed/authorize Portfolio Stream Feed Authorize

Documentation for Feeder Functions

Connecting to the WebSocket for market and portfolio updates is streamlined through two primary Feeder functions:

  1. MarketDataStreamer: Offers real-time market updates, providing a seamless way to receive instantaneous information on various market instruments.
  2. PortfolioDataStreamer: Delivers updates related to the user's orders, enhancing the ability to track order status and portfolio changes effectively.

Both functions are designed to simplify the process of subscribing to essential data streams, ensuring users have quick and easy access to the information they need.

Detailed Explanation of Feeder Interface

MarketDataStreamer

The MarketDataStreamer interface is designed for effortless connection to the market WebSocket, enabling users to receive instantaneous updates on various instruments. The following example demonstrates how to quickly set up and start receiving market updates for selected instrument keys:

import upstox_client

def on_message(message):
    print(message)


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration), ["NSE_INDEX|Nifty 50", "NSE_INDEX|Nifty Bank"], "full")

    streamer.on("message", on_message)

    streamer.connect()


if __name__ == "__main__":
    main()

In this example, you first authenticate using an access token, then instantiate MarketDataStreamer with specific instrument keys and a subscription mode. Upon connecting, the streamer listens for market updates, which are logged to the console as they arrive.

Feel free to adjust the access token placeholder and any other specifics to better fit your actual implementation or usage scenario.

Exploring the MarketDataStreamer Functionality

Modes

  • ltpc: ltpc provides information solely about the most recent trade, encompassing details such as the last trade price, time of the last trade, quantity traded, and the closing price from the previous day.
  • full: The full option offers comprehensive information, including the latest trade prices, D5 depth, 1-minute, 30-minute, and daily candlestick data, along with some additional details.

Functions

  1. constructor MarketDataStreamer(apiClient, instrumentKeys, mode): Initializes the streamer with optional instrument keys and mode (full or ltpc).
  2. connect(): Establishes the WebSocket connection.
  3. subscribe(instrumentKeys, mode): Subscribes to updates for given instrument keys in the specified mode. Both parameters are mandatory.
  4. unsubscribe(instrumentKeys): Stops updates for the specified instrument keys.
  5. changeMode(instrumentKeys, mode): Switches the mode for already subscribed instrument keys.
  6. disconnect(): Ends the active WebSocket connection.
  7. auto_reconnect(enable, interval, retryCount): Customizes auto-reconnect functionality. Parameters include a flag to enable/disable it, the interval(in seconds) between attempts, and the maximum number of retries.

Events

  • open: Emitted upon successful connection establishment.
  • close: Indicates the WebSocket connection has been closed.
  • message: Delivers market updates.
  • error: Signals an error has occurred.
  • reconnecting: Announced when a reconnect attempt is initiated.
  • autoReconnectStopped: Informs when auto-reconnect efforts have ceased after exhausting the retry count.

The following documentation includes examples to illustrate the usage of these functions and events, providing a practical understanding of how to interact with the MarketDataStreamer effectively.


  1. Subscribing to Market Data on Connection Open with MarketDataStreamer
import upstox_client

def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    def on_open():
        streamer.subscribe(
            ["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"], "full")

    def on_message(message):
        print(message)

    streamer.on("open", on_open)
    streamer.on("message", on_message)

    streamer.connect()

if __name__ == "__main__":
    main()

  1. Subscribing to Instruments with Delays
import upstox_client
import time


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    def on_open():
        streamer.subscribe(
            ["NSE_EQ|INE020B01018"], "full")

    # Handle incoming market data messages\
    def on_message(message):
        print(message)

    streamer.on("open", on_open)
    streamer.on("message", on_message)

    streamer.connect()

    time.sleep(5)
    streamer.subscribe(
        ["NSE_EQ|INE467B01029"], "full")


if __name__ == "__main__":
    main()

  1. Subscribing and Unsubscribing to Instruments
import upstox_client
import time


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    def on_open():
        print("Connected. Subscribing to instrument keys.")
        streamer.subscribe(
            ["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"], "full")

    # Handle incoming market data messages\
    def on_message(message):
        print(message)

    streamer.on("open", on_open)
    streamer.on("message", on_message)

    streamer.connect()

    time.sleep(5)
    print("Unsubscribing from instrument keys.")
    streamer.unsubscribe(["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"])


if __name__ == "__main__":
    main()

  1. Subscribe, Change Mode and Unsubscribe
import upstox_client
import time

def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    def on_open():
        print("Connected. Subscribing to instrument keys.")
        streamer.subscribe(
            ["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"], "full")

    # Handle incoming market data messages\
    def on_message(message):
        print(message)

    streamer.on("open", on_open)
    streamer.on("message", on_message)

    streamer.connect()

    time.sleep(5)
    print("Changing subscription mode to ltpc...")
    streamer.change_mode(
        ["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"], "ltpc")

    time.sleep(5)
    print("Unsubscribing from instrument keys.")
    streamer.unsubscribe(["NSE_EQ|INE020B01018", "NSE_EQ|INE467B01029"])


if __name__ == "__main__":
    main()

  1. Disable Auto-Reconnect
import upstox_client
import time


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    def on_reconnection_halt(message):
        print(message)

    streamer.on("autoReconnectStopped", on_reconnection_halt)

    # Disable auto-reconnect feature
    streamer.auto_reconnect(False)

    streamer.connect()


if __name__ == "__main__":
    main()

  1. Modify Auto-Reconnect parameters
import upstox_client


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.MarketDataStreamer(
        upstox_client.ApiClient(configuration))

    # Modify auto-reconnect parameters: enable it, set interval to 10 seconds, and retry count to 3
    streamer.auto_reconnect(True, 10, 3)

    streamer.connect()


if __name__ == "__main__":
    main()

PortfolioDataStreamer

Connecting to the Portfolio WebSocket for real-time order updates is straightforward with the PortfolioDataStreamer function. Below is a concise guide to get you started on receiving updates:

import upstox_client

def on_message(message):
    print(message)


def main():
    configuration = upstox_client.Configuration()
    access_token = <ACCESS_TOKEN>
    configuration.access_token = access_token

    streamer = upstox_client.PortfolioDataStreamer(
        upstox_client.ApiClient(configuration))

    streamer.on("message", on_message)

    streamer.connect()


if __name__ == "__main__":
    main()

Position and holding updates can be enabled by setting the corresponding flag to True in the constructor of the PortfolioDataStreamer class.

import upstox_client
import data_token


def on_message(message):
    print(message)


def on_open():
    print("connection opened")


def main():
    configuration = upstox_client.Configuration()
    configuration.access_token = <ACCESS_TOKEN>

    streamer = upstox_client.PortfolioDataStreamer(upstox_client.ApiClient(configuration),order_update=True,position_update=True,holding_update=True)

    streamer.on("message", on_message)
    streamer.on("open", on_open)
    streamer.connect()


if __name__ == "__main__":
    main()

This example demonstrates initializing the PortfolioDataStreamer, connecting it to the WebSocket, and setting up an event listener to receive and print order updates. Replace <ACCESS_TOKEN> with your valid access token to authenticate the session.

Exploring the PortfolioDataStreamer Functionality

Functions

  1. constructor PortfolioDataStreamer(): Initializes the streamer.
  2. connect(): Establishes the WebSocket connection.
  3. disconnect(): Ends the active WebSocket connection.
  4. auto_reconnect(enable, interval, retryCount): Customizes auto-reconnect functionality. Parameters include a flag to enable/disable it, the interval(in seconds) between attempts, and the maximum number of retries.

Events

  • open: Emitted upon successful connection establishment.
  • close: Indicates the WebSocket connection has been closed.
  • message: Delivers market updates.
  • error: Signals an error has occurred.
  • reconnecting: Announced when a reconnect attempt is initiated.
  • autoReconnectStopped: Informs when auto-reconnect efforts have ceased after exhausting the retry count.

Documentation For Models

upstox-python's People

Contributors

alokgaira avatar ketangupta12 avatar rahulzz avatar svishi avatar yogendrasrivastava avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

upstox-python's Issues

History data feed isssue

Hi

I'm using upstox history data feed python api and when i request 10Min candle then it works perfectly except the in the morning candle.. First morning candle at 09:15 and second come at 09:30 (its a 15min candle), other all candles are fine (10min bars).

Can we fix it?

AttributeError: module 'websocket._ssl_compat' has no attribute 'ssl'

Hello,

When i try to use the upstox using Recticulate package for Python for R , i get below error:

Error in py_module_import(module, convert = convert) :
AttributeError: module 'websocket._ssl_compat' has no attribute 'ssl'

Detailed traceback:
File "C:\PROGRA3\ANACON1\lib\site-packages\upstox_api\api.py", line 12, in
import websocket
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_init_.py", line 23, in
from ._app import WebSocketApp
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_app.py", line 36, in
from ._core import WebSocket, getdefaulttimeout
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_core.py", line 34, in
from ._handshake import *
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_handshake.py", line 30, in
from ._http import *
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_http.py", line 31, in
from ._socket import*
File "C:\PROGRA3\ANACON1\lib\site-packages\websocket_socket.py", line 30, in
from ._ssl_compat import *

Could you please help me?

modify_order order not working as before

The below code was working previously but now started giving below error.
{"code":400,"status":"Bad Request","timestamp":"2021-07-09T12:49:52+05:30","message":"Can not modify this order.","error":{"name":"Error","reason":"Can not modify this order."}}

Syntax: image

Here is an example:

New_price = 100
df_temp = pd.DataFrame(u.get_order_history())
for label, row in df_temp.iterrows():
u.modify_order(row['order_id'],
quantity=None,
order_type=None,
price=float(New_price),
trigger_price=None,
disclosed_quantity=None,
duration=None)

Error at accessing token

import upstox_api.api as upapi
s = upapi.Session (APIKEY)
s.set_redirect_uri (MYURL)
s.set_api_secret (APISECRET)

print (s.get_login_url())        #then I go into that website and log in which redirects to my website with the code

s.set_code ('p3VHsd')      #putting the code which i got

access_token = s.retrieve_access_token()       #this gives error

NOTE : i followed the code which has been given in this GitHub repo exactly
version of library -> 2.0.1
python version -> 3.9.13

ERROR

SystemError Traceback (most recent call last)
Cell In[28], line 1
----> 1 access_token = s.retrieve_access_token()
2 print ('Received access_token: %s' % access_token)

File c:\Users\anaconda3\lib\site-packages\upstox_api\api.py:94, in Session.retrieve_access_token(self)
92 body = json.loads(r.text)
93 if 'access_token' not in body:
---> 94 raise SystemError(body);
95 return body

SystemError: {'message': 'Forbidden'}

Websocket order update

Hi Team,

Just have few question.

  1. Can we connect both order update and streaming data Websocket together ?
    Need to know about the order updates and want the streaming stock data i.e. ohlc/ltp date for some stocks together

  2. Can we test order update websocket after the market is closed ?
    Do tarting the websocket after the market is closed and then placing some orders (which will fail obviously) will show the order events like failed, placed etc. via API ?
    Will it show AMO(after market order) (during trading hours and after market is closed) ?

login issue

    # Configure OAuth2 access token for authorization: OAUTH2
    configuration = upstox_client.Configuration()
    configuration.access_token = 'YOUR_ACCESS_TOKEN'

what is access token ?

give an example for login.

give details about access token

Getting error while trying to cancel all the open orders.

Lately I have been getting following error, when I try to cancel all open orders in system.

  File "C:\Users\Admin\Anaconda3\lib\site-packages\apscheduler\executors\base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "E:\Work\Upstox\Final\AUTO_Order_cancellation.py", line 44, in order_cancel
    u.cancel_all_orders()
  File "C:\Users\Admin\Anaconda3\lib\site-packages\upstox_api\api.py", line 610, in cancel_all_orders
    return self.api_call_helper('cancelAllOrders', PyCurlVerbs.DELETE, None, None)
  File "C:\Users\Admin\Anaconda3\lib\site-packages\upstox_api\api.py", line 856, in api_call_helper
    raise requests.HTTPError(response.text)
requests.exceptions.HTTPError: {"code":400,"status":"Bad Request","timestamp":"2021-12-14T15:10:00+05:30","message":"No open orders to cancel","error":{"name":"Error","reason":"No open orders to cancel"}}``

I am using following code

u = Upstox(.....,access_token)
u.cancel_all_orders()

It is throwing error, even though there are open orders present in the system.

Please look into this issue.

Deleted package detected

I'm a Cyber Security researcher and developer of PackjGuard [1] to address open-source software supply chain attacks.

Issue

During my research, I detected a deleted package in this repository.

Details

Specifically, the package upstox-python mentioned in file README at line 30 does not exist on the public PyPI registry. A bad actor can hijack this package to propagate malicious code.

Impact

Not only your apps/services using https://github.com/upstox/upstox-python repo code are vulnerable to this attack, but the users of your open-source Github repo could also fall victim.

You could read more about such attacks here: https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610

Remediation

Please highlight this in file README and register a placeholder package for upstox-python on public PyPI soon to remediate.

To automatically fix such issues in future, please install PackjGuard Github app [1].

Thanks!

  1. PackjGuard is a Github app that monitors your repos 24x7, detects vulnerable/malicious/risky open-source dependencies, and creates pull requests for auto remediation: https://github.com/marketplace/packjguard

unable to pip - "Please specify --curl-dir=/path/to/built/libcurl" error

Hi.,
I am trying this on Windows PC and getting below error while installing.

pip install pycurl
Collecting pycurl
Using cached pycurl-7.43.0.tar.gz
Complete output from command python setup.py egg_info:
Please specify --curl-dir=/path/to/built/libcurl

----------------------------------------

Command "python setup.py egg_info" failed with error code 10 in C:\Users\xxxx\AppData\Local\Temp\pip-build-lya0ul6p\pycurl\

Thanks,

issue in websocket

Hi team,

After upsto stopped API and started again.... I am seeing some issues occuring..

Websocket connection has issues.

2020-07-02 22:58:09.182 | DEBUG    | __main__:start_watch:2900 - Subscribed to: Instrument(exchange='MCX_FO', token=217804, parent_token=294, symbol='crudeoil20julfut', name='CRUDE OIL', closing_price=3003.0, expiry='1595269799000', strike_price=None, tick_size=100.0, lot_size=100, instrument_type='FUTCOM', isin=None)

2020-07-02 22:58:09.184 | DEBUG    | __main__:start_watch:2905 - Listening: ['CRUDEOIL20JULFUT']

2020-07-02 22:58:12.277 | DEBUG    | __main__:start_watch:2909 - Started strategy runner for crudeoilm...
error: in on_error args=(<websocket._app.WebSocketApp object at 0x7ff01658b080>, SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:847)')), kwargs={}

2020-07-02 22:58:12.440 | DEBUG    | __main__:on_error:2766 - error: in on_error args=(<websocket._app.WebSocketApp object at 0x7ff01658b080>, SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:847)')), kwargs={}

subscribed but websocket connection failing..
Used websocket-client version of Version: 0.40.0
Also tried latest version of websocket.. Later version no errors but no data received on websocket.. thus reverrted to Version: 0.40.0.. which is recommended.

Please resolve or point out any workaround ??

CAN ANY BODY FIX THIS ISSUE

THIS IS MY CODE

`from future import print_function
import time
import upstox_client
from upstox_client.rest import ApiException
from pprint import pprint

Configure OAuth2 access token for authorization: OAUTH2

configuration = upstox_client.Configuration()
configuration.access_token = token

create an instance of the API class

api_instance = upstox_client.MarketQuoteApi(upstox_client.ApiClient(configuration))
symbol = 'TECHM' # str | Comma separated list of symbols
api_version = api # str | API Version Header

try:
# Market quotes and instruments - Full market quotes
api_response = api_instance.get_full_market_quote(symbol, api_version)
pprint(api_response)
except ApiException as e:
print("Exception when calling MarketQuoteApi->get_full_market_quote: %s\n" % e)`

THIS WILL THROW AN ERROR

Exception when calling MarketQuoteApi->get_full_market_quote: (400) Reason: Bad Request HTTP response headers: HTTPHeaderDict({'Date': 'Mon, 18 Dec 2023 10:15:12 GMT', 'Content-Type': 'application/json', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Origin, Access-Control-Request-Method, Access-Control-Request-Headers', 'message': 'request failed', 'requestId': '38f4ec52-cda8-4243-a84c-d5e61acc6223', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Strict-Transport-Security': 'max-age=0; includeSubDomains', 'X-Frame-Options': 'DENY', 'CF-Cache-Status': 'DYNAMIC', 'Set-Cookie': '__cf_bm=h8THwt1WvO.k0vkpH.EZJ4qOaVuMksdknZ2n_ba_s2g-1702894512-1-AdB5+ZTlzyAuq5F/bccA4Pzt2LcMgkI3nHQsr12CpSq4PYk8tl1eLulDb3zguG/8qeECnKRp1+h12DsgYY+an1A=; path=/; expires=Mon, 18-Dec-23 10:45:12 GMT; domain=.upstox.com; HttpOnly; Secure; SameSite=None, _cfuvid=riSE6HpwwSnCYKLo0wPVigNf_Zvi1D9bCKYSfFyOOU8-1702894512390-0-604800000; path=/; domain=.upstox.com; HttpOnly; Secure; SameSite=None', 'Server': 'cloudflare', 'CF-RAY': '8376a4adf8412fe5-CNN'}) HTTP response body: b'{"status":"error","errors":[{"errorCode":"UDAPI1011","message":"symbol is of invalid format","propertyPath":"getFullMarketQuote.symbol","invalidValue":"TECHM","error_code":"UDAPI1011","property_path":"getFullMarketQuote.symbol","invalid_value":"TECHM"}]}'

Error when trying to get ltc or ohlc quotes

I am getting the following error when calling the MarketQuoteAPI to get LTC or OHLC quote data for a specific instrument

File ***\venv\lib\site-packages\upstox_client\api_client.py", line 206, in sanitize_for_serialization
for attr, _ in six.iteritems(obj.swagger_types)
AttributeError: 'Instrument' object has no attribute 'swagger_types'

I am calling it as per the example provided in the github document

try:
api_instance = upstox_client.MarketQuoteApi(upstox_client.ApiClient(self._configuration))
# api_response = api_instance.ltp(instrument, self.api_version)
api_response = api_instance.get_market_quote_ohlc(instrument, "1d", self.api_version)
if api_response.status == "success":
return api_response.data["last_price"]
else:
return 0
except ApiException as e:
# TODO: Log error message
return 0

No clear documentation

Hi ,

It seems almost all methods are missing detail descriptions of arguments and the same applies to parent HTTP docs on uplink site, can someone spend a few days to document all code so as to help us make more sense of examples. It is very difficult to get anything to work right now based on the limited documentation here. Do you have a starter script that fully works?

Explanation of the ticks data

Where can I find the documentation for ticks data:-

{'timestamp': '1567147349000', 'exchange': 'NSE_FO', 'symbol': 'BANKNIFTY19SEPFUT', 'ltp': 27273.2, 'close': 27435.2, 'open': 27501.15, 'high': 27686.0, 'low': 27151.5, 'vtt': 2412740.0, 'atp': 27434.26, 'oi': 1749800.0, 'spot_price': 27224.95, 'total_buy_qty': 449200, 'total_sell_qty': 204480, 'lower_circuit': 24691.7, 'upper_circuit': 30178.75, 'yearly_low': None, 'ltt': 1567147348000, 'bids': [{'quantity': 20, 'price': 27271.25, 'orders': 1}, {'quantity': 80, 'price': 27271.1, 'orders': 1}, {'quantity': 40, 'price': 27270.2, 'orders': 1}, {'quantity': 220, 'price': 27270.0, 'orders': 3}, {'quantity': 240, 'price': 27269.9, 'orders': 1}], 'asks': [{'quantity': 20, 'price': 27273.65, 'orders': 1}, {'quantity': 20, 'price': 27273.9, 'orders': 1}, {'quantity': 20, 'price': 27273.95, 'orders': 1}, {'quantity': 120, 'price': 27274.0, 'orders': 1}, {'quantity': 20, 'price': 27274.15, 'orders': 1}], 'instrument': Instrument(exchange='NSE_FO', token=44460, parent_token=26009, symbol='banknifty19sepfut', name='', closing_price=27435.2, expiry='1569436200000', strike_price=None, tick_size=5.0, lot_size=20, instrument_type='FUTIDX', isin=None)}

Can you please explain the highlighted item? Is there any link to documentation?

Convert quote update values to numbers / strings from bytes

When getting quote updates, the values are just dictionary objects. Would be nice to convert them into int/float/strings. Probably at this line:

for index, field in enumerate(fields):
    if field == 'NaN' or field == '':
        fields[index] = None

required redirect_uri

hi
below is the message i recieve when i tried to authorize my access from login url..

{"code":401,"status":"Unauthorized","timestamp":"2021-05-25T10:57:16+05:30","message":"Invalid redirect_uri","error":{"name":"Error","reason":"Invalid redirect_uri"}}

##code
s = Session(user_api_key)
s.set_redirect_uri(user_api_redirect_url)
s.set_api_secret(user_api_access_token_key)
print('URL:%s' % s.get_login_url())

Thanks
Vijay

message":"Access Denied"reason":"Invalid Bearer token

I am getting the following error, do anybody have any idea how to resolve it
requests.exceptions.HTTPError: {"code":401,"status":"Unauthorized","timestamp":"2021-03-02T06:03:17+05:30","message":"Access Denied","error":{"reason":"Invalid Bearer token"}}

Simple Live Feed not working

I have a very simple live feed program to get live feed data, but there is no response:
MY code is as below:

`from upstox_api.api import *

import datetime
import sys

def event_handler_quote_update(message):
    print("Quote Update: %s" % str(message))
    sys.stdout.flush()

u = Upstox('xxxxxx', 'xxxxxx')

inst = u.get_master_contract('NSE_EQ')
inst = u.get_master_contract('NSE_INDEX')

u.subscribe(u.get_instrument_by_symbol('NSE_EQ', 'TATAMTRDVR'), LiveFeedType.Full)

u.set_on_quote_update(event_handler_quote_update)

u.start_websocket(False)`

Search instruments not returning correct results

When searched from get_instrument_by_symbol, Nifty bank returns results. But when used search function it does not return the output.

ipdb> o = u.get_instrument_by_symbol('NSE_INDEX', 'NIFTY_BANK')
ipdb> o
Instrument(exchange=u'NSE_INDEX', token=u'', parent_token=None, symbol=u'nifty_bank', name=u'Nifty Bank', closing_price=27085.95, expiry=None, strike_price=None, tick_size=None, lot_size=None, instrument_type=u'INDEX', isin=None)
ipdb> ![screen shot 2019-02-03 at 6 14 25 pm](https://user-images.githubusercontent.com/1237354/52176903-94d9c200-27df-11e9-9e97-8c4a66d594af.png) o = u.search_instruments('NSE_INDEX', 'NIFTY_BANK')
ipdb> o
[]
screen shot 2019-02-03 at 6 14 25 pm

My websocket connection keeps on closing every 1 minutes.

= connection is CONNECTING

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: 9Xv4qCwtS9uDndJVVtOnyw==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
User-Agent: Python/3.11 websockets/11.0.3
< HTTP/1.1 101 Switching Protocols
< Date: Tue, 10 Oct 2023 05:53:47 GMT
< Connection: upgrade
< Sec-WebSocket-Extensions: permessage-deflate
< Sec-WebSocket-Accept:
< Upgrade: WebSocket
< CF-Cache-Status: DYNAMIC
< Strict-Transport-Security: max-age=0; includeSubDomains
= connection is OPEN
Connection established
< PING '' [0 bytes]
PONG '' [0 bytes]
BINARY 7b 22 67 75 69 64 22 3a 20 22 73 6f 6d 65 67 75 ... 31 30 33 36 22 5d 7d 7d [497 bytes]
< BINARY 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e 45 37 ... 0a 18 a4 9c 98 c1 b1 31 [10243 bytes]
< BINARY 08 01 12 be 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 0a 18 b0 9c 98 c1 b1 31 [1736 bytes]
< BINARY 08 01 12 bd 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 dc 9e 98 c1 b1 31 [3408 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 88 a1 98 c1 b1 31 [4548 bytes]
< BINARY 08 01 12 b5 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 b4 a3 98 c1 b1 31 [3443 bytes]
< BINARY 08 01 12 b1 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 e1 a5 98 c1 b1 31 [573 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 06 18 8d a8 98 c1 b1 31 [3975 bytes]
< BINARY 08 01 12 b5 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 05 18 b8 aa 98 c1 b1 31 [2847 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 e4 ac 98 c1 b1 31 [3446 bytes]
< BINARY 08 01 12 b2 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 06 18 91 af 98 c1 b1 31 [2262 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 07 18 bd b1 98 c1 b1 31 [6248 bytes]
< BINARY 08 01 12 b2 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 e9 b3 98 c1 b1 31 [2873 bytes]
< BINARY 08 01 12 af 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 03 18 94 b6 98 c1 b1 31 [1136 bytes]
< BINARY 08 01 12 b5 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 c1 b8 98 c1 b1 31 [3423 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 0a 18 ed ba 98 c1 b1 31 [6280 bytes]
< PING '' [0 bytes]
PONG '' [0 bytes]
< BINARY 08 01 12 b0 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 05 18 99 bd 98 c1 b1 31 [572 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 c5 bf 98 c1 b1 31 [3983 bytes]
< BINARY 08 01 12 b2 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 f1 c1 98 c1 b1 31 [3977 bytes]
< BINARY 08 01 12 bd 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 03 18 9d c4 98 c1 b1 31 [2309 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 06 18 c9 c6 98 c1 b1 31 [1137 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 f5 c8 98 c1 b1 31 [5702 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 a1 cb 98 c1 b1 31 [3437 bytes]
< BINARY 08 01 12 ba 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 cd cd 98 c1 b1 31 [2287 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 25 18 f9 cf 98 c1 b1 31 [3989 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 0b 18 a5 d2 98 c1 b1 31 [5699 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 0b 18 d1 d4 98 c1 b1 31 [1727 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 fd d6 98 c1 b1 31 [3995 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 a8 d9 98 c1 b1 31 [2846 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 0b 18 d5 db 98 c1 b1 31 [3998 bytes]
< BINARY 08 01 12 b0 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 16 18 81 de 98 c1 b1 31 [1135 bytes]
< BINARY 08 01 12 b7 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 02 18 ac e0 98 c1 b1 31 [7416 bytes]
< BINARY 08 01 12 b3 04 0a 13 4e 53 45 5f 45 51 7c 49 4e ... 01 18 d8 e2 98 c1 b1 31 [4004 bytes]
< CLOSE 1000 (OK) [2 bytes]
= connection is CLOSING
CLOSE 1000 (OK) [2 bytes]
= connection is CLOSED


ConnectionClosedOK Traceback (most recent call last)
Cell In[41], line 45
43 nest_asyncio.apply()
44 loop = asyncio.get_event_loop()
---> 45 loop.run_until_complete(fetch_market_data(dfinstrument["Join"].to_list()))
46 #except Exception as e:
47 #logger_monitor("Exception when calling Main: %s\n" % e,True)
48 #continue
49 print("Trading End")

File ~\miniconda3\Lib\site-packages\nest_asyncio.py:90, in _patch_loop..run_until_complete(self, future)
87 if not f.done():
88 raise RuntimeError(
89 'Event loop stopped before Future completed.')
---> 90 return f.result()

File ~\miniconda3\Lib\asyncio\futures.py:203, in Future.result(self)
201 self.__log_traceback = False
202 if self._exception is not None:
--> 203 raise self._exception.with_traceback(self._exception_tb)
204 return self._result

File ~\miniconda3\Lib\asyncio\tasks.py:267, in Task.__step(failed resolving arguments)
263 try:
264 if exc is None:
265 # We use the send method directly, because coroutines
266 # don't have __iter__ and __next__ methods.
--> 267 result = coro.send(None)
268 else:
269 result = coro.throw(exc)

Cell In[32], line 42, in fetch_market_data(Instrument)
40 await asyncio.sleep(60 - time() % 60)
41 else:
---> 42 message = await websocket.recv()
43 decoded_data = decode_protobuf(message)
44 # Convert the decoded data to a dictionary

File ~\miniconda3\Lib\site-packages\websockets\legacy\protocol.py:568, in WebSocketCommonProtocol.recv(self)
564 return None # type: ignore
565 else:
566 # Wait until the connection is closed to raise
567 # ConnectionClosed with the correct code and reason.
--> 568 await self.ensure_open()
570 # Pop a message from the queue.
571 message = self.messages.popleft()

File ~\miniconda3\Lib\site-packages\websockets\legacy\protocol.py:935, in WebSocketCommonProtocol.ensure_open(self)
932 return
934 if self.state is State.CLOSED:
--> 935 raise self.connection_closed_exc()
937 if self.state is State.CLOSING:
938 # If we started the closing handshake, wait for its completion to
939 # get the proper close code and reason. self.close_connection_task
940 # will complete within 4 or 5 * close_timeout after close(). The
941 # CLOSING state also occurs when failing the connection. In that
942 # case self.close_connection_task will complete even faster.
943 await asyncio.shield(self.close_connection_task)

ConnectionClosedOK: received 1000 (OK); then sent 1000 (OK)

Authentication not working in Native Python Library

For auth we need to call:
api_response = api_instance.token(api_version, code=code, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, grant_type=grant_type)

For this, we need the code parameter, which we should be getting from authorize function call:

api_instance.authorize(client_id, redirect_uri, api_version, state=state, scope=scope)

But this will always return None. So where are we suppose to get the code value? This works perfect in browser with redirection url. But not with official Python library.

raise requests.HTTPError(response.text) HTTPError: {"message":"Forbidden"}

def fetchLtp(ticker):
    """extracts historical data and outputs in the form of dataframe"""
    tick = u.get_instrument_by_symbol('NSE_EQ', "DEEPAKNTR")
    data = u.get_live_feed(tick, LiveFeedType.LTP)
    pp = data["data"]["ltp"]
    return pp

when I am trying to execute ltp code, I am getting the above mentioned error

API Trading

Hi,

I want to write a customized algo for trading. But, it seems the API_trading app is not opened for all. can you pls mention when it will be opened? or do you open it up based on special requests?

Also, I couldn't find the pricing for API usage and historical data. pls mentioned pricing as well.

Thanks

Live Feed of NSE_EQ not giving proper data when bond is present

When i subscribe the Live Feed data for NSE EQ of "IDFCFIRSTB" IDFC First Bank Share, I am getting its bond equity feed not the share equity trading feed, this is happening because the bond is having same name and its showing as equity, Similarly i am facing this issue in the NTPC, REC etc the companies in which bond are issued i am not able to get there equity feeds.

This is the feed i am receiving for IDFC FIRST BANK for NSE EXCHANGE
{
timestamp: '1615975102000',
exchange: 'NSE_EQ',
symbol: 'IDFCFIRSTB',
ltp: '10430', <- this price is of its listed bond not of the share
close: '10500' <- this price is of its listed bond not of the share
}

exchange | token | parent_token | symbol | name | closing_price | expiry | strike_price | tick_size | lot_size | instrument_type | isin |  
NSE_EQ | 11184 |   | IDFCFIRSTB | IDFC FIRST BANK LIMITED | 63.4 |   |   | 5 | 1 | EQUITY | INE092T01019
NSE_EQ | 10814 |   | IDFCFIRSTB | BOND 9% 2021 TR-1 SR-I | 5150 |   |   | 1 | 1 | EQUITY | INE092T08CK9
NSE_EQ | 10817 |   | IDFCFIRSTB | BOND 0% 2021 TR-1 SR-II | 11096 |   |   | 1 | 1 | EQUITY | INE092T08CL7
NSE_EQ | 10908 |   | IDFCFIRSTB | BOND 8.70% 2022 TR-2 SR-I |   |   |   | 1 | 1 | EQUITY | INE092T08CM5
NSE_EQ | 10914 |   | IDFCFIRSTB | BOND 0% 2022 TR-2 SR-II | 10680 |   |   | 1 | 1 | EQUITY | INE092T08CN3
NSE_EQ | 10917 |   | IDFCFIRSTB | BOND 8.43% 2022 TR-3 SR-I |   |   |   | 1 | 1 | EQUITY | INE092T08CO1
NSE_EQ | 10920 |   | IDFCFIRSTB | BOND 0% 2022 TR-3 SR-II |   |   |   | 1 | 1 | EQUITY | INE092T08CP8

As you can see here, symbol for the IDFCFIRSTB is same for bonds, How to get the feed for the Share since the name is same

subscription to instruments with '&' in 'symbol'

subscription to instruments with '&' in 'symbol' give error. Even after converting the & -> %26, The error is there this problem persists.

Unsubscribing - M%26M
WARNING:root:Cannot find symbol [nse_eq:m%26m] in master contract
Traceback (most recent call last):
File "D:\Projects\PTrade\test.py", line 162, in
unsubscribe_to_all_nifty_stocks()
File "D:\Projects\PTrade\test.py", line 82, in unsubscribe_to_all_nifty_stocks
upstox.unsubscribe(upstox.get_instrument_by_symbol('NSE_EQ', n), LiveFeedType.Full)
File "C:\Program Files\Python36\lib\site-packages\upstox_api\api.py", line 594, in unsubscribe
raise TypeError("Required parameter instrument not of type Instrument")
TypeError: Required parameter instrument not of type Instrument

"errorCode":"UDAPI100060","message":"Resource not Found

autologin.py

      import aconfig as l
      import urllib.parse 
      import pandas as pd 
      import requests
      from selenium import webdriver 
      import time
      import os
      from pyotp import TOTP
      
      def autologin():
          print('hello')
          browser = webdriver.Chrome()
          redirecturl = urllib.parse.quote(l.rurl,safe="")
          print (redirecturl)
          browser.get('https://api-v2.upstox.com/Login/authorization/dialog?client_id='+l.apiKey + '&redirect_uri=' + redirecturl)
          browser.implicitly_wait(99999999999)
          mobilenumber = browser.find_element("xpath", '/html/body/main/div/div[3]/div/div/div[2]/div[1]/div/div/div[2]/form/div/div/div/div/input').click()
          mobilenumber.send_keys(l.mobilenumber)
          browser.implicitly_wait(5)
          bclick = browser.find_element("xpath", '/html/body/main/div/div[3]/div/div/div[2]/div[1]/div/div/div[2]/form/div/button').click()
          browser.implicitly_wait(5)
          totp = TOTP (l.totp)
          token = totp.now()
          token=int(token)
          print(token)
          otpnumber = browser.find_element_by_id("otpNum")
          otpnumber.send_keys(token)
          browser.implicitly_wait(5)
          bclick= browser.find_element("xpath", '/html/body/main/div/div[3]/div/div/div[2]/div[1]/div/div/div[2]/form/div[2]/button').click()
          browser.implicitly_wait(5)
          browser.implicitly_wait(5)
          otpnumber = browser.find_element_by_id("pinCode")
      
      
          otpnumber.send_keys(l.key)
          browser.implicitly_wait(5)
          bclick= browser.find_element ("xpath", '/html/body/main/div/div[3]/div/div[1]/div[2]/div[1]/div/div/div[2]/form/button').click() 
          time.sleep(5)
          temp_token=browser.current_url.split('code=')[1][:6]
          # Save in Database or text File
          print('temp_token', temp_token)
      
          
      autologin()

aconfig.py

    apiKey = '*****************'
    secretKey = '**************'
    rurl = 'https://127.0.0.1' 
    mobilenumber='**************'
    totp='********************'
    token_df=None 
    key=********

it comes an error like this
{"status":"error","errors":[{"errorCode":"UDAPI100060","message":"Resource not Found.","propertyPath":null,"invalidValue":null,"error_code":"UDAPI100060","property_path":null,"invalid_value":null}]}

image

I want to get my access token how do I get ?

give a sample code for this ?

Error at get_market_data_feed

from __future__ import print_function
import time
import upstox_client
from upstox_client.rest import ApiException
from pprint import pprint

# Configure OAuth2 access token for authorization: OAUTH2
configuration = upstox_client.Configuration()
configuration.access_token = 'YOUR_ACCESS_TOKEN'

# create an instance of the API class
api_instance = upstox_client.WebsocketApi(upstox_client.ApiClient(configuration))
api_version = 'api_version_example' # str | API Version Header

try:
    # Market Data Feed
    api_instance.get_market_data_feed(api_version)
except ApiException as e:
    print("Exception when calling WebsocketApi->get_market_data_feed: %s\n" % e)

NOTE : i followed the code which has been given in this GitHub repo exactly
version of library -> 2.0
python version -> 3.9.13

ERROR

URLSchemeUnknown: Not supported URL scheme wss

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.