error = HTTPBadRequest() error.body = json.dumps(["Invalid JSON."]).encode("utf-8") error.content_type = "application/json" raise error def echo_query(request): return parser.parse(hello_args, request, locations=("query", )) @use_args(hello_args) def echo_use_args(request, args): return args @use_args({"value": fields.Int()}, validate=lambda args: args["value"] > 42) def echo_use_args_validated(request, args): return args @use_kwargs(hello_args) def echo_use_kwargs(request, name): return {"name": name} def echo_multi(request): return parser.parse(hello_multiple, request) def echo_many_schema(request): return parser.parse(hello_many_schema, request, locations=("json", ))
get_user, get_users, upsert_user, update_user, ) # Import Schemas from app.schemas.user import UserSchema @docs.register @doc(description="Retrieve users", security=security_params, tags=["users"]) @app.route(f"{config.API_V1_STR}/users/", methods=["GET"]) @use_kwargs( { "skip": fields.Int(default=0), "limit": fields.Int(default=100) }, locations=["query"], ) @marshal_with(UserSchema(many=True)) @jwt_required def route_users_get(skip=0, limit=100): current_user = get_current_user() if not current_user: abort(400, "Could not authenticate user with provided token") elif not check_if_user_is_active(current_user): abort(400, "Inactive user") elif not check_if_user_is_admin_or_superuser(current_user): abort(400, "The user doesn't have enough privileges") users = get_users(bucket, skip=skip, limit=limit)
return J(parser.parse(hello_args)) @app.route('/echo_query') def echo_query(): return J(parser.parse(hello_args, request, locations=('query', ))) @app.route('/echo_use_args', methods=['GET', 'POST']) @use_args(hello_args) def echo_use_args(args): return J(args) @app.route('/echo_use_args_validated', methods=['GET', 'POST']) @use_args({'value': fields.Int()}, validate=lambda args: args['value'] > 42) def echo_use_args_validated(args): return J(args) @app.route('/echo_use_kwargs', methods=['GET', 'POST']) @use_kwargs(hello_args) def echo_use_kwargs(name): return J({'name': name}) @app.route('/echo_multi', methods=['GET', 'POST']) def multi(): return J(parser.parse(hello_multiple))
class VolunteerRegistration(Resource): # pylint: disable=no-member, unused-argument, too-many-arguments, too-many-locals, no-self-use """Endpoints for registering a user or retrieving registered user(s).""" @use_kwargs(base.SimilarKwargs.GET) @verify({GIDS['dev']}) def get(self, uid, token, email): """Gets a user's entry by the model and their email. Gets all users by the model if email is omitted. :param uid: UID to authenticate as :type uid: string :param token: token (really a password) for the given UID :type token: string :param email: [OPTIONAL] email to query for :type email: string :returns: If an email is given, returns a list containing that one result (because email is unique). If there is no email in the request, returns all users. :rtype: list of dicts :aborts: 400: email is given but with invalid format 401: invalid permissions (not on whitelist or not in a required role) 404: email is not found in the DB 422: missing required parameter(s) """ return base.get_user(Volunteer, email=email) @use_kwargs({ **base.SimilarKwargs.POST, 'age': fields.Int(required=True), 'short_answer': fields.String(required=True), 'assoc_clubs': fields.String(required=True), 'availability': fields.String(required=True) }) def post(self, email, first_name, last_name, age, shirt_size, short_answer, assoc_clubs, availability, github, linkedin, dietary_rest): """Inserts the user in the mentors table. Since this hooks into the DB, each field has specific constraints. Please check registration.src.models.mentor for more information. [OPTIONAL] tags indicate that the parameter was not in the request. For example, they do not indicate fields like an 'undeclared' major being [OPTIONAL]. For the sake of the database, 'undeclared' is a valid major. :param uid: UID to authenticate as :type uid: string :param token: token (really a password) for the given UID :type token: string :param email: user's email (UNIQUE for the DB) :type email: string :param first_name: user's first name :type first_name: string :param last_name: user's last name :type last_name: string :param birthday: date of birth in the form YYYY-MM-DD :type birthday: string :param shirt_size: XS, S, M, ..., shirt size to take into consideration for orders :type shirt_size: string :param short_answer: user's reponse to the short answer question :type short_answer: string :param assoc_clubs: clubs that the user is associated with :type assoc_clubs: comma-delimited list of string :param availability: when the user is available to volunteer :type availability: comma-delimited list of strings :param github: [OPTIONAL] Github profile URL :type github: string :param linkedin: [OPTIONAL] LinkedIn profile URL :type linkedin: string :param dietary_rest: [OPTIONAL] user's dietary restrictions :type dietary_rest: comma-delimited string (might need to change this to a list of strings) :returns: representation of the row that was posted :rtype: string :aborts: 401: invalid permissions (not on whitelist or not in a required role) 422: missing required parameter(s) 500: internal DB error, usually because input did not match the constraints set by the DB. Is the column the correct type? Unique? Can it be NULL? """ volunteer = Volunteer( email, first_name, last_name, age, shirt_size, short_answer, assoc_clubs, availability, github=github, linkedin=linkedin, dietary_rest=dietary_rest ) return base.apply(volunteer, email, os.environ['MAILCHIMP_VOLUNTEER_LIST'])
def echo_nested_many(request): args = { 'users': fields.Nested({'id': fields.Int(), 'name': fields.Str()}, many=True) } parsed = yield from parser.parse(args, request) return json_response(parsed)
return redirect(config.api_location, http.client.MOVED_PERMANENTLY) @app.route('/developers/') def developers(): """Redirect to developer portal as described at https://18f.github.io/API-All-the-X/pages/developer_hub_kit. """ url = furl.furl(config.api_location) url.path.add('developers') return redirect(url.url, http.client.MOVED_PERMANENTLY) @app.route('/candidate/<c_id>/') @use_kwargs({ 'cycle': fields.Int(), 'election_full': fields.Bool(missing=True), }) def candidate_page(c_id, cycle=None, election_full=True): """Fetch and render data for candidate detail page. :param int cycle: Optional cycle for associated committees and financials. :param bool election_full: Load full election period """ candidate, committees, cycle = api_caller.load_with_nested( 'candidate', c_id, 'committees', cycle=cycle, cycle_key='two_year_period', election_full=election_full,
(h, )) def queryAll(): return execute_close('SELECT * FROM device', None) # initialise db init() @app.route('/', methods=['GET']) @use_args( { "hashid": fields.Str(required=True), "x": fields.Int(required=True), "y": fields.Int(required=True), "index": fields.Int(missing=1) }, location="query") # TODO: check if x and y are less than curve_256.p() def Device(args): '''input the point on the curve. If it is in the Group, we store a random key D that corresponds to this point, and return the point exponeniated to D. ''' try: # check if curve contains points if curve_256.contains_point(int(args['x']), int(args['y'])) != True: raise ValueError("Point ({},{}) does not exist on {}".format( args['x'], args['y'], curve_256))
def test_type_conversion_with_multiple_required(web_request, parser): web_request.json = {} args = {"ids": fields.List(fields.Int(), required=True)} msg = "Missing data for required field." with pytest.raises(ValidationError, match=msg): parser.parse(args, web_request)
def test_parse_basic(web_request, parser): web_request.json = {"foo": "42"} args = {"foo": fields.Int()} result = parser.parse(args, web_request) assert result == {"foo": 42}
class UserModelSchema(ObjectSchema): id = fields.Int() email = fields.Str() first_name = fields.Str() last_name = fields.Str()
g.news_api = newsapi.NewsApiClient(api_key=api_key.read().strip()) return g.news_api @app.route('/api/get_news') @use_args({ "whitelist": fields.Str(required=False), "blacklist": fields.Str(required=False), "q": fields.Str(required=False), "sort": fields.Str(required=False), "category": fields.Str(required=False), "from-date": fields.Str(required=False), "to-date": fields.Str(required=False), "category": fields.Str(required=False), "lang": fields.Str(required=False), "page": fields.Int(required=False), }) @as_json_p def get_news(args): use_whitelist = "whitelist" in args whitelist = args["whitelist"].split(',') if use_whitelist else [] blacklist = args["blacklist"].split(',') if "blacklist" in args else [] sort = args["sort"] if "sort" in args else "relevance" q = args["q"] if "q" in args else "" lang = args["lang"] if "lang" in args else "en" page = args["page"] if "page" in args else 0 newsapi = get_news_api() return newsapi.get_top_headlines( q=q,
async def echo_path_param(request): parsed = await parser.parse({"path_param": fields.Int()}, request, location="path_params") return J(parsed)
@app.route("/echo_ignoring_extra_data", methods=["POST"]) async def echo_json_ignore_extra_data(request): parsed = await parser.parse(hello_exclude_schema, request) return J(parsed) @app.route("/echo_use_args", methods=["GET"]) @use_args(hello_args, location="query") async def echo_use_args(request, args): return J(args) @app.route("/echo_use_args_validated", methods=["POST"]) @use_args({"value": fields.Int()}, validate=lambda args: args["value"] > 42, location="form") async def echo_use_args_validated(request, args): return J(args) @app.route("/echo_use_kwargs", methods=["GET"]) @use_kwargs(hello_args, location="query") async def echo_use_kwargs(request, name): return J({"name": name}) @app.route("/echo_multi", methods=["GET"]) async def echo_multi(request): result = await parser.parse(hello_multiple, request, location="query")
def echo_matchdict(request): return parser.parse({"mymatch": fields.Int()}, request, locations=("matchdict", ))
class TagsSetRemoveNoteSchema(ma.SQLAlchemySchema): class Meta: pass tags = fields.List(fields.Int())
class MySchema(Schema): foo = fields.Int()
class UserSchema(Schema): id = fields.Int(dump_only=True) username = fields.Str(required=True) first_name = fields.Str() last_name = fields.Str()
def test_int_list_allowed_missing(web_request, parser): args = {"name": fields.List(fields.Int())} web_request.json = {} result = parser.parse(args, web_request) assert result == {}
@app.route("/trendingTopics/<string:level>") def get_trending_topics(level): return jsonify(repository.get_trending_topics(level)) @app.route('/logout') @login_required def logout(): logout_user() return redirect('/') @app.route("/upvote", methods=['GET', 'POST']) @login_required @use_args({"postID": fields.Int(validate=lambda id: not is_upvoted(username=current_user.username,post_id=id))}) def upvote(args): return insert_upvote(username=current_user.username,post_id=args['postID']) @app.route("/save/comment", methods=['GET', 'POST']) @login_required @use_args({ "description": fields.Str(validate=lambda val: bool(val.strip())), "topicID": fields.Int(required=True) }) def save_comment(args): return insert_secondary_post( topicID=args["topicID"] ,username=current_user.username ,description=args["description"])
class UserSchema(Schema): id = fields.Int(dump_only=True) email = fields.Email() password = fields.Str(load_only=True)
# Register: /API/pico/register?uid={UID} # Response: '#{0}#\r\n' where {0} : T = Registered, F = Not Registered register_args = { 'uid': fields.Str(required=True), # 32 character alpha-numeric serial number } @main.route('/API/pico/register') @use_args(register_args, location='querystring') def process_register(args): return '#T#\r\n' # Change State: /API/pico/picoChangeState?picoUID={UID}&state={STATE} # Response: '\r\n' change_state_args = { 'picoUID': fields.Str(required=True), # 32 character alpha-numeric serial number 'state': fields.Int(required=True), # 2 = Ready, 3 = Brewing, 4 = Sous Vide, 5 = Rack Beer, 6 = Rinse, 7 = Deep Clean, 9 = De-Scale } @main.route('/API/pico/picoChangeState') @use_args(change_state_args, location='querystring') def process_change_state_request(args): return '\r\n' # Check Firmware: /API/pico/checkFirmware?uid={UID}&version={VERSION} # Response: '#{0}#' where {0} : T = Update Available, F = No Updates check_firmware_args = { 'uid': fields.Str(required=True), # 32 character alpha-numeric serial number 'version': fields.Str(required=True), # Current firmware version - i.e. 0.1.11 } @main.route('/API/pico/checkFirmware') @use_args(check_firmware_args, location='querystring')
class AttendeeRegistration(Resource): # pylint: disable=no-member, unused-argument, too-many-arguments, too-many-locals, no-self-use """Endpoints for registering a user or retrieving registered user(s).""" @use_kwargs(base.SimilarKwargs.GET) @verify({GIDS['dev']}) def get(self, uid, token, email): """Gets a user's entry by the model and their email. Gets all users by the model if email is omitted. :param uid: UID to authenticate as :type uid: string :param token: token (really a password) for the given UID :type token: string :param email: [OPTIONAL] email to query for :type email: string :returns: If an email is given, returns a list containing that one result (because email is unique). If there is no email in the request, returns all users. :rtype: list of dicts :aborts: 400: email is given but with invalid format 401: invalid permissions (not on whitelist or not in a required role) 404: email is not found in the DB 422: missing required parameter(s) """ return base.get_user(Attendee, email=email) @use_kwargs({ **base.SimilarKwargs.POST, 'age': fields.Int(required=True), 'university': fields.String(required=True), 'short_answer1': fields.String(required=True), 'short_answer2': fields.String(required=True), 'phone_number': fields.String(required=True), 'gender': fields.String(missing=None), 'ethnicity': fields.String(missing=None), 'major': fields.String(missing=None), 'num_hacks': fields.String(missing=None), 'workshop_ideas': fields.String(missing=None), 'grad_year': fields.Int(missing=None), 'resume_uri': fields.String(missing=None) }) def post(self, email, first_name, last_name, age, university, shirt_size, short_answer1, short_answer2, phone_number, gender, ethnicity, major, num_hacks, linkedin, github, dietary_rest, workshop_ideas, grad_year, resume_uri): """Inserts the user in the attendees table. Since this hooks into the DB, each field has specific constraints. Please check registration.src.models.attendee for more information. [OPTIONAL] tags indicate that the parameter was not in the request. For example, they do not indicate fields like an 'undeclared' major being [OPTIONAL]. For the sake of the database, 'undeclared' is a valid major. :param uid: UID to authenticate as :type uid: string :param token: token (really a password) for the given UID :type token: string :param email: user's email (UNIQUE for the DB) :type email: string :param first_name: user's first name :type first_name: string :param last_name: user's last name :type last_name: string :param age: user's age in years :type age: int :param university: university that the user is enrolled in :type university: string :param shirt_size: XS, S, M, ..., shirt size to take into consideration for orders :type shirt_size: string :param short_answer1: user's reponse to the first short answer question :type short_answer1: string :param short_answer2: user's reponse to the second short answer question :type short_answer2: string :param phone_number: user's phone number :type phone_number: string :param gender: [OPTIONAL] user's gender, or agender, etc. :type gender: character :param ethnicity: [OPTIONAL] user's ethnicity :type ethnicity: string :param major: [OPTIONAL] user's expected major (or undeclared) :type major: string :param num_hacks: [OPTIONAL] number of hackathons that the user has attended previously :type num_hacks: string :param github: [OPTIONAL] Github profile URL :type github: string :param linkedin: [OPTIONAL] LinkedIn profile URL :type linkedin: string :param dietary_rest: [OPTIONAL] user's dietary restrictions :type dietary_rest: comma-delimited string (might need to change this to a list of strings) :param workshop_ideas: [OPTIONAL] comments about workshops that the user would like to see implemented :type workshop_ideas: string :param grad_year: [OPTIONAL] user's expected year of graduation :type grad_year: int :param resume_uri: [OPTIONAL] URI to the user's resume. Typically an S3 URL or path. :type resume_uri: string :returns: representation of the row that was posted :rtype: string :aborts: 401: invalid permissions (not on whitelist or not in a required role) 422: missing required parameter(s) 500: internal DB error, usually because input did not match the constraints set by the DB. Is the column the correct type? Unique? Can it be NULL? """ attendee = Attendee(email, first_name, last_name, age, university, shirt_size, short_answer1, short_answer2, strip_non_num(phone_number), gender=gender, ethnicity=ethnicity, major=major, num_hacks=num_hacks, github=github, linkedin=linkedin, dietary_rest=dietary_rest, workshop_ideas=workshop_ideas, grad_year=grad_year, resume_uri=resume_uri) return base.apply(attendee, email, os.environ['MAILCHIMP_ATTENDEE_LIST'])
def echo_query(request): parsed = yield from parser.parse(hello_args, request, locations=('query', )) return json_response(parsed) @asyncio.coroutine @use_args(hello_args) def echo_use_args(request, args): return json_response(args) @asyncio.coroutine @use_kwargs(hello_args) def echo_use_kwargs(request, name): return json_response({'name': name}) @asyncio.coroutine @use_args({'value': fields.Int()}, validate=lambda args: args['value'] > 42) def echo_use_args_validated(request, args): return json_response(args) @asyncio.coroutine def echo_multi(request): parsed = yield from parser.parse(hello_multiple, request) return json_response(parsed) @asyncio.coroutine def echo_many_schema(request): parsed = yield from parser.parse(hello_many_schema, request, locations=('json', )) return json_response(parsed) @asyncio.coroutine @use_args({'value': fields.Int()})
'is_individual': fields.Bool( missing=None, description='Restrict to non-earmarked individual contributions'), 'contributor_type': fields.List( fields.Str(validate=validate.OneOf(['individual', 'committee'])), description= 'Filters individual or committee contributions based on line number.'), } schedule_a_by_size = { 'cycle': fields.List(fields.Int, description=docs.RECORD_CYCLE), 'size': fields.List(fields.Int(validate=validate.OneOf([0, 200, 500, 1000, 2000])), description=docs.SIZE), } schedule_a_by_state = { 'cycle': fields.List(fields.Int, description=docs.RECORD_CYCLE), 'state': fields.List(IStr, description='State of contributor'), 'hide_null': fields.Bool(missing=False, description='Exclude values with missing state'), } schedule_a_by_zip = { 'cycle': fields.List(fields.Int, description=docs.RECORD_CYCLE),
def echo_match_info(request): parsed = yield from parser.parse({'mymatch': fields.Int(location='match_info')}, request) return json_response(parsed)
def add_generation_routes(app, is_local, server_path): """ Create routes related to file generation Attributes: app: A Flask application is_local: A boolean flag indicating whether the application is being run locally or not server_path: A string containing the path to the server files (only applicable when run locally) """ @app.route("/v1/generate_file/", methods=["POST"]) @convert_to_submission_id @requires_submission_perms('writer') @use_kwargs({ 'file_type': webargs_fields.String( required=True, validate=webargs_validate.OneOf(('D1', 'D2', 'E', 'F'), error="Must be either D1, D2, E or F")), 'start': webargs_fields.String( validate=webargs_validate.Regexp(DATE_REGEX, error="Must be in the format MM/DD/YYYY")), 'end': webargs_fields.String( validate=webargs_validate.Regexp(DATE_REGEX, error="Must be in the format MM/DD/YYYY")), 'agency_type': webargs_fields.String( missing='awarding', validate=webargs_validate.OneOf(('awarding', 'funding'), error="Must be either awarding or funding if provided") ), 'file_format': webargs_fields.String( missing='csv', validate=webargs_validate.OneOf(('csv', 'txt'), error="Must be either csv or txt if provided") ) }) def generate_file(submission_id, file_type, **kwargs): """ Kick of a file generation, or retrieve the cached version of the file. Attributes: submission: submission ID for which we're generating the file file_type: type of file to generate the job for start: the start date for the file to generate end: the end date for the file to generate agency_type: The type of agency (awarding or funding) to generate the file for file_format: determines if the file generated is a txt or a csv """ start = kwargs.get('start') end = kwargs.get('end') agency_type = kwargs.get('agency_type') file_format = kwargs.get('file_format') return generation_handler.generate_file(submission_id, file_type, start, end, agency_type, file_format) @app.route("/v1/check_generation_status/", methods=["GET"]) @convert_to_submission_id @requires_submission_perms('reader') @use_kwargs({'file_type': webargs_fields.String( required=True, validate=webargs_validate.OneOf(('D1', 'D2', 'E', 'F'), error="Must be either D1, D2, E or F")) }) def check_generation_status(submission, file_type): """ Return status of file generation job Attributes: submission: submission for which we're generating the file file_type: type of file to check the status of """ return generation_handler.check_generation(submission, file_type) @app.route("/v1/generate_detached_file/", methods=["POST"]) @requires_login @use_kwargs({ 'file_type': webargs_fields.String(required=True, validate=webargs_validate.OneOf(('A', 'D1', 'D2'))), 'cgac_code': webargs_fields.String(), 'frec_code': webargs_fields.String(), 'start': webargs_fields.String(), 'end': webargs_fields.String(), 'year': webargs_fields.Int(), 'period': webargs_fields.Int(validate=webargs_validate.OneOf(list(range(2, 13)), error="Period must be an integer 2-12.")), 'agency_type': webargs_fields.String( missing='awarding', validate=webargs_validate.OneOf(('awarding', 'funding'), error="Must be either awarding or funding if provided") ), 'file_format': webargs_fields.String( missing='csv', validate=webargs_validate.OneOf(('csv', 'txt'), error="Must be either csv or txt if provided") ) }) def generate_detached_file(file_type, **kwargs): """ Generate a file from external API, independent from a submission Attributes: file_type: type of file to be generated cgac_code: the code of a CGAC agency if generating for a CGAC agency frec_code: the code of a FREC agency if generating for a FREC agency start: start date in a string, formatted MM/DD/YYYY end: end date in a string, formatted MM/DD/YYYY year: integer indicating the year to generate for (YYYY) period: integer indicating the period to generate for (2-12) agency_type: The type of agency (awarding or funding) to generate the file for file_format: determines if the file generated is a txt or a csv """ cgac_code = kwargs.get('cgac_code') frec_code = kwargs.get('frec_code') start = kwargs.get('start') end = kwargs.get('end') year = kwargs.get('year') period = kwargs.get('period') agency_type = kwargs.get('agency_type') file_format = kwargs.get('file_format') return generation_handler.generate_detached_file(file_type, cgac_code, frec_code, start, end, year, period, agency_type, file_format) @app.route("/v1/check_detached_generation_status/", methods=["GET"]) @requires_login @use_kwargs({'job_id': webargs_fields.Int(required=True)}) def check_detached_generation_status(job_id): """ Return status of file generation job """ return generation_handler.check_detached_generation(job_id)
# Indico is free software; you can redistribute it and/or # modify it under the terms of the MIT License; see the # LICENSE file for more details. from marshmallow_enum import EnumField from webargs import fields from indico.legacy.common.cache import GenericCache from indico.modules.rb.models.reservations import RepeatFrequency _cache = GenericCache('Rooms') search_room_args = { 'capacity': fields.Int(), 'equipment': fields.List(fields.Str()), 'features': fields.List(fields.Str(), data_key='feature'), 'favorite': fields.Bool(), 'mine': fields.Bool(), 'text': fields.Str(), 'division': fields.Str(), 'start_dt': fields.DateTime(), 'end_dt': fields.DateTime(), 'repeat_frequency': EnumField(RepeatFrequency), 'repeat_interval': fields.Int(missing=0), 'building': fields.Str(), 'sw_lat': fields.Float(validate=lambda x: -90 <= x <= 90), 'sw_lng': fields.Float(validate=lambda x: -180 <= x <= 180), 'ne_lat': fields.Float(validate=lambda x: -90 <= x <= 90), 'ne_lng': fields.Float(validate=lambda x: -180 <= x <= 180)
from flask import g from datetime import datetime from util.api_util import not_found from util.json_util import jsonify from api import api from util.api_util import Location, bad_request from marshmallow import missing from webargs import fields from webargs.flaskparser import use_kwargs from util.access_util import login_required, project_owner_required @api.route('/main', methods=['GET']) @login_required @use_kwargs({'section_id':fields.Int(), 'owner_user_id': fields.Int()}, locations=Location.query) def get_projects(section_id, owner_user_id): """ --- get: description: Return a list of projects. parameters: - name: section_id description: ID of the section you want the results filtered by. in: query type: integer - name: owner_user_id description: ID of the user you want the results filtered by. in: query type: integer
def echo_view_arg(view_arg): return J( parser.parse({'view_arg': fields.Int()}, locations=('view_args', )))
} names = { 'q': fields.List(fields.Str, required=True, description='Name (candidate or committee) to search for'), } query = { 'q': fields.Str(required=False, description='Text to search legal documents for.'), 'from_hit': fields.Int(required=False, description='Get results starting from this index.'), 'hits_returned': fields.Int(required=False, description='Number of results to return (max 10).'), 'type': fields.Str(required=False, description='Document type to refine search by'), 'ao_no': fields.List(IStr, required=False, description='Force advisory opinion number'), 'ao_name': fields.List(IStr, required=False, description='Force advisory opinion name'), 'ao_min_issue_date':