Skip to content

Commit

Permalink
Shipping (#2)
Browse files Browse the repository at this point in the history
* remove python27 from travis - no plans to use this ever again :)

* start on shipping api

* recover token from Royal mail

* making a shipping object attempting to post it currently gettting 500 errors, but unsure of correct way to create data, documentation is all over the place.

* quick and brutal configparser to keep our credentials safe.
Public github repo!
include it in our modules so we don't have to keep cutting and pasting.

* remove json import, don't think thats the issue

* working sending the data in as json=

create a delete call so we can cancel the shipments

* result.json() not result.json

put shipment label url

tools

makes a shipment, gets the label, deletes the label to test

* some docs with an example json object for shipping

use shipping type to initialise the object with and check - when we get to returns this will limit our options etc

* test webhook to rtd is working
  • Loading branch information
Bobspadger committed Mar 28, 2018
1 parent f55eeb6 commit f3c256f
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 5 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ python:
- 3.6
- 3.5
- 3.4
- 2.7

# Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install: pip install -U tox-travis
Expand Down
49 changes: 49 additions & 0 deletions docs/example_shipping.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Example Shipping object from Royal Mail
=======================================

.. code-block:: json
{
"shipmentType":"Delivery",
"service":{
"format":"P",
"occurrence":"1",
"offering":"TPN",
"type":"T",
"signature":"true",
"enhancements":["14"
]
},
"shippingDate":"2017-09-25",
"items":[
{
"count":1,
"weight":{
"unitOfMeasure":"g",
"value":100
}
}
],
"recipientContact":{
"name":"Joe Bloggs",
"complementaryName":"null",
"email":"joe.bloggs@royalmail.com"
},
"recipientAddress":{
"buildingName":"Cable and Engineering Limited",
"buildingNumber":"1",
"addressLine1":"Broadgate Circle",
"addressLine2":"Address line 2",
"addressLine3":"Address Line 3",
"postTown":"London",
"country":"GB",
"postCode":"EC1A 1BB"
},
"senderReference":"Senders Ref",
"departmentReference":"Dept Ref",
"customerReference":"Do not use",
"safePlace":"null"
}
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Welcome to Royal Mail Rest API's documentation!
readme
installation
usage
example_shipping
modules
contributing
authors
Expand Down
13 changes: 13 additions & 0 deletions docs/modules.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Modules
=======


.. automodule:: royal_mail_rest_api.api
:members:

.. automodule:: royal_mail_rest_api.tracking
:members:

.. automodule:: royal_mail_rest_api.shipping
:members:

5 changes: 5 additions & 0 deletions royal_mail_rest_api/credentials_example.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[royal_mail]
CLIENT_ID: ''
CLIENT_SECRET: ''
USERNAME: ''
PASSWORD_HASHED: ''
11 changes: 11 additions & 0 deletions royal_mail_rest_api/get_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import configparser


def return_credentials():
config = configparser.ConfigParser()
config.read('credentials.ini')
return config


if __name__ == '__main__':
return_credentials()
165 changes: 165 additions & 0 deletions royal_mail_rest_api/shipping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import requests
from royal_mail_rest_api.api import RoyalMailBaseClass


class ShippingApi(RoyalMailBaseClass):
token_url = '/shipping/v2/token'
post_domestic_url = '/shipping/v2/domestic'
delete_shipment_url = '/shipping/v2/'
put_shipment_label_url = '/shipping/v2/'

def __init__(self, client_id, client_secret, username, password):
"""
authenticate with the Shipping service.
Password is an SHA1 hashed password. The royal mail develop tools have an html file to do this for you
https://developer.royalmail.net/node/18564
https://developer.royalmail.net/sites/developer.royalmail.net/files/rmg_shipping_api_v2_rest_password_generator_0.zip
:param client_id:
:param client_secret:
:param username:
:param password:
"""

self.client_id = client_id
self.client_secret = client_secret
self.username = username
self.password = password
self._create_authentication_header()


def _create_authentication_header(self):
self.header = {'X-IBM-Client-Id': self.client_id,
'X-IBM-Client-Secret': self.client_secret,
'x-rmg-user-name': self.username,
'x-rmg-password': self.password,
'accept': 'application/json',
'content-type': 'application/json'}

def _create_token_header(self):
self.tokenheader = {'X-IBM-Client-Id': self.client_id,
'X-IBM-Client-Secret': self.client_secret,
'x-rmg-auth-token': self.token,
'accept': 'application/json'}

def get_token(self):
"""
Summary
=======
Method to get a JWT token
Description
-----------
This method will accept a DMO/NEOPOST user name and password. On successful validation of the user credential it will issue a JWT token to the user which will be valid for 4 hours. On subsequent requests, user will pass the JWT token in the request header.
:return:
"""


result = requests.get('{}{}'.format(self.url, self.token_url), headers=self.header)
result.raise_for_status()
result = result.json()
self.token = result['token']
self._create_token_header()

def post_domestic(self, data):
"""
Summary
=======
Operation to create a shipment
Description
-----------
This method will take a domestic shipment request in the body and on successful response, it will return the shipment numbers and item details.
:return:
"""
data = data
result = requests.post('{}{}'.format(self.url,self.post_domestic_url), json=data, headers=self.tokenheader)
result.raise_for_status()
return result.json()

def put_shipment(self):
"""
Summary
=======
updateShipment
Description
-----------
Update a shipment. Send a shipment request in body. On successful response, it will return shipment number and warnings. Service related information can not be updated, and if passed as part of request, it will be ignored.
:return:
"""
pass


def delete_shipment(self, shipment_number):
"""
Description
Delete a shipment. Send a shipment identifier in Url. Successful response will be 200 with no content.
:return:
"""
result = requests.delete('{}{}{}'.format(self.url, self.delete_shipment_url, shipment_number), headers=self.tokenheader)
result.raise_for_status()
return result.json()


def put_shipment_label(self, shipment_number):
"""
Description
-----------
This method returns a label for the shipment identifier passed in the url.
:return:
"""
result = requests.put('{}{}{}/label'.format(self.url, self.put_shipment_label_url,shipment_number), headers=self.tokenheader)
result.raise_for_status()
return result.json()

def post_manifest(self):
"""
Description
-----------
This method creates a shipping manifest
:return:
"""
pass

def put_manifest(self):
"""
Description
-----------
This method return a manifest label for a previously manifested shipment.
:return:
"""
pass



if __name__ == '__main__':
from royal_mail_rest_api.get_credentials import return_credentials
creds = return_credentials()

CLIENT_ID = creds['royal_mail']['CLIENT_ID']
CLIENT_SECRET = creds['royal_mail']['CLIENT_SECRET']
USERNAME = creds['royal_mail']['USERNAME']
PASSWORD_HASHED = creds['royal_mail']['PASSWORD_HASHED']

shipping_api = ShippingApi(CLIENT_ID, CLIENT_SECRET, USERNAME, PASSWORD_HASHED)
token = shipping_api.get_token()

0 comments on commit f3c256f

Please sign in to comment.