Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
407 changes: 407 additions & 0 deletions .pylintrc

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
language: python
python:
- "3.6"
# need to refactor to requirements/ setup
- '3.6'
install:
- pip install pipenv
- pipenv install --dev
- pip install pipenv
- pipenv install --dev
script:
# have pylint only show warnings and errors
# and ignore regular syntax errors
- pylint --disable=R,C nessie
- python -m unittest
- pylint --disable=R,C nessie
- python -m unittest
env:
global:
secure: kxSk6tcEhkvodjtDWCeJf/qI/vpRptfGZ6UmZ2G9GbHizXIVFleEmDmIZyWNnqRqv/ugdomlQhif0FRGod/e73MoIV9qa7kGWxuhExOhWzTo8tz0NzyyqLAFTmw5IB8m09H6MhJY9VpPygbpN0aWjOrrKdxRsj0ocVXPn3M62je6Om2ndSjMbynWrYutrhtijcp3BVka2vvjy6iNt9i0ZK/M0dsqqnuEgXe5uL4xKcmpvWu56QYcRhNky6qzxhh3Y1pyoBF7fA7fH2EnECCpnJaBFrdQFJzJ7VNAdoztX15G1E5KSudJu+qnKEw91RoQz9F9lmJgJJlJnYYMrjAqIE1h6eS560vFU1UGUZs1MU+FAWmRS1V09l+YKEtfmXg6NOO8tyzMuOEj1opwA95q1j17Ffg7E3SEs38ICpQYuK3LZUTlXELVsfPizR+70CQFDzWjI/OTIo6xi1gE1gWYUo3bHXIAn5jCJQiWNxMkaKavE+YXj/zWePJIeWlWbx1ZV0kZrhJ+V7Prlh86VYFPyI/jPdj+6Jc8IbvxDtsvCn2WZiHNJqtBTlcTT+kN5WShbq5bC+fMa++uffVe1nFy/cFEMaUX+tN2r/puzSPn4YCZ8BAHOuSKbUMEVk6j8ZKDBzqCMPxoYwFHdrrlbFC+lqEj38Z3+odV9Ni4CrquiUA=
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Install python 3.6.2 or greater
Setup virtual python environment

pip install pipenv
pipenv install
pipenv install --dev

To add packages

Expand All @@ -50,6 +50,11 @@ More info about pipenv: http://python-docs.readthedocs.io/en/latest/dev/virtuale
To run test package

pipenv run python ./src/atmRequests.py

To test locally

python3 -m unittest
pylint --disable=R,C nessie


## Deploying to pip
Expand Down
1 change: 1 addition & 0 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Customer 1 -- * Accounts

## Transactions

#### Bill
#### Desposit
#### Loan
#### Purchase
Expand Down
5 changes: 3 additions & 2 deletions nessie/atmRequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __validateParams(self, req):
if (paramsInvalid):
raise ATMValidationError(constants.atmInvalidFields)

def getAtms(self, lat=None, lng=None, rad=None):
def get_atms(self, lat=None, lng=None, rad=None):
reqUrl = "%s/atms" % self.baseUrl
par = self.__buildParams(lat, lng, rad)
self.__validateParams(par)
Expand All @@ -50,6 +50,7 @@ def getAtms(self, lat=None, lng=None, rad=None):

jsonAtms = r.json()
while ('next' in r.json()['paging']):
print(r.json())
reqUrl = "%s%s" % (self.baseUrl, r.json()['paging']['next'])
r = requests.get(reqUrl)

Expand All @@ -60,7 +61,7 @@ def getAtms(self, lat=None, lng=None, rad=None):

return self.__formatResponse(jsonAtms)

def getAtmById(self, idCode):
def get_atm(self, idCode):
reqUrl = "%s/atms/%s" % (self.baseUrl, idCode)
par = {'key': self.key}

Expand Down
2 changes: 1 addition & 1 deletion nessie/billRequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ def delete_bill(self, bill_id):
response = requests.delete(url)
if (response.status_code != 200):
raise NessieApiError(response)
return response.json()
return response.json()
28 changes: 28 additions & 0 deletions nessie/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

from .accountRequests import AccountRequests
from .atmRequests import ATMRequest
from .billRequests import BillRequest
from .branchRequests import BranchRequest
from .customerRequests import CustomerRequests
from .dataRequests import DataRequests

