Skip to content

Commit

Permalink
Merge pull request #56 from liampauling/version_1_0
Browse files Browse the repository at this point in the history
Version 1 0
closes #55, #47, #45 and #43
  • Loading branch information
liampauling committed Apr 8, 2017
2 parents 0563477 + ab3dac3 commit cdc6383
Show file tree
Hide file tree
Showing 34 changed files with 1,220 additions and 473 deletions.
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Lightweight, super fast pythonic wrapper for [Betfair API-NG](http://docs.develo

[Documentation](https://github.com/liampauling/betfairlightweight/wiki)

Currently tested on Python 2.7, 3.4 and 3.5.
Currently tested on Python 2.7, 3.4, 3.5 and 3.6.

# installation

Expand Down Expand Up @@ -35,7 +35,7 @@ The library can then be used as follows:


```python
>>> event_types = trading.betting.list_event_types({'filter': {}})
>>> event_types = trading.betting.list_event_types()

[<EventTypeResult>, <EventTypeResult>, ..]
```
Expand All @@ -50,22 +50,30 @@ stream. The listener can hold a cache and push market_books/order_books out via
[Exchange Stream API](http://docs.developer.betfair.com/docs/display/1smk3cen4v3lu3yomq5qye0ni/Exchange+Stream+API)

```python
from betfairlightweight import StreamingMarketFilter, StreamingMarketDataFilter
from betfairlightweight.filters import (
streaming_market_filter,
streaming_market_data_filter,
)

betfair_socket = trading.streaming.create_stream(unique_id=2, description='Test Market Socket')
betfair_socket = trading.streaming.create_stream(
unique_id=2,
description='Test Market Socket',
)

market_filter = StreamingMarketFilter(
market_filter = streaming_market_filter(
event_type_ids=['7'],
country_codes=['IE'],
market_types=['WIN'],
)
market_data_filter = StreamingMarketDataFilter(
market_data_filter = streaming_market_data_filter(
fields=['EX_ALL_OFFERS', 'EX_MARKET_DEF'],
ladder_levels=3
)

betfair_socket.subscribe_to_markets(unique_id=12345,
market_filter=market_filter,
market_data_filter=market_data_filter)
betfair_socket.subscribe_to_markets(
unique_id=12345,
market_filter=market_filter,
market_data_filter=market_data_filter,
)
betfair_socket.start(async=False)
```
10 changes: 0 additions & 10 deletions appspec.yml

This file was deleted.

30 changes: 29 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1 +1,29 @@
build: off
build: off

environment:
matrix:
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x"

- PYTHON: "C:\\Python34"
PYTHON_VERSION: "3.4.x"

- PYTHON: "C:\\Python35"
PYTHON_VERSION: "3.5.x"

- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6.x"

init:
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"

install:
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- cmd: if %PYTHON_VERSION% == 2.7.x pip install enum34
- "pip install -r requirements.txt"
- "python setup.py install"

test_script:
- "pip install mock"
- "python setup.py test"

17 changes: 14 additions & 3 deletions betfairlightweight/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import logging

from .apiclient import APIClient
from .exceptions import BetfairError
from .streaming import StreamListener
from .filters import MarketFilter, StreamingMarketFilter, StreamingMarketDataFilter

from . import filters

__title__ = 'betfairlightweight'
__version__ = '0.9.10'
__version__ = '1.0.0'
__author__ = 'Liam Pauling'

# Set default logging handler to avoid "No handler found" warnings.
try: # Python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass

logging.getLogger(__name__).addHandler(NullHandler())
14 changes: 13 additions & 1 deletion betfairlightweight/apiclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@
class APIClient(BaseClient):

def __init__(self, username, password=None, app_key=None, certs=None, locale=None, cert_files=None):
super(APIClient, self).__init__(username, password, app_key=app_key, certs=certs, locale=locale, cert_files=cert_files)
"""
Creates API client for API operations.
:param str username: Betfair username
:param str password: Password for supplied username, if None will look in .bashprofile
:param str app_key: App Key for account, if None will look in .bashprofile
:param str certs: Directory for certificates, if None will look in /certs/
:param str locale: Exchange to be used, defaults to UK for login and global for api
:param str cert_files: Certificate and key files. If None will look in `certs`
"""
super(APIClient, self).__init__(
username, password, app_key=app_key, certs=certs, locale=locale, cert_files=cert_files
)

self.login = endpoints.Login(self)
self.keep_alive = endpoints.KeepAlive(self)
Expand Down
58 changes: 34 additions & 24 deletions betfairlightweight/baseclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
import datetime
import os

from .exceptions import PasswordError, AppKeyError, CertsError
from .exceptions import (
PasswordError,
AppKeyError,
CertsError,
)
from .compat import FileNotFoundError


class BaseClient(object):
"""
Base API client
"""

IDENTITY_URLS = collections.defaultdict(
lambda: 'https://identitysso.betfair.com/api/',
Expand All @@ -30,18 +37,14 @@ class BaseClient(object):

def __init__(self, username, password=None, app_key=None, certs=None, locale=None, cert_files=None):
"""
:param username:
Betfair username.
:param password:
Password for supplied username, if None will look in .bashprofile.
:param app_key:
App Key for account, if None will look in .bashprofile.
:param certs:
Directory for certificates, if None will look in /certs/
:param locale:
Exchange to be used, defaults to UK for login and global for api.
:param cert_files:
Certificate and key files. If None will look in `certs`
Creates base client for API operations.
:param str username: Betfair username
:param str password: Password for supplied username, if None will look in .bashprofile
:param str app_key: App Key for account, if None will look in .bashprofile
:param str certs: Directory for certificates, if None will look in /certs/
:param str locale: Exchange to be used, defaults to UK for login and global for api
:param str cert_files: Certificate and key files. If None will look in `certs`
"""
self.username = username
self.password = password
Expand All @@ -61,15 +64,18 @@ def __init__(self, username, password=None, app_key=None, certs=None, locale=Non
self.get_app_key()

def set_session_token(self, session_token):
"""Sets session token and new login time.
:param session_token: Session token from request.
"""
Sets session token and new login time.
:param str session_token: Session token from request.
"""
self.session_token = session_token
self._login_time = datetime.datetime.now()

def get_password(self):
"""If password is not provided will look in environment
variables for username+'password'
"""
If password is not provided will look in environment variables
for username+'password'.
"""
if self.password is None:
if os.environ.get(self.username+'password'):
Expand All @@ -78,8 +84,9 @@ def get_password(self):
raise PasswordError(self.username)

def get_app_key(self):
"""If app_key is not provided will look in environment
variables for username
"""
If app_key is not provided will look in environment
variables for username.
"""
if self.app_key is None:
if os.environ.get(self.username):
Expand All @@ -88,26 +95,29 @@ def get_app_key(self):
raise AppKeyError(self.username)

def client_logout(self):
"""Resets session token and login time.
"""
Resets session token and login time.
"""
self.session_token = None
self._login_time = None

@property
def session_expired(self):
"""Returns True if login_time not set or seconds since
"""
Returns True if login_time not set or seconds since
login time is greater than 200 mins.
"""
if not self._login_time or (datetime.datetime.now()-self._login_time).total_seconds() > 12000:
return True

@property
def cert(self):
"""The betfair certificates.
By default, it looks for the certificates in /certs/.
"""
The betfair certificates, by default it looks for the
certificates in /certs/.
:return: Path of cert files
:rtype: str
"""
if self.cert_files is not None:
return self.cert_files
Expand Down
73 changes: 62 additions & 11 deletions betfairlightweight/endpoints/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,95 @@

from .baseendpoint import BaseEndpoint
from .. import resources
from ..utils import clean_locals
from ..filters import time_range


class Account(BaseEndpoint):
"""
Account operations.
"""

URI = 'AccountAPING/v1.0/'
connect_timeout = 6.05

def get_account_funds(self, params=None, session=None):
def get_account_funds(self, wallet=None, session=None):
"""
Get available to bet amount.
:param str wallet: Name of the wallet in question
:param requests.session session: Requests session object
:rtype: resources.AccountFunds
"""
params = clean_locals(locals())
date_time_sent = datetime.datetime.utcnow()
method = '%s%s' % (self.URI, 'getAccountFunds')
response = self.request(method, params, session)
return self.process_response(response.json(), resources.AccountFunds, date_time_sent)

def get_account_details(self, params=None, session=None):
def get_account_details(self, session=None):
"""
Returns the details relating your account, including your discount
rate and Betfair point balance.
:param requests.session session: Requests session object
:rtype: resources.AccountDetails
"""
params = clean_locals(locals())
date_time_sent = datetime.datetime.utcnow()
method = '%s%s' % (self.URI, 'getAccountDetails')
response = self.request(method, params, session)
return self.process_response(response.json(), resources.AccountDetails, date_time_sent)

def get_account_statement(self, params=None, session=None):
def get_account_statement(self, locale=None, from_record=None, record_count=None, item_date_range=time_range(),
include_item=None, wallet=None, session=None):
"""
Get account statement.
:param str locale: The language to be used where applicable.
:param int from_record: Specifies the first record that will be returned
:param int record_count: Specifies the maximum number of records to be returned.
:param dict item_date_range: Return items with an itemDate within this date range.
:param str include_item: Which items to include, if not specified then defaults to ALL.
:param str wallet: Which wallet to return statementItems for.
:param requests.session session: Requests session object
:rtype: resources.AccountStatementResult
"""
params = clean_locals(locals())
date_time_sent = datetime.datetime.utcnow()
method = '%s%s' % (self.URI, 'getAccountStatement')
response = self.request(method, params, session)
return self.process_response(response.json(), resources.AccountStatementResult, date_time_sent)

def list_currency_rates(self, params=None, session=None):
def list_currency_rates(self, from_currency=None, session=None):
"""
Returns a list of currency rates based on given currency
:param str from_currency: The currency from which the rates are computed
:param requests.session session: Requests session object
:rtype: list[resources.CurrencyRate]
"""
params = clean_locals(locals())
date_time_sent = datetime.datetime.utcnow()
method = '%s%s' % (self.URI, 'listCurrencyRates')
response = self.request(method, params, session)
return self.process_response(response.json(), resources.CurrencyRate, date_time_sent)

def transfer_funds(self, params=None, session=None):
raise DeprecationWarning('As of 20/09/2016 AUS wallet has been removed, function still available for when '
'accounts are added in 2017.')
# date_time_sent = datetime.datetime.utcnow()
# method = '%s%s' % (self.URI, 'transferFunds')
# response = self.request(method, params, session)
# return self.process_response(response.json(), resources.TransferFunds, date_time_sent)
def transfer_funds(self, session=None):
"""
Transfer funds between the UK Exchange and other wallets
:param requests.session session: Requests session object
:rtype: resources.TransferFunds
"""
raise DeprecationWarning(
'As of 20/09/2016 AUS wallet has been removed, function still available for when '
'accounts are added in 2017.')

@property
def url(self):
Expand Down

0 comments on commit cdc6383

Please sign in to comment.