def post(self): data = request.files.get('image') if data is None: return mk_errors(400, 'image file not present') elif data.mimetype not in VALID_MIMETYPES: return mk_errors(400, 'wrong file format (must be png or jpg)') else: uid = max(_get_uids(), default=0) + 1 path = _get_path(uid, data.mimetype) data.save(path) obj = ImageDao(uid) DB[uid] = obj return ImageSchema().dump(obj), 201
def delete(self, uid): if not _exists(uid): return mk_errors(404, '{} does not exist'.format(uid)) for mt in VALID_MIMETYPES: path = _get_path(uid, mt) if os.path.isfile(path): break else: return mk_errors(500, 'internal error') os.remove(path) del DB[uid] return '', 204
def generic_error_handler(error): code = getattr(error, 'status_code', 500) if config.debug: messages = [str(error)] else: messages = ['something went wrong!'] return mk_errors(code, messages)
def post(self): """ Revoke refresh token. .. :quickref: Refresh Logout; Revoke refresh token. **Example request**: .. sourcecode:: http POST /auth/logout/refresh HTTP/1.1 Host: example.com Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 204 NO CONTENT :reqheader Authorization: refresh token of logged in user (required) :status 204: token revoked """ jti = get_raw_jwt()['jti'] try: revoked_token = RevokedToken(jti=jti) revoked_token.save() return '', 204 except: return mk_errors('error in logout')
def delete(self, user_id): """ Delete user. Only priviledged users can use this method. .. :quickref: Delete user; Delete user. **Example request**: .. sourcecode:: http DELETE /users/1 HTTP/1.1 Host: example.com Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 204 NO CONTENT :reqheader Authorization: access token of logged in user (required) :param int user_id: id of user. :status 204: user deleted """ check_priviledges() user = User.query.filter_by(user_id=user_id).first() if user is None: return mk_errors(404, 'user id={} does not exist'.format(user_id)) db.session.delete(user) db.session.commit() return '', 204
def handle_request_parsing_error(error, *args): try: if not isinstance(error, list): error = [error] messages = fmt_validation_error_messages(error) except: raise ValidationError abort(mk_errors(400, messages))
def get(self, uid): if not _exists(uid): return mk_errors(404, '{} does not exist'.format(uid)) for mt, __ in request.accept_mimetypes: if mt in VALID_MIMETYPES: return send_file(_get_path(uid, mt), mt) else: return ImageSchema().dump(DB[uid])
def put(self, uid): if not _exists(uid): return mk_errors(404, '{} does not exist'.format(uid)) data = request.files.get('image') if data is None: return mk_errors(400, 'image file not present') elif data.mimetype not in VALID_MIMETYPES: return mk_errors(400, 'wrong file format (must be png or jpg)') else: for mt in VALID_MIMETYPES: path = _get_path(uid, mt) if os.path.isfile(path): break else: raise data.save(path) DB[uid].modified_at = dt.datetime.now() return ImageSchema().dump(DB[uid]), 200
def error_handler(error): try: if isinstance(error, JWTExtendedException): return jwt_error_handler(error) elif isinstance(error, HTTPException): return http_error_handler(error) elif isinstance(error, ValidationError): return validation_error_handler(error) else: return generic_error_handler(error) except: return mk_errors(500, 'something went wrong!')
def put(self, text_id): """ Update text resource. .. :quickref: Update Text; Update text. **Example request**: .. sourcecode:: http PUT /texts/1 HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "text": { "content": "Updated text", "text_id": 1, "tags": [ "bomdia" ], "updated_at": "2018-09-16T23:00:13+00:00", "created_at": "2018-09-15T22:53:26+00:00" } } :reqheader Authorization: access token of logged in user (required) :param int text_id: id of text resource. :form content: the text contents :form tags: comma-separated list of tags :resheader Content-Type: application/json :status 200: text updated :returns: :class:`memedata.models.Text` """ text = TextRes.get_text(text_id) try: schema = TextSchema() args = TextsRes.parse_post_args(request) text = schema.load(args, instance=text, partial=True) except ValidationError as e: return mk_errors(400, fmt_validation_error_messages(e.messages)) db.session.add(text) db.session.commit() return schema.dump(text)
def http_error_handler(error): resp = error.response if resp is None: code = error.code messages = [error.description] else: code = getattr(resp, 'status_code', 500) json = resp.get_json() if 'errors' in json and json['errors']: messages = [e['message'] for e in json['errors'] if 'message' in e] else: messages = [str(resp.status)] return mk_errors(code, messages)
def post(self): """ Create new text resource. .. :quickref: Text creation; Create new text. **Example request**: .. sourcecode:: http POST /texts HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 201 CREATED Content-Type: application/json { "text": { "content": "Bom dia!", "text_id": 1, "tags": [ "bomdia" ], "updated_at": null, "created_at": "2018-09-15T22:53:26+00:00" }, } :reqheader Authorization: access token of logged in user (required) :form content: the text contents (required) :form tags: comma-separated list of tags :resheader Content-Type: application/json :status 201: resource created :returns: :class:`memedata.models.Text` """ try: args = TextsRes.parse_post_args(request) text = TextSchema().load(args) except ValidationError as e: return mk_errors(400, fmt_validation_error_messages(e.messages)) db.session.add(text) db.session.commit() return TextSchema().dump(text), 201
def post(self): """ Login into system. .. :quickref: Login; User login. **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "message": "user 'jose' logged in", "access_token": "lajdfh09l8valufd89y614b", "refresh_token": "lkjahdljxoiuhqdouifhob" } :form username: the user name (required) :form password: the user password (required) :resheader Content-Type: application/json :status 200: user logged in """ args = parser.parse(_USER_PASS_ARGS, request, locations=('form', 'json')) user = User.query.filter_by(username=args['username']).first() if user is None or not verify_hash(args['password'], user.password): return mk_errors(400, 'invalid username or password') access_tok = create_access_token(identity=args['username']) refresh_tok = create_refresh_token(identity=args['username']) return { 'message': 'user \'{}\' logged in'.format(args['username']), 'access_token': access_tok, 'refresh_token': refresh_tok, }
def get(self, text_id): """ Return text resource. .. :quickref: Get Text; Get text. **Example request**: .. sourcecode:: http GET /texts/1 HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "text": { "content": "Bom dia!", "text_id": 1, "tags": [ "bomdia" ], "updated_at": null, "created_at": "2018-09-15T22:53:26+00:00" } } :reqheader Authorization: access token of logged in user (required) :param int text_id: id of text resource. :resheader Content-Type: application/json :status 200: text found :returns: :class:`memedata.models.Text` """ text = TextRes.get_text(text_id) try: args = TextRes.parse_get_args(request) except ValidationError as e: return mk_errors(400, fmt_validation_error_messages(e.messages)) obj = TextSchema().dump(text) return filter_fields(obj, args.get('fields'))
def post(self): """ Create user. Only priviledged users can use this method. .. :quickref: Create user; Create user. **Example request**: .. sourcecode:: http POST /users HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 201 CREATED Content-Type: application/json { "user_id": 1, "message": "user 'joao' created" } :reqheader Authorization: access token of logged in user (required) :resheader Content-Type: application/json :status 201: user created """ check_priviledges() args = parser.parse(_USER_PASS_ARGS, request, locations=('form', 'json')) if User.query.filter_by(username=args['username']).first(): return mk_errors( 400, 'username \'{}\' already taken'.format(args['username'])) new_user = User.create_and_save(args['username'], args['password']) return { 'message': 'user \'{}\' created'.format(args['username']), 'user_id': int(new_user.user_id), }, 201
def get(self, user_id): """ Get user. Only priviledged users can use this method. .. :quickref: Get user; Get user. **Example request**: .. sourcecode:: http GET /users/1 HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "user": { "user_id": 1, "password": "******", "username": "******" } } :reqheader Authorization: access token of logged in user (required) :param int user_id: id of user. :resheader Content-Type: application/json :status 200: user found """ check_priviledges() user = User.query.filter_by(user_id=user_id).first() if user is None: return mk_errors(404, 'user id={} does not exist'.format(user_id)) return {'user': user.to_json()}
def jwt_error_handler(error): code = 401 messages = list(getattr(error, 'args', [])) return mk_errors(code, messages)
def validation_error_handler(error): code = getattr(error, 'status_code', 500) messages = getattr(error, 'messages', []) return mk_errors(code, messages)
def get_text(text_id): text = Text.query.get(text_id) if text is None: abort(mk_errors(404, '{} doest not exist'.format(text_id))) return text
def get(self): """ Return collection of texts. .. :quickref: Get Texts; Get collection of texts. **Example request**: .. sourcecode:: http GET /texts HTTP/1.1 Host: example.com Accept: application/json Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhb **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Content-Type: application/json { "texts": [ { "content": "Bom dia!", "text_id": 1, "tags": [ "bomdia" ], "updated_at": null, "created_at": "2018-09-15T22:53:26+00:00" }, { "content": "Eu adoro as manhãs", "text_id": 32, "tags": [ "jesus", "sexta" ], "updated_at": null, "created_at": "2018-09-15T22:53:26+00:00" }, ], "offset": 2 } :reqheader Authorization: access token of logged in user (required) :query string fields: comma-separated list of fields to get for each \ text. :query string date_from: only texts created after specified date \ (inclusive). :query string date_to: only texts created before specified date. :query string any_tags: texts with at least one tags in specified list. :query string all_tags: texts only containing all specified tags. :query string no_tags: texts only not containing any of specified tags. :query int offset: pagination offset to start getting results :query int max_n_results: maximum number of results to return. :resheader Content-Type: application/json :status 200: texts found :returns: :class:`memedata.models.Text` """ try: args = TextsRes.parse_get_args(request) except ValidationError as e: return mk_errors(400, fmt_validation_error_messages(e.messages)) texts, offset = TextsRes.filter_texts(args) objs = TextSchema(many=True).dump(texts) objs = filter_fields(objs, args.get('fields')) objs['offset'] = offset return objs