class Client():
def __init__(self, nessie_api_key=None):
# if no key is set then fetch from environment
if nessie_api_key is None:
try:
self.key = os.environ['NESSIE_API_KEY']
except KeyError as e:
raise Exception(e,"probably need to `export NESSIE_API_KEY=xxxxxxxxxxx`")
else:
self.key = nessie_api_key

self.account = AccountRequests(self.key)
self.atm = ATMRequest(self.key)
self.bill = BillRequest(self.key)
self.branch = BranchRequest(self.key)
self.data = DataRequests(self.key)
self.customer = CustomerRequests(self.key)


20 changes: 12 additions & 8 deletions nessie/customerRequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import json
import re

from nessie.models.customer import Customer
from nessie.utils.exceptions import CustomerValidationError, NessieApiError, AddressValidationError
from nessie import utils

from .models.customer import Customer
from .utils.exceptions import CustomerValidationError, NessieApiError, AddressValidationError
from . import utils

class CustomerRequests:

Expand Down Expand Up @@ -56,7 +57,6 @@ def get_customer_by_id(self, customer_id):
def create_customer(self, first_name: str, last_name: str, address):
if first_name is None or last_name is None:
raise CustomerValidationError(utils.constants.createCustomerMissingFields)

val_address = validate_address(address)
if val_address != utils.constants.success:
raise AddressValidationError(val_address)
Expand All @@ -66,7 +66,7 @@ def create_customer(self, first_name: str, last_name: str, address):
body = {
"first_name": first_name,
"last_name": last_name,
"address": address.to_dict()
"address": address
}
r = requests.post(utils.constants.customersUrl, headers=header, params=payload, data=json.dumps(body))
if r.status_code != 201:
Expand All @@ -80,17 +80,21 @@ def create_customer(self, first_name: str, last_name: str, address):
return created_customer

# Updates a customer's address based on CustomerId
# weird can only change address not first/last name
def update_customer(self, customer_id, new_address):
if customer_id is None:
raise CustomerValidationError(utils.constants.customerIdMissingField)


# needs check because otherwise
# if you set new city (or any one field of address)
# but not the rest it sets the other address fields to none
val_address = validate_address(new_address)
if val_address != utils.constants.success:
raise AddressValidationError(val_address)

header = {"Content-Type": "application/json"}
payload = {"key": self.key}
body = {"address": new_address.to_dict()}
body = {'address':new_address}
url = utils.constants.customersIdUrl % customer_id
r = requests.put(url, headers=header, params=payload, data=json.dumps(body))
if r.status_code != 202:
Expand All @@ -102,6 +106,6 @@ def update_customer(self, customer_id, new_address):
def validate_address(address):
if address is None:
return utils.constants.addressMissingField
elif re.fullmatch(r"^[0-9]{5}$", address.zipcode) is None:
elif re.fullmatch(r"^[0-9]{5}$", address['zip']) is None:
return utils.constants.addressValidationZipCode
return utils.constants.success
16 changes: 14 additions & 2 deletions nessie/dataRequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,23 @@ def __init__(self,api_key):

def delete_data(self, dataType:str):
url=f'{baseUrl}/data?type={dataType}&key={self.key}'
response = requests.delete(url)
# 'Connection':'close',
headers = { 'Content-type': 'application/json'}
response = requests.delete(url, headers=headers)
# status_code 200 denotes success
# status_code 404 denotes success, but no data to delete
if((response.status_code != 200) and (response.status_code!= 404)):
if(
(response.status_code != 200) and
(response.status_code != 204) and
(response.status_code != 404)):
raise NessieApiError(response)

# sometimes the response encoding is nothing
# rather than utf-8 so the response.json()
# will crash
if (response.encoding is None):
return {}

result = response.json()
return result

Expand Down
3 changes: 3 additions & 0 deletions nessie/models/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ def to_dict(self):
"state": self.state,
"zip": self.zipcode
}

def __eq__(self, other):
return self.to_dict() == other.to_dict()
2 changes: 1 addition & 1 deletion nessie/models/atm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def __init__(self, jsonData):
self.hours = jsonData.get('hours')
self.geocode = jsonData.get('geocode')

