def _convert_models( view_kwargs: dict, url_param_names_to_models: dict, ) -> dict: for url_param_name, model_mapping in url_param_names_to_models.items(): arg_name = None model = model_mapping if isinstance(model_mapping, dict): arg_name, model = list(model_mapping.items())[0] if not (inspect.isclass(model) and issubclass(model, Model)): continue if not arg_name: arg_name = camel_to_snake_case(model.__name__) filter_by = url_param_name.replace( camel_to_snake_case(model.__name__) + '_', '') instance = model.query.filter_by( **{ filter_by: view_kwargs.pop(url_param_name), }).first() if not instance: abort(HTTPStatus.NOT_FOUND) view_kwargs[arg_name] = instance return view_kwargs
def _get_endpoint(self, view_func, endpoint=None, plural=False): if endpoint: assert '.' not in endpoint, 'Api endpoints should not contain dots' elif isinstance(view_func, MethodViewType): endpoint = camel_to_snake_case(view_func.__name__) if hasattr(view_func, 'model') and plural: plural_model = camel_to_snake_case(view_func.model.__plural__) endpoint = f'{plural_model}_resource' else: endpoint = view_func.__name__ return f'{self.name}.{endpoint}'
def _convert_models(view_kwargs: dict, url_param_names_to_models: dict, ) -> dict: for url_param_name, model_mapping in url_param_names_to_models.items(): arg_name = None model = model_mapping if isinstance(model_mapping, dict): arg_name, model = list(model_mapping.items())[0] if not (inspect.isclass(model) and issubclass(model, Model)): continue if not arg_name: arg_name = camel_to_snake_case(model.__name__) extra_params = url_param_names_to_models[url_param_name] if isinstance(extra_params, dict): param_value = view_kwargs.get(url_param_name) validations = extra_params.pop('validations', []) or [] for validation in validations: validation_message = Validator.is_invalid( param_value, **validation) if validation_message: abort(make_response( jsonify(message=validation_message), HTTPStatus.BAD_REQUEST)) filter_by = url_param_name.replace( camel_to_snake_case(model.__name__) + '_', '') instance = model.query.filter_by(**{ filter_by: view_kwargs.pop(url_param_name), }) if isinstance(extra_params, dict) and extra_params.get('is_list'): instance = instance.all() else: instance = instance.first() if not instance: abort(HTTPStatus.NOT_FOUND) view_kwargs[arg_name] = instance return view_kwargs
def foreign_key(model_or_table_name, fk_col=None, primary_key=False, nullable=True, deferrable=True, foreign_key_args=None, **kwargs): """Helper method to add a foreign key Column to a model. For example:: class Post(Model): category_id = foreign_key('Category') category = relationship('Category', back_populates='posts') Is equivalent to:: class Post(Model): category_id = Column(BigInteger, ForeignKey('category.id'), nullable=False) category = relationship('Category', back_populates='posts') :param deferrable: :param nullable: :param model_or_table_name: the model or table name to link to If given a lowercase string, it's treated as an explicit table name. If there are any uppercase characters, it's assumed to be a model name, and will be converted to snake case using the same automatic conversion as Flask-SQLAlchemy does itself. If given an instance of :class:`flask_sqlalchemy.Model`, use its :attr:`__tablename__` attribute. :param str fk_col: column name of the primary key (defaults to "id") :param bool primary_key: Whether or not this Column is a primary key :param dict kwargs: any other kwargs to pass the Column constructor """ if foreign_key_args is None: foreign_key_args = {} model = model_or_table_name table_name = model_or_table_name fk_col = fk_col or 'id' if inspect.isclass(model) and issubclass(model, db.Model): table_name = model_or_table_name.__tablename__ elif table_name != table_name.lower(): table_name = camel_to_snake_case(table_name) return Column(db.BigInteger, db.ForeignKey(f'{table_name}.{fk_col}', deferrable=deferrable, **foreign_key_args), primary_key=primary_key, nullable=nullable, **kwargs)
def handle_error(self, error, data): """Customize the error messages for required/not-null validators with dynamically generated field names. This is definitely a little hacky (it mutates state, uses hardcoded strings), but unsure how better to do it """ required_messages = ('Missing data for required field.', 'Field may not be null.') for field_name in error.field_names: for i, msg in enumerate(error.messages[field_name]): if msg in required_messages: label = camel_to_snake_case(field_name).replace( '_', ' ').title() error.messages[field_name][i] = f'{label} is required.'
def save_fixture(self): from sqlalchemy import inspect def get_row_dic(row): return { c.key: getattr(row, c.key) for c in inspect(row).mapper.column_attrs } return { "table": camel_to_snake_case(self.__class__.__name__), "records": [get_row_dic(row) for row in self.all()] }
def can_access_field(source, info, **kwargs): """Checks if the requested field can be accessed by the user :type info: graphql.execution.base.ResolveInfo """ session = get_session(info) user = get_current_user(info) permissions = permissions_config().get(str(info.parent_type)) if permissions is None: return False field_name = camel_to_snake_case(info.field_name) permission = permissions.get(field_name) if all_permissions.get(permission, deny)(session, user, source, path=info.path, **kwargs): return True return False
def title_case(string): return camel_to_snake_case(string).replace('_', ' ').title()
def test_camel_to_snake_case(name, expect): assert camel_to_snake_case(name) == expect