From 750ece0cfa0d507774a0e4c71ba169914b0ed3aa Mon Sep 17 00:00:00 2001 From: kiat-ebed Date: Mon, 21 Sep 2020 22:12:08 +0100 Subject: [PATCH 1/5] added key to the lin spec --- bridgeDealConverter/bridgeDealConverter-api.py | 2 +- bridgeDealConverter/bridgeDealConverter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bridgeDealConverter/bridgeDealConverter-api.py b/bridgeDealConverter/bridgeDealConverter-api.py index eee8469..491be43 100644 --- a/bridgeDealConverter/bridgeDealConverter-api.py +++ b/bridgeDealConverter/bridgeDealConverter-api.py @@ -140,7 +140,7 @@ def lambda_handler(event, context): elif output == "rbn": b = {B["rbn"][0]:B["rbn"][1]} elif output == "lin": - b = B["lin"][1] + b = {"md":B["lin"][1]} return { 'statusCode': 200, diff --git a/bridgeDealConverter/bridgeDealConverter.py b/bridgeDealConverter/bridgeDealConverter.py index 7e04f6c..773ed31 100755 --- a/bridgeDealConverter/bridgeDealConverter.py +++ b/bridgeDealConverter/bridgeDealConverter.py @@ -136,7 +136,7 @@ elif output == "rbn": b = {B["rbn"][0]:B["rbn"][1]} elif output == "lin": - b = B["lin"][1] + b = {"md":B["lin"][1]} print({ 'statusCode': 200, From 44d94afb12afaff4707d69e1af050e121373fe6a Mon Sep 17 00:00:00 2001 From: Kiat Date: Tue, 22 Sep 2020 17:24:46 +0100 Subject: [PATCH 2/5] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9618389 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Bridge Hackathon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From c08314592f648a3eae650441dc99c59be38ce038 Mon Sep 17 00:00:00 2001 From: kiat-ebed Date: Tue, 29 Sep 2020 01:51:48 +0100 Subject: [PATCH 3/5] Refactored the app for Zappa and local testing with Flask --- dealConverter/dealConverter.py | 165 ++++++++++++++++++++++++++++++ dealConverter/zappa_settings.json | 12 +++ 2 files changed, 177 insertions(+) create mode 100644 dealConverter/dealConverter.py create mode 100644 dealConverter/zappa_settings.json diff --git a/dealConverter/dealConverter.py b/dealConverter/dealConverter.py new file mode 100644 index 0000000..116b761 --- /dev/null +++ b/dealConverter/dealConverter.py @@ -0,0 +1,165 @@ +from flask import Flask, request, jsonify, make_response +from sys import argv +from re import sub + +app = Flask(__name__) + +@app.route('/') +def index(): + return "Hello, world!", 200 + +# We only need this for local development. +if __name__ == '__main__': + app.run() + +@app.route('/api',methods=['POST']) +def dealConverter(): + event = request.get_json() + + # get presented deal in UUID format + UUID = event.get('uuid') + + # get requested output + output = event.get('output') + + # int as Hex + I=int(UUID,16) + + # Total number of possible deals = 52!/(13!)^4 + K = int("0xAD55E315634DDA658BF49200",16) + + # initialising suits and card counts + N, E, S, W = 13, 13, 13, 13 + C = 52 + + # cards = A K Q J T 9 8 7 6 5 4 3 2 + cards="AKQJT98765432" + + # suits [spades, hearts, diamonds, clubs] + suits = [[(52-4*i) for i in range(13)], [(51-4*i) for i in range(13)], [(50-4*i) for i in range(13)], + [(49-4*i) for i in range(13)]] + + # initialise the suits + suits[0].insert(0,"S") + suits[1].insert(0,"H") + suits[2].insert(0,"D") + suits[3].insert(0,"C") + + # initialise the seats: north, east, south, west + seats = [["N"], ["E"], ["S"], ["W"]] + + # initialize the deck which is SA, HA, DA, CA, SK, HK, DK, CK, SQ, .... etc + deck = ["" for i in range(52)] + + # + # Algorithm as explained by Richard Pavlicek + # http://www.rpbridge.net/7z68.htm + # + # map the UUID into the deck, where the SA position (0) is replaced by the seat that holds it + # Example = ["N", "E", "E", "S", "W", .....etc] + for C in range(52, 0, -1): + X = K*N/C + # is this card Norths? + if I < K*N/C and N > 0: + X = K*N/C + # print("C=",C ,"; N=",N, "K*N/C=", X) + N = N-1 + K = X + deck[C-1]="N" + seats[0].append(C) + # ...Easts? + elif I < K*(N+E)/C and E > 0: + I = I - K*N/C + X = K*E/C + # print("C=",C ,"; E=",E, "K*E/C=", X) + E = E-1 + K = X + deck[C-1]="E" + seats[1].append(C) + # ...South's? + elif I < K*(N+E+S)/C and S > 0: + I = I - K*(N+E)/C + X = K*S/C + # print("C=",C ,"; S=",S, "K*S/C=", X) + S = S-1 + K = X + deck[C-1]="S" + seats[2].append(C) + # ...West's? + elif I < K*(N+E+S+W)/C and W > 0: + I = I - K*(N+E+S)/C + X = K*W/C + # print("C=",C ,"; W=",W, "K*W/C=", X) + W = W-1 + K = X + deck[C-1]="W" + seats[3].append(C) + + else: + print(".") # not needed if the elif cases are done correctly + + # formats + # single string + # N:.AT87.A852.943.Q6 E:.QJ.KJ93.QJ7.J752 S:.K6432.4.KT652.83 W:.95.QT76.A8.AKT94 + # key/value + B = {} + + # Human (readable) + B["human"] = {} + # PBN + B["pbn"] = {} + B["pbn"][0] = "Deal" + # RBN (Richard's Bridge Notation) - http://www.rpbridge.net/7a12.htm + B["rbn"] = {} + B["rbn"][0] = "H" + # LIN + B["lin"] = {} + # B["lin"][0] = "H" + + + # cycle the seats + A = ["" for i in range(4)] + # special array for LIN as they have suit names before + L = ["" for i in range(4)] + + for k in range(4): + suit = ["" for i in range(4)] + # suits + A[k] = ''.join([seats[k][0],":"]) + for j in range(4): + suit[j]="" + for i in range(1,14): + try: + suit[j] += cards[suits[j].index(seats[k][i])-1] + except ValueError: + a = "" + A[k] = A[k] + "." + suit[j] + L[k] = L[k] + suits[j][0] + suit[j] + B["human"][seats[k][0]] = sub(r'^.{3}','',A[k]) + B["pbn"][seats[k][0]] = sub(r'^.{3}','',A[k]) + B["lin"][seats[k][0]] = L[k] + + B["pbn"][1] = ''.join(["N:",B["pbn"]["N"],' ',B["pbn"]["E"],' ',B["pbn"]["S"],' ',B["pbn"]["N"]]) + B["rbn"][1] = ''.join(["N:",B["pbn"]["N"],':',B["pbn"]["E"],':',B["pbn"]["S"],':',B["pbn"]["N"]]) + B["lin"][1] = ','.join([B["lin"]["S"],B["lin"]["W"],B["lin"]["N"],B["lin"]["E"]]) + + # print formats + + b = "" + if output == "human": + b = B["human"] + elif output == "pbn": + b = {B["pbn"][0]:B["pbn"][1]} + elif output == "rbn": + b = {B["rbn"][0]:B["rbn"][1]} + elif output == "lin": + b = {"md":B["lin"][1]} + + response_body = { + 'statusCode': 200, + 'body': b + } + + result = make_response(jsonify(response_body), 200) + + return result \ No newline at end of file diff --git a/dealConverter/zappa_settings.json b/dealConverter/zappa_settings.json new file mode 100644 index 0000000..9b228f5 --- /dev/null +++ b/dealConverter/zappa_settings.json @@ -0,0 +1,12 @@ +{ + "dev": { + "app_function": "dealConverter.app", + "aws_region": "eu-west-2", + "profile_name": "default", + "project_name": "dealconverter", + "runtime": "python3.8", + "s3_bucket": "zappa-bshl8wgdy", + "domain": "converter.aws.globalbridge.app", + "certificate_arn": "arn:aws:acm:us-east-1:613256704476:certificate/b96a2ffb-d1a5-4d84-af5e-e646c1027cc9" + } +} From c3927187d39af20fab04d53074db95bb4ec5913b Mon Sep 17 00:00:00 2001 From: kiat-ebed Date: Tue, 29 Sep 2020 02:01:37 +0100 Subject: [PATCH 4/5] renamed folder --- {dealConverter => deploy-aws}/dealConverter.py | 0 {dealConverter => deploy-aws}/zappa_settings.json | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {dealConverter => deploy-aws}/dealConverter.py (100%) rename {dealConverter => deploy-aws}/zappa_settings.json (100%) diff --git a/dealConverter/dealConverter.py b/deploy-aws/dealConverter.py similarity index 100% rename from dealConverter/dealConverter.py rename to deploy-aws/dealConverter.py diff --git a/dealConverter/zappa_settings.json b/deploy-aws/zappa_settings.json similarity index 100% rename from dealConverter/zappa_settings.json rename to deploy-aws/zappa_settings.json From 580acb99ba26090be98c73f2da469ee01c85e7b9 Mon Sep 17 00:00:00 2001 From: kiat-ebed Date: Tue, 29 Sep 2020 02:12:15 +0100 Subject: [PATCH 5/5] added README and requirements.txt --- deploy-aws/README.md | 27 +++++++++++++++++++++++++++ deploy-aws/requirements.txt | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 deploy-aws/README.md create mode 100644 deploy-aws/requirements.txt diff --git a/deploy-aws/README.md b/deploy-aws/README.md new file mode 100644 index 0000000..f16cb78 --- /dev/null +++ b/deploy-aws/README.md @@ -0,0 +1,27 @@ +# Deploying Converter (API) on AWS as a Lambda function + +## Overview +New converter python code deployed with Flask on AWS or locally + +### Prep python environment +Create a virtual environment +``` +cd deploy-aws +virtualenv venv +source ./venv/bin/activate +``` + +Install modules including zappa, Flask +```pip3 install -r requirements.txt``` + +Initialize zappa and configure auth to AWS +TODO + +Deploy to AWS +```zappa update dev``` (if not yet deployed zappa deploy dev) + +To re(certify) the ACM SSL cert created +```zappa certify``` + +Watching the logs +```zappa tail``` \ No newline at end of file diff --git a/deploy-aws/requirements.txt b/deploy-aws/requirements.txt new file mode 100644 index 0000000..d3fe603 --- /dev/null +++ b/deploy-aws/requirements.txt @@ -0,0 +1,2 @@ +Flask==1.1.2 +zappa==0.51.0