def toDict(self):
def to_dict(self):
returnDict = {}
returnDict['_id'] = self.atmId
returnDict['name'] = self.name
Expand Down
2 changes: 0 additions & 2 deletions nessie/models/bill.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
class Bill():

def __init__(self, _json):
print(_json)

self.bill_id = _json['_id']
self.status = _json["status"]
self.payee = _json["payee"]
Expand Down
3 changes: 3 additions & 0 deletions nessie/models/customer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ def to_dict(self):
"last_name": self.last_name,
"address": self.address.to_dict()
}

def __eq__(self, other):
return self.to_dict() == other.to_dict()
7 changes: 7 additions & 0 deletions nessie/models/transaction.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# underlying base class
# should not be directly used


class Transaction():
def __init__(self, _json):
pass
26 changes: 26 additions & 0 deletions nessie/models/transfer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

class Transfer():
def __init__(self, _json):
self.transfer_id = _json['_id']
self.type = _json['type']
self.transaction_date = _json['transaction_date']
self.status = ['status']
self.medium = _json['medium']
self.payer_id = _json['payer_id']
self.payee_id = _json['payee_id']
self.description = _json['description']

def to_dict(self):
return vars(self)


# """
# "_id": "string",
# "type": "p2p",
# "transaction_date": "2018-02-01",
# "status": "pending",
# "medium": "balance",
# "payer_id": "string",
# "payee_id": "string",
# "description": "string"
# """
69 changes: 69 additions & 0 deletions nessie/transactionRequests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# base class transaction
# should not be directly used
import requests
from abc import ABC
from nessie import utils

"""
Where transaction is a:
bill
deposit
loan
purchase
transfer
withdrawal

accounts/<account_id>/<transaction>s
GET fetch all transaction
POST create new transaction under <account_id>

transaction/<id>
GET fetch selected transaction
PUT update selected transaction
DELETE delete selected transaction
"""

class TransactionRequest(ABC):
def __init__(self, api_key, transaction_name:str, transaction_class):
self.key = api_key
self.base_url = utils.constants.baseUrl
self.transaction = transaction_name
self.transaction_class = transaction_class

# creates <transaction> under the provided account
def _create_transaction(self, account_id):
url = f'{self.base_url}/{account_id}/{self.transaction}?key={self.key}'
response = requests.post(url)
result = response.json()
return result

# return list of <Transaction> python objects from account
def _get_account_transactions(self, account_id):
url = f'{self.base_url}/accounts/{account_id}/{self.transaction}?key={self.key}'
response = requests.get(url)
result = response.json()

return result
# need to do work here to convert json into objects

def _get_transaction(self, transaction_id):
url = f'{self.base_url}/{self.transaction}/{transaction_id}?key={self.key}'
response = requests.get(url)
result = response.json()
return result

def _update_transaction(self, transaction_id):
url = f'{self.base_url}/{self.transaction}/{transaction_id}?key={self.key}'
response = requests.put(url)
result = response.json()
return result

def _delete_transaction(self, transaction_id):
url = f'{self.base_url}/{self.transaction}/{transaction_id}?key={self.key}'
response = requests.delete(url)
result = response.json()
return result




34 changes: 34 additions & 0 deletions nessie/transferRequest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import requests

from .transactionRequests import TransactionRequest
from .models.transfer import Transfer
from .utils.constants import baseUrl

class TransferRequests():
def __init__(self, api_key):
self.key = key

# a GET request for transfer with
# corresponding transfer_id
def get_transfer(self, transfer_id):
url = f'{baseUrl}/transfers/{transfer_id}?key={self.key}'
response = requests.get(url)
if (response.status_code != 200):
raise NessieApiError(response)

# GET request to fetch all transfer transactions
# from the specified account
def get_transfers_of_account(self, account_id):
url = f'{baseUrl}/accounts/{account_id}/transfers?key={self.key}'

def create_transfer(self,medium,payee_id,transaction_date, status,description):
url = f'{baseUrl}/accounts/{account_id}/transfers?key={self.key}'

body = {
'medium': medium,
'payee_id': payee_id,
'transaction_date': transaction_date,
'status': status,
'description':description
}
response = requests.post(url, json=body)
Loading