def test_file_field(app): field = doc.File() assert field.serialize() == {"type": "file"} @app.get("/") @doc.consumes(field, location="formData", required=True) def test(request): return text("test") _, response = app.test_client.get("/swagger/swagger.json") assert response.status == 200 assert response.content_type == "application/json" swagger_json = response.json path = swagger_json["paths"]["/"]["get"] assert path["parameters"][0] == { "required": True, "in": "formData", "name": None, "type": "file", }
class AvatarView(HTTPMethodView): @doc.summary('get the user\'s avatar') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.produces(_user_avatar) @token_required async def get(self, request): user = request.ctx.user if not await async_exists(USERS_ROOT / user.email / user.avatar): return json(response_message(ENOENT)) async with aiofiles.open(USERS_ROOT / user.email / user.avatar, 'rb') as img: _, ext = os.path.splitext(user.avatar) return json(response_message(SUCCESS, type=f'image/{ext[1:]}', data=base64.b64encode(await img.read()).decode('ascii'))) @doc.summary('upload the avatar for a user') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.consumes(doc.File(name='file'), location='formData', content_type="multipart/form-data") @doc.produces(json_response) @token_required async def post(self, request): user = request.ctx.user avatar = request.files.get('file') async with aiofiles.open(USERS_ROOT / user.email / 'temp.png', 'wb') as f: await f.write(avatar.body) return json(response_message(SUCCESS)) @doc.summary('change the avatar\'s source') @doc.description('type: {custom | default}, where "custom" means using a custom avatar uploaded by user, "default" means use an identicon generated from user\'s email') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.consumes(_avatar, location='body') @doc.produces(json_response) @token_required async def patch(self, request): user = request.ctx.user avatar_type = request.json.get('type', None) if not avatar_type: return json(response_message(EINVAL, 'Field type is required')) if avatar_type == 'custom': filename1 = USERS_ROOT / user.email / 'temp.png' if not await async_exists(filename1): return json(response_message(ENOENT, 'Avatar file not found')) filename2 = USERS_ROOT / user.email / (str(user.pk) + '.png') try: await aiofiles.os.remove(filename2) except FileNotFoundError: pass await aiofiles.os.rename(filename1, filename2) elif avatar_type == 'default': filename = USERS_ROOT / user.email / (str(user.pk) + '.png') try: await aiofiles.os.remove(filename) except FileNotFoundError: pass img = await render_identicon(hash(user.email), 27) await async_wraps(img.save)(USERS_ROOT / user.email / f'{user.pk}.png') else: return json(response_message(EINVAL, 'Unknown avatar type')) return json(response_message(SUCCESS))
if payload.get("redirect", False): return response.redirect(url) if template.valid: status = 201 else: status = 404 template.delete() return response.json({"url": url}, status=status) @blueprint.get("/preview.jpg") @doc.summary("Display a preview of a custom meme") @doc.produces( doc.File(), description="Successfully displayed a custom meme", content_type="image/jpeg", ) async def preview(request): key = request.args.get("template", "_error") lines = request.args.getlist("lines[]", []) style = request.args.get("style") return await preview_image(request, key, lines, style) @blueprint.get("/<template_key>.png") @doc.summary("Display a template background") @doc.produces( doc.File(), description="Successfully displayed a template background",
from sanic.log import logger from sanic.views import HTTPMethodView from sanic.response import json, file from sanic_openapi import doc from ..util import async_exists from ..util.dto import SettingDto, json_response from ..util.response import * bp = Blueprint('setting', url_prefix='/setting') @bp.get('/download') @doc.summary('Get installation packages for the endpooint') @doc.consumes(doc.String(name='file', description='The file path')) @doc.produces(201, doc.File()) @doc.produces(200, json_response) async def handler(request): download_file = request.args.get('file', default=None) if not download_file: return json(response_message(EINVAL, 'Field file is required')) ret = urlparse(request.url) if download_file == 'get-endpoint.py' or download_file == 'get-poetry.py': src = os.path.join('static', 'download', 'template.' + download_file) new = os.path.join('static', 'download', download_file) if await async_exists(new): await aiofiles.os.remove(new) async with aiofiles.open(src) as f_src, aiofiles.open(new, 'w') as f_new: async for line in f_src:
from sanic import Blueprint, response from sanic.exceptions import abort from sanic.log import logger from sanic_openapi import doc from .. import models, settings, utils blueprint = Blueprint("shortcuts", url_prefix="/") @blueprint.get("/images/<template_key>") @doc.summary("Redirect to a sample image") @doc.response(302, doc.File(), description="Successfully redirected to a sample image") @doc.response(404, str, description="Template not found") @doc.response(501, str, description="Template not fully implemented") async def sample(request, template_key): if settings.DEBUG: template = models.Template.objects.get_or_create(template_key) else: template = models.Template.objects.get_or_none(template_key) if template and template.valid: url = template.build_sample_url(request.app, "shortcuts.custom", external=False) return response.redirect(url) if settings.DEBUG: message = f"Template not fully implemented: {template}"
url = template.build_custom_url( request.app, payload.get("text_lines") or [], extension=payload.get("extension"), ) if payload.get("redirect", False): return response.redirect(url) return response.json({"url": url}, status=201) @blueprint.get("/preview.jpg") @doc.summary("Display a preview of a custom meme") @doc.produces( doc.File(), description="Successfully displayed a custom meme", content_type="image/jpeg", ) async def preview(request): key = request.args.get("template", "_error") lines = request.args.getlist("lines[]", []) style = request.args.get("style") return await preview_image(request, key, lines, style) @blueprint.get("/<template_key>.png") @doc.summary("Display a template background") @doc.produces( doc.File(), description="Successfully displayed a template background",
from sanic import Blueprint, response from sanic.exceptions import abort from sanic.log import logger from sanic_openapi import doc from .. import models, settings, utils blueprint = Blueprint("shortcuts", url_prefix="/") @blueprint.get("/images/<template_key>") @doc.summary("Redirect to a example image") @doc.response(302, doc.File(), description="Successfully redirected to a example image") @doc.response(404, str, description="Template not found") @doc.response(501, str, description="Template not fully implemented") async def example(request, template_key): if settings.DEBUG: template = models.Template.objects.get_or_create(template_key) else: template = models.Template.objects.get_or_none(template_key) if template and template.valid: url = template.build_example_url( request.app, "shortcuts.custom", external=False ) return response.redirect(url) if settings.DEBUG: if "<" in template_key: message = f"Replace {template_key!r} in the URL" else:
class ScriptView(HTTPMethodView): @doc.summary('A compound method to return either the script file list or the script file content') @doc.description('When field file is None, return the file list as per script_type, otherwise return the specified file.') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.consumes(_script_query) @doc.produces(200, _script_file_list) @doc.produces(201, doc.File()) @token_required @organization_team_required_by_args async def get(self, request): script_path = request.args.get('file', default=None) script_type = request.args.get('script_type', default=None) organization = request.ctx.organization team = request.ctx.team test_libraries_root = await get_back_scripts_root(team=team, organization=organization) test_scripts_root = await get_user_scripts_root(team=team, organization=organization) if script_path: if script_type is None: return json(response_message(EINVAL, 'Field script_type is required')) if script_type == 'test_scripts': return await file(test_scripts_root / script_path, status=201) elif script_type == 'test_libraries': return await file(test_libraries_root / script_path, status=201) else: return json(response_message(EINVAL, 'Unsupported script type ' + script_type)) elif script_type: return json(response_message(EINVAL, 'Field file is required')) test_scripts = await async_wraps(path_to_dict)(test_scripts_root) test_libraries = await async_wraps(path_to_dict)(test_libraries_root) return json(response_message(SUCCESS, test_scripts=test_scripts, test_libraries=test_libraries)) @doc.summary('update the script file content') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.consumes(_update_script, location='body') @doc.produces(json_response) @token_required @organization_team_required_by_json async def post(self, request): script = request.json.get('file', None) if not script: return json(response_message(EINVAL, 'Field file is required')) if not is_path_secure(script): return json(response_message(EINVAL, 'Illegal file path')) new_name = request.json.get('new_name', None) if new_name: if not is_path_secure(new_name): return json(response_message(EINVAL, 'Illegal new name')) script_type = request.json.get('script_type', None) if script_type is None: return json(response_message(EINVAL, 'Field script_type is required')) content = request.json.get('content', None) if content is None and new_name is None: return json(response_message(EINVAL, 'Field content is required')) organization = request.ctx.organization team = request.ctx.team user = request.ctx.user package = None if script_type == 'test_scripts': root = await get_user_scripts_root(team=team, organization=organization) elif script_type == 'test_libraries': root = await get_back_scripts_root(team=team, organization=organization) else: return json(response_message(EINVAL, 'Unsupported script type ' + script_type)) dirname = os.path.dirname(script).split('/')[0] basename = os.path.basename(script) if script_type == 'test_scripts' and basename.endswith('.md'): test = await Test.find_one({'test_suite': os.path.splitext(basename)[0], 'path': dirname}) if not test: return json(response_message(ENOENT, 'test suite not found')) elif script_type == 'test_libraries' and dirname: package = await Package.find_one({'py_packages': dirname}) if not package: return json(response_message(ENOENT, 'package not found')) if not await async_exists(root / dirname): await async_makedirs(root / dirname) if content or content == '': if script_type == 'test_scripts': content = re.sub(r'\\([{}*_\.])', r'\1', content) elif script_type == 'test_libraries': content = re.sub(r'\r\n', '\n', content) if basename: async with aiofiles.open(root / script, 'w', encoding='utf-8') as f: await f.write(content) if new_name: if basename: new_path = os.path.join(dirname, new_name) await aiofiles.os.rename(root / script, root / new_path) if script_type == 'test_scripts' and test: # not md files test.test_suite = os.path.splitext(new_name)[0] await test.commit() else: await aiofiles.os.rename(root / script, root / os.path.dirname(dirname) / new_name) if basename and script_type == 'test_scripts': _script = str(Path(dirname) / new_name) if new_name else script if _script.endswith('.md'): ret = await db_update_test(root, _script, user, organization, team) if not ret: return json(response_message(UNKNOWN_ERROR, 'Failed to update test suite')) if script_type == 'test_libraries' and package: package.modified = True await package.commit() return json(response_message(SUCCESS)) @doc.summary('delete the script file') @doc.consumes(doc.String(name='X-Token'), location='header') @doc.consumes(_script_query, location='body') @doc.produces(json_response) @token_required @organization_team_required_by_json async def delete(self, request): organization = request.ctx.organization team = request.ctx.team script = request.json.get('file', None) if not script: return json(response_message(EINVAL, 'Field file is required')) if not is_path_secure(script): return json(response_message(EINVAL, 'Referencing to Upper level directory is not allowed')) dirname = os.path.dirname(script) basename = os.path.basename(script) script_type = request.json.get('script_type', None) if script_type is None: return json(response_message(EINVAL, 'Field script_type is required')) if script_type == 'test_scripts': root = await get_user_scripts_root(team=team, organization=organization) elif script_type == 'test_libraries': root = await get_back_scripts_root(team=team, organization=organization) else: return json(response_message(EINVAL, 'Unsupported script type ' + script_type)) if not await async_exists(root / script): return json(response_message(ENOENT, 'File/directory doesn\'t exist')) if await async_isfile(root / script): try: await aiofiles.os.remove(root / script) except OSError as err: logger.exception(err) return json(response_message(EIO, 'Error happened while deleting the file')) if script_type == 'test_scripts': cnt = 0 async for test in Test.find({'test_suite': os.path.splitext(basename)[0], 'path': dirname, 'organization': organization.pk, 'team': team.pk if team else None}): await test.delete() cnt += 1 if cnt == 0: return json(response_message(ENOENT, 'Test suite not found in the database')) else: if script_type == 'test_scripts': cnt = 0 async for test in Test.find({'organization': organization.pk, 'team': team.pk if team else None}): if test.path.startswith(dirname): await test.delete() cnt += 1 if cnt == 0: logger.error(f'Test suite not found in the database under the path {dirname}') try: await async_rmtree(root / script) except OSError as err: logger.exception(err) return json(response_message(EIO, 'Error happened while deleting the directory')) return json(response_message(SUCCESS))
app.blueprint(swagger_blueprint) jinja = SanicJinja2(app) app.static('/static', './static') db = Gino() class Image(db.Model): __tablename__ = 'image' id = db.Column(db.Integer(), primary_key=True, autoincrement=True) path = db.Column(db.Unicode(), default='noname') @app.route(methods=['GET', 'POST'], uri='/upload') @doc.consumes(doc.File(name="file"), location="formData", content_type="multipart/form-data") async def upload_img(request): loop = asyncio.get_event_loop() template = open(os.getcwd() + "/templates/index.html") if request.files: args = request.files byte_image = args.getlist('file')[0][1] # подключение к aio-pika, создание очереди и пеердача в очередь [путь или набор байтов] connection = await aio_pika.connect_robust( "amqp://*****:*****@localhost/", loop=loop) async with connection: routing_key = "image_path" # название очереди # создание очереди
class upload_package(organization_team): proprietary = doc.String() package_type = doc.String() file = doc.File()
class upload_scripts(organization_team): script_type = doc.String( description='File type {test_scripts | test_libraries}') file = doc.File()