def delete_course(id): """Delete a course :return: A confirmation message (see the challenge notes for examples) """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- None """ # YOUR CODE HERE ind = -1 for i in range(0, len(courses)): if str(courses[i]["id"]) == (id): ind = i if ind == -1: message = "Course " + str(id) + " does not exist" response = app.response_class(response=json.dumps({"message": message}), status=400, mimetype='application/json') return response courses.remove(courses[ind]) message = "The specified course was deleted" response = app.response_class(response=json.dumps({"message": message}), status=200, mimetype='application/json') return response
def update_course(id): """Update a a course. :param int id: The record id. :return: The updated course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the PUT body fields, including checking against the id in the URL """ # YOUR CODE HERE content = request.get_json() if (id not in courses): response = app.response_class(status=400, response="Id does not match payload", mimetype='application/json') else: courses[id] = content now = datetime.datetime.now() courses[id]['date_updated'] = now.strftime("%Y-%m-%d %H:%M:%S") response = app.response_class(status=200, response=json.dumps(courses), mimetype='application/json') return response
def delete_course(id): """Delete a course :return: A confirmation message (see the challenge notes for examples) """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- None """ # YOUR CODE HERE courses = list(filter(lambda x: x["id"] == id, data.load_data())) if len(courses) >= 1: courses = list(filter(lambda x: x["id"] != id, data.load_data())) with open("./json/course.json", "w") as outfile: json.dump(courses, outfile) msg = "The specified course was deleted" response = app.response_class(response=json.dumps(msg), status=200, mimetype='application/json') else: msg = {"error": f"Course {id} does not exist"} response = app.response_class(response=json.dumps(msg), status=404, mimetype='application/json') return response
def get_course(id): """Get a course by id. :param int id: The record id. :return: A single course (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for not using a linear scan on your data structure. """ # YOUR CODE HERE ret = {} if (id not in courses): response = app.response_class(status=404, response="Course not found", mimetype='application/json') else: ret["data"] = courses[id] response = app.response_class(status=200, response=json.dumps(ret), mimetype='application/json') return response
def create_course(): """Create a course. :return: The course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the POST body fields """ # YOUR CODE HERE content = request.get_json() if ('title' not in content or 'price' not in content or 'on_discount' not in content): response = app.response_class(status=400, response="Enter required data", mimetype='application/json') else: i = max(courses) + 1 courses[i] = content now = datetime.datetime.now() courses[i]['date_created'] = now.strftime("%Y-%m-%d %H:%M:%S") courses[i]['date_updated'] = now.strftime("%Y-%m-%d %H:%M:%S") response = app.response_class(status=201, response=json.dumps(courses), mimetype='application/json') return response
def get_course(id): """Get a course by id. :param int id: The record id. :return: A single course (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for not using a linear scan on your data structure. """ # YOUR CODE HERE course = list(filter(lambda x: x["id"] == id, data.load_data())) if len(course) == 1: response = app.response_class(response=json.dumps(course[0]), status=200, mimetype='application/json') else: msg = {"error": f"Course {id} does not exist"} response = app.response_class(response=json.dumps(msg), status=404, mimetype='application/json') return response
def update_course(id): """Update a a course. :param int id: The record id. :return: The updated course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the PUT body fields, including checking against the id in the URL """ # YOUR CODE HERE if request.method == 'PUT': jsonf = request.get_json() description = jsonf['description'] discountprice = jsonf['discount_price'] title = jsonf['title'] price = jsonf['price'] imagepath = jsonf['image_path'] discount = jsonf['on_discount'] idup = jsonf['id'] ind = -1 for i in range(0, len(courses)): if str(courses[i]["id"]) == str(idup): ind = i if ind == -1: message = "The id does not match the payload" response = app.response_class(response=json.dumps( {"message": message}), status=400, mimetype='application/json') return response if isinstance(description, str) and len(description) <= 255: if isinstance(discountprice, int): if isinstance(title, str) and len(title) <= 100 and len(title) >= 5: if isinstance(price, int) and len(imagepath) <= 100: if isinstance(discount, bool): courses[ind]["description"] = description courses[ind]["discount_price"] = discountprice courses[ind]["title"] = title courses[ind]["price"] = price courses[ind]["image_path"] = imagepath courses[ind]["on_discount"] = discount response = app.response_class( response=json.dumps({"data": courses[ind]}), status=200, mimetype='application/json') return response message = "Cannot update the course. Check the information provided" response = app.response_class(response=json.dumps({"message": message}), status=400, mimetype='application/json') return response
def create_course(): """Create a course. :return: The course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the POST body fields """ # YOUR CODE HERE if request.method == 'POST': jsonf = request.get_json() description = jsonf['description'] discountprice = jsonf['discount_price'] title = jsonf['title'] price = jsonf['price'] imagepath = jsonf['image_path'] discount = jsonf['on_discount'] maxid = -1 for i in courses: if maxid < i["id"]: maxid = i["id"] if isinstance(description, str) and len(description) <= 255: if isinstance(discountprice, int): if isinstance(title, str) and len(title) <= 100 and len(title) >= 5: if isinstance(price, int) and len(imagepath) <= 100: if isinstance(discount, bool): data = {} data["description"] = description data["discount_price"] = discountprice data["title"] = title data["price"] = price data["image_path"] = imagepath data["on_discount"] = discount data["id"] = maxid + 1 maxid = maxid + 1 courses.append(data) response = app.response_class( response=json.dumps({"data": data}), status=201, mimetype='application/json') return response message = "Cannot create the course. Check the information provided" response = app.response_class(response=json.dumps({"message": message}), status=400, mimetype='application/json') return response
def foundation_versions(): Body = { "versions": [ { "api_id": "opencde-foundation", "version_id": "1.0", "detailed_version": "https://github.com/BuildingSMART/opencde-foundation-API/tree/v1.0", }, # { # "api_id": "bcf", # "version_id": "2.1", # "detailed_version": "https://github.com/buildingSMART/BCF-API/tree/release_2_1", # "api_base_url": "http://127.0.0.1:5000/bcf/2.1" # }, { "api_id": "bcf", "version_id": "3.0", "detailed_version": "https://github.com/buildingSMART/BCF-API/tree/release_3_0", "api_base_url": "http://127.0.0.1:5000/bcf/3.0", }, ] } response = app.response_class(response=json.dumps(Body), status=200, mimetype="application/json") return response
def foundation_auth(): data = { "oauth2_auth_url": "http://127.0.0.1:5000/oauth/authorize", "oauth2_token_url": "http://127.0.0.1:5000/oauth/token", "supported_oauth2_flows": ["authorization_code"], } response = app.response_class(response=json.dumps(data), status=200, mimetype="application/json") return response
def delete_course(id): """Delete a course :return: A confirmation message (see the challenge notes for examples) """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- None """ # YOUR CODE HERE if (id not in courses): response = app.response_class(status=404, response="Course does not exist", mimetype='application/json') else: courses.pop(id) response = app.response_class(status=200, response="Specified course deleted", mimetype='application/json') return response
def get_courses(): """Get a page of courses, optionally filtered by title words (a list of words separated by commas". Query parameters: page-number, page-size, title-words If not present, we use defaults of page-number=1, page-size=10 :return: A page of courses (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for not using a linear scan, on your data structure, if title-words is supplied 2. Bonus points for returning resulted sorted by the number of words which matched, if title-words is supplied. 3. Bonus points for including performance data on the API, in terms of requests/second. """ # YOUR CODE HERE pagenumber = request.args.get("page-number", default=1, type=int) pagesize = request.args.get("page-size", default=10, type=int) titlewords = request.args.get("title-words", default="", type=str) final = [] if titlewords != "": for i in titlewords.split(','): res = search_title(str(i)) final.extend(res) else: final = courses total_res = len(final) total_pages = total_res / pagesize mets = {} mets["page_count"] = total_pages mets["page_number"] = pagenumber mets["page_size"] = pagesize mets["record_count"] = total_res start = pagesize * (pagenumber - 1) end = pagesize * pagenumber final = final[start:end] response = app.response_class(response=json.dumps({ "data": final, "metadata": mets }), status=200, mimetype='application/json') return response
def get_courses(): """Get a page of courses, optionally filtered by title words (a list of words separated by commas". Query parameters: page-number, page-size, title-words If not present, we use defaults of page-number=1, page-size=10 :return: A page of courses (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for not using a linear scan, on your data structure, if title-words is supplied 2. Bonus points for returning resulted sorted by the number of words which matched, if title-words is supplied. 3. Bonus points for including performance data on the API, in terms of requests/second. """ # YOUR CODE HERE content = request.get_json() ret = [] if ('page-size' not in content): size = 1 else: size = content['page-size'] if ('title-words' in content): for i in content['title-words']: print(i) if (i in words): for j in words[i]: ret.append(courses[j]) size -= 1 if (size == 0): break if (size == 0): break for i in courses: if (size == 0): break ret.append(courses[i]) size -= 1 response = app.response_class(status=200, response=json.dumps(ret), mimetype='application/json') return response
def issue_token(): try: code = request.form["code"] Headers = str.split(request.headers["Authorization"]) decode_header = base64.b64decode(Headers[1]).decode("utf-8") creds = decode_header.split(":") client_id = creds[0] # print(code, Headers, decode_header, creds, client_id) auth_code = OAuth2AuthorizationCode.query.filter_by(code=code).first() if auth_code: if auth_code.client_id == client_id: access_token = gen_salt(48) refresh_token = gen_salt(48) expires_in = 3600 OauthToken = OAuth2Token( client_id=auth_code.client_id, user_id=auth_code.user_id, access_token=access_token, refresh_token=refresh_token, expires_in=expires_in, scope=auth_code.scope, token_type="Bearer", ) db.session.add(OauthToken) db.session.commit() query = { "access_token": access_token, "refresh_token": refresh_token, "expires_in": expires_in, } response = app.response_class( response=json.dumps(query), status=200, mimetype="application/json", ) print(query) return response else: flash( "You are not authorized to access this client", category="danger", ) else: flash("Client not found", category="danger") except Exception as e: flash(e, category="danger") return render_template("oauth.html")
def update_course(id): """Update a a course. :param int id: The record id. :return: The updated course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the PUT body fields, including checking against the id in the URL """ # YOUR CODE HERE request_data = request.get_json() description = request_data.get('description', None) discount_price = request_data.get('discount_price', None) title = request_data.get('title', None) price = request_data.get('price', None) image_path = request_data.get('image_path', None) on_discount = request_data.get("on_discount", None) date_created = request_data.get("date_created", None) date_updated = str(datetime.datetime.now()) payload = { "description": description, "discount_price": discount_price, "title": title, "price": price, "image_path": image_path, "on_discount": on_discount, "date_updated": date_updated, "id": id } if validate_put_data(payload, request_data): courses = data.load_data() for item in courses: if item["id"] == id: item["description"]: description item["discount_price"]: discount_price item["title"]: title item["price"]: price item["image_path"]: image_path item["on_discount"]: on_discount item["date_updated"]: date_updated with open("./json/course.json", "w") as outfile: json.dump(courses, outfile) response = app.response_class(response=json.dumps({"data": payload}), status=200, mimetype='application/json') else: msg = {"message": "The id does match the payload"} response = app.response_class(response=json.dumps(msg), status=400, mimetype='application/json') return response
def get_courses(): """Get a page of courses, optionally filtered by title words (a list of words separated by commas". Query parameters: page-number, page-size, title-words If not present, we use defaults of page-number=1, page-size=10 :return: A page of courses (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for not using a linear scan, on your data structure, if title-words is supplied 2. Bonus points for returning resulted sorted by the number of words which matched, if title-words is supplied. 3. Bonus points for including performance data on the API, in terms of requests/second. """ # YOUR CODE HERE title_words = request.args.get('title-words') if title_words: # courses = list(filter(lambda x: any(title in x['title'] for title in title_words.split(',')) , data.load_data())) courses = [] for course in data.load_data(): if any(title.lower() in course["title"].lower() for title in title_words.split(',')): courses.append(course) else: courses = data.load_data() page_size = int(1 if not request.args.get('page-size') else request.args. get('page-size')) # courses = data.load_data() record_count = len(courses) page_count = int((record_count / page_size)) page_number = int(1 if not request.args.get('page-number') else request. args.get('page-number')) metadata = { "page_count": page_count, "page_number": page_number, "page_size": page_size, "record_count": record_count } if len(courses) >= 1: response = app.response_class(response=json.dumps({ "data": courses[(page_number - 1) * page_size:page_size * page_number], "metadata": metadata }), status=200, mimetype='application/json') else: response = app.response_class(response=json.dumps({ "data": [], "metadata": metadata }), status=200, mimetype='application/json') return response
def create_course(): """Create a course. :return: The course object (see the challenge notes for examples) :rtype: object """ """ ------------------------------------------------------------------------- Challenge notes: ------------------------------------------------------------------------- 1. Bonus points for validating the POST body fields """ # YOUR CODE HERE request_data = request.get_json() description = None if len(request_data.get('description',None)) >=255\ else request_data.get('description',None) discount_price = request_data.get('discount_price', None) title = request_data.get('title',None) if len(request_data.get('title',None)) >=5 and len(request_data.get('title',None)) <=100\ else None price = request_data.get('price', None) image_path = None if len(request_data.get('image_path',None)) >=100\ else request_data.get('image_path',None) on_discount = request_data.get("on_discount", None) id = max(data.load_data(), key=lambda x: x['id']) date_created = str(datetime.datetime.now()) date_updated = date_created payload = { "description": description, "discount_price": discount_price, "title": title, "price": price, "image_path": image_path, "on_discount": on_discount, "date_created": date_created, "date_updated": date_updated, "id": id['id'] + 1 } courses = data.load_data() if validate_post_data(payload): if payload["description"] != None and payload[ "title"] != None and payload["image_path"] != None: courses.append(payload) with open("./json/course.json", "w") as outfile: json.dump(courses, outfile) response = app.response_class(response=json.dumps( {"data": payload}), status=200, mimetype='application/json') else: msg = {"message": "The id does match the payload"} response = app.response_class(response=json.dumps(msg), status=400, mimetype='application/json') else: msg = {"message": "The id does match the payload"} response = app.response_class(response=json.dumps(msg), status=400, mimetype='application/json') return response