def api_submit(request): if get_tournament_state() == TOURNAMENT_STATE.BEFORE: return HttpResponseBadRequest("Tournament is not open yet.") if get_tournament_state() == TOURNAMENT_STATE.CLOSED: return HttpResponseBadRequest("Tournament has closed.") api_token = request.META.get("HTTP_AUTHORIZATION", "") if api_token == "": return HttpResponseUnauthorized("API token not provided or empty") try: user = User.objects.get(api_token=api_token) except User.DoesNotExist: return HttpResponseUnauthorized("Invalid API token") try: bot_code = request.FILES["bot_code"].read().decode("utf8") except KeyError: bot_code = request.POST["bot_code"] try: verifier.verify_bot_code(bot_code) except verifier.InvalidBotCode as e: return HttpResponseBadRequest("Bot code not valid") create_bot(user, request.POST["bot_name"], bot_code) return JsonResponse({})
def test_code_with_get_next_move_having_extra_param(self): code = """ def get_next_move(move_list, beard): pass """ with self.assertRaisesRegexp(verifier.InvalidBotCode, "may only have"): verifier.verify_bot_code(code)
def test_code_with_get_next_move_missing_required_param(self): code = """ def get_next_move(token, state): pass """ with self.assertRaisesRegexp(verifier.InvalidBotCode, "must have either"): verifier.verify_bot_code(code)
def test_code_with_syntax_error(self): code = """ def get_next_move() pass """ with self.assertRaisesRegexp(verifier.InvalidBotCode, "contains a SyntaxError"): verifier.verify_bot_code(code)
def test_code_missing_get_next_move(self): code = """ def get_move(board): pass """ with self.assertRaisesRegexp(verifier.InvalidBotCode, "does not define"): verifier.verify_bot_code(code)
def test_code_with_top_level_definition(self): code = """ x = 123 def get_next_move(board): pass """ with self.assertRaisesRegexp(verifier.InvalidBotCode, "not an import"): verifier.verify_bot_code(code)
def test_valid_code(self): code = """ # This is a comment import random from botany_noughtsandcrosses import game def get_available_moves(board): return game.available_moves(board) def get_next_move(board): return random.choice(get_available_moves(board)) """ verifier.verify_bot_code(code)
def api_submit(request): if datetime.now(timezone.utc) > settings.BOTANY_TOURNAMENT_CLOSE_AT: return HttpResponseBadRequest("Tournament has closed") user = get_object_or_404(User, api_token=request.POST["api_token"]) try: bot_code = request.FILES["bot_code"].read().decode("utf8") except KeyError: bot_code = request.POST["bot_code"] try: verifier.verify_bot_code(bot_code) except verifier.InvalidBotCode as e: return HttpResponseBadRequest("Bot code not valid") create_bot(user, request.POST["bot_name"], bot_code) return JsonResponse({})
def read_and_validate_bot_code(path): try: with open(path) as f: bot_code = f.read() except FileNotFoundError: raise click.UsageError(f"Could not read bot code from {path}") try: verifier.verify_bot_code(bot_code) except verifier.InvalidBotCode as e: msg = f""" Bot code at {path} does not conform to the bot specification: {e} Refer to the Botany User Guide for more details """.strip() raise click.UsageError(msg) return bot_code