def get(self, instrument_id: int, log_entry_id: int, object_attachment_id: int): try: instrument = get_instrument(instrument_id=instrument_id) except errors.InstrumentDoesNotExistError: return { "message": f"instrument {instrument_id} does not exist" }, 404 if not instrument.users_can_view_log_entries and flask.g.user not in instrument.responsible_users: return { "message": f"log entries for instrument {instrument_id} can only be accessed by instrument scientists" }, 403 try: log_entry = get_instrument_log_entry(log_entry_id) if log_entry.instrument_id != instrument_id: raise errors.InstrumentLogEntryDoesNotExistError() except errors.InstrumentLogEntryDoesNotExistError: return { "message": f"log entry {log_entry_id} for instrument {instrument_id} does not exist" }, 404 try: object_attachment = get_instrument_log_object_attachment( object_attachment_id) if object_attachment.log_entry_id != log_entry_id: raise errors.InstrumentLogObjectAttachmentDoesNotExistError() except errors.InstrumentLogObjectAttachmentDoesNotExistError: return { "message": f"object attachment {object_attachment_id} for log entry {log_entry_id} for instrument {instrument_id} does not exist" }, 404 return object_attachment_to_json(object_attachment)
def test_update_instrument(): instrument = instruments.create_instrument(name="Example Instrument", description="") instruments.update_instrument(instrument_id=instrument.id, name="Test", description="desc") instrument = instruments.get_instrument(instrument_id=instrument.id) assert instrument.name == "Test" assert instrument.description == "desc" assert len(instrument.responsible_users) == 0
def get(self, instrument_id: int): try: instrument = get_instrument(instrument_id=instrument_id) except errors.InstrumentDoesNotExistError: return { "message": "instrument {} does not exist".format(instrument_id) }, 404 return instrument_to_json(instrument)
def test_create_instrument(): assert len(instruments.get_instruments()) == 0 instrument = instruments.create_instrument(name="Example Instrument", description="") assert len(instruments.get_instruments()) == 1 assert instrument == instruments.get_instrument( instrument_id=instrument.id) assert len(instrument.responsible_users) == 0
def get(self, instrument_id: int): try: instrument = get_instrument(instrument_id=instrument_id) except errors.InstrumentDoesNotExistError: return { "message": f"instrument {instrument_id} does not exist" }, 404 if not instrument.users_can_view_log_entries and flask.g.user not in instrument.responsible_users: return { "message": f"log categories for instrument {instrument_id} can only be accessed by instrument scientists" }, 403 categories = get_instrument_log_categories(instrument_id) return [category_to_json(category) for category in categories]
def test_get_missing_instrument(): instrument = instruments.create_instrument(name="Example Instrument", description="") with pytest.raises(errors.InstrumentDoesNotExistError): instruments.get_instrument(instrument_id=instrument.id + 1)
def post(self, instrument_id: int): try: instrument = get_instrument(instrument_id=instrument_id) except errors.InstrumentDoesNotExistError: return { "message": f"instrument {instrument_id} does not exist" }, 404 if not instrument.users_can_create_log_entries and flask.g.user not in instrument.responsible_users: return { "message": f"log entries for instrument {instrument_id} can only be created by instrument scientists" }, 403 try: data = json.loads(flask.request.data) unexpected_keys = set(data.keys()) - { 'content', 'category_ids', 'file_attachments', 'object_attachments' } if unexpected_keys: raise ValueError() content = data['content'] category_ids = data.get('category_ids', []) file_attachments = data.get('file_attachments', []) object_attachments = data.get('object_attachments', []) except Exception: return { "message": "expected json object containing content, category_ids, file_attachments and object attachments" }, 400 if content is None: content = '' if not isinstance(content, str): return {"message": "expected string or null for content"}, 400 try: if not isinstance(category_ids, list): raise TypeError() for category_id in category_ids: if not isinstance(category_id, int): raise TypeError() except TypeError: return { "message": "expected list containing integer numbers for category_ids" }, 400 existing_category_ids = { category.id for category in get_instrument_log_categories(instrument_id) } unknown_category_ids = set(category_ids) - existing_category_ids if unknown_category_ids: return { "message": f"unknown category_ids: {', '.join(map(str, unknown_category_ids))}" }, 400 try: if not isinstance(file_attachments, list): raise TypeError() for file_attachment in file_attachments: if not isinstance(file_attachment, dict): raise TypeError() if set(file_attachment.keys()) - { 'file_name', 'base64_content' }: raise ValueError() if not isinstance(file_attachment['file_name'], str): raise TypeError() file_attachment['file_name'] = file_attachment[ 'file_name'].strip() if not isinstance(file_attachment['base64_content'], str): raise TypeError() file_attachment['content'] = base64.b64decode( file_attachment['base64_content'].encode('ascii')) except Exception: return { "message": "expected list containing dicts containing file_name and base64_content for file_attachments" }, 400 for file_attachment in file_attachments: if not file_attachment['file_name'] or len( file_attachment['file_name']) > MAX_FILE_NAME_LENGTH: return { "message": f"file attachment names must not be empty and must contain at most {MAX_FILE_NAME_LENGTH} characters" }, 400 try: if not isinstance(object_attachments, list): raise TypeError() for object_attachment in object_attachments: if not isinstance(object_attachment, dict): raise TypeError() if set(object_attachment.keys()) - {'object_id'}: raise ValueError() if not isinstance(object_attachment['object_id'], int): raise TypeError() if object_attachment['object_id'] < 0: raise ValueError() except Exception: return { "message": "expected list containing dicts containing object_id for object_attachments" }, 400 unknown_object_ids = set() attached_object_ids = [] for object_attachment in object_attachments: object_id = object_attachment['object_id'] try: permissions = get_user_object_permissions( object_id, flask.g.user.id) if Permissions.READ not in permissions: raise errors.ObjectDoesNotExistError() except errors.ObjectDoesNotExistError: unknown_object_ids.add(object_id) else: if object_id in attached_object_ids: return { "message": f"duplicate object id in object_attachments: {object_id}" }, 400 attached_object_ids.append(object_id) if unknown_object_ids: return { "message": f"unknown object ids in object_attachments: {', '.join(map(str, unknown_object_ids))}" }, 400 if not (content or file_attachments or object_attachments): return { "message": "log entry must contain content or an attachment" }, 400 log_entry = create_instrument_log_entry(instrument_id=instrument.id, user_id=flask.g.user.id, content=content, category_ids=category_ids) for file_attachment in file_attachments: create_instrument_log_file_attachment( instrument_log_entry_id=log_entry.id, file_name=file_attachment['file_name'], content=file_attachment['content']) for object_id in attached_object_ids: create_instrument_log_object_attachment( instrument_log_entry_id=log_entry.id, object_id=object_id) return None, 201, { 'Location': flask.url_for('api.instrument_log_entry', instrument_id=instrument_id, log_entry_id=log_entry.id, _external=True) }