lower case model endpoints (user instead of User) - loopbackjs

I'd like my REST API endpoints to use all lower case letters for the model.
In the case of the built-in User model, would I simply make a new model named user with User as the base? or is there another method I should use?

There are a few options:
At the moment, the endpoint name is case-insenstive, i.e., /api/users and /api/Users both work.
You can customize the model endpoint name in the model definition json, for example
"http": {"path": "/my-users"}
There are a pending PR: https://github.com/strongloop/loopback/pull/433
As Simon pointed out, you can subclass the User model. Please the default endpoint name is derived from the plural of the model name.

Yes. You just generate a new model using slc loopback:model user, follow the prompts, then change the base property value from PersistedModel to User in common/models/user.json.
I have an example here: https://github.com/strongloop/loopback-example-access-control/blob/master/common/models/user.json#L3

The best way to achieve this is to set normalizeHttpPath setting to true in your /server/config.json file.
...
"remoting": {
"rest": {
...
"normalizeHttpPath": true,
},
},
When normalizeHttpPath is set to true, it converts (in HTTP paths) from:
Uppercase letters to lowercase.
Underscores (_) to dashes (-).
CamelCase to dash-delimited.
For example, "MyClass" or "My_class" becomes "my-class" in HTTP path.
Note: It does not affect placeholders (for example ":id").
For more information, look at the remoting properties in official documentation for config.json.

Related

reversing admin "change" url

I´m trying to find some example of how to use change url of modelAdmin and what exactly result it gives. Sincerly I do not understand the part from docs:
"This will find the first registered instance of the admin application (whatever the instance name), and resolve to the view for changing poll.Choice instances in that instance."
You can reverse with:
reverse('app:poll_choice_change', kwargs={'object_id': pk})
With app the default namespace (you can specify a different one if you include this in the path(…) where you attach the admin.urls. poll the name of the app, choice the name of the model in lowercase, and pk the primary key of the object.

Flask Swagger documentation query parameter GET required

I'm using Swagger documentation with my flask project to document the endpoints and parameters.
To define the query parameters for an endpoint I'm doing:
#api.doc(params={
'name_query_parameter': 'Description'})
I wanted to know if it's possible for that parameter to show in the docs as "required", like it does for when the parameter is part of the path (home/name_query_parameter/something/something).
Looking into the documentation I only found the following:
#api.expect()
#api.doc(body=the_defined_payload)
But this implies for the information to be on the body, I can't have that with a GET request. Plus, I want it as a query parameter, not as part of the payload.
Is this possible at all?
Thanks.
The final solution to this is as follows, thanks to Mikhail for commenting about the parser. I have to admit though, documentation is not the best for flask-restplus.
I used the params part to make sure the fields appear in the docs along with a description and the parser for custom validation and to make the field appear as required even though it is located in the URL as params.
parser = reqparse.RequestParser()
parser.add_argument('superimportant',
type=inputs.boolean, location='args', required=True)
parser.add_argument('something', type=custom_validation_parser, location='args')
class MySuperClassResource(Resource):
#api.doc(parser=categories_by_retailer_parser,
params={"superimportant": "Description of this important field",
"something": "bla bla"
})
def get(self, blable):
parser.parse_args()
pass
The custom_validation_parser is just a method that allows custom validation, like for empty values. The format of that method is as follows. (It must return the value you want to access, and if there's . problem, raise a ValueError).
def custom_validation_parser(value):
if not value:
raise ValueError("Must not be empty.")
return value

Find the class name of a relation from the instance of a model in ember JS

I have foo an instance of the ember-data model thing. thing.js has the following property :
owner: DS.belongsTo('user')
If I have foo with an empty owner, how can I, with only foo and the 'owner' string, retrieve the value 'user' representing the model of the owner relation?
EDIT: I want to allow my select-relation component to works with relations where the name is different from the class name
It sounds like you have some work to do to finish setting up your relationships. Have a read through this page of the guides.
If the relationships are set up correctly, to get the associated user, you should be able to do foo.owner. This assumes that users are already present in the store. I recommend using the Ember Inspector browser plugin to debug the relationships.
This looks like a use case for typeForRelationship.
In your example you should be able to do something like
store.modelFor('thing').typeForRelationship('owner', store);
If you don't like that approach you can use the belongsTo reference API, where you use the meta data from the relationship to get the type
foo.belongsTo('owner').type
The only thing with that approach is that the type property may not be public API and possible (though unlikely) to change at some point.
It seems I can do the following :
this.get('model').get('_internalModel._relationships.initializedRelationships.'+this.get('relation')+'.relationshipMeta.type')
model being an instance and relation the string of the relation name, it correctly return the model of the relation.
EDIT : a better solution not using private API courtesy from the ember discord :
function getRelatedModelName(record, relationName){
let ParentModelClass = record.constructor;
let meta = get(ParentModelClass, 'relationshipsByName').get(relationName);
return meta.type;
}

Allowing users to only view data related to them in Apache Superset

I have some information related to different vendors in my database and I want to allow each registered vendor (representative person) to view slices/dashboards which contains only data related to them.
One possible solution could be to create separate views for each vendor as well as separate roles for each vendor. But it feels like a bad idea if you have 100+ vendors (as is my case); and it's not a flexible or scalable solution.
Is there some way to automatically filter a given view for each user? For example, we have a "general profit by product" bar chart, and user X can see only products of vendor X
What you're looking for is multi-tenancy support, and this is not currently supported out-of-the-box in Superset.
There is however an open PR for one possible solution: https://github.com/apache/incubator-superset/pull/3729
One option could be to re-use and/or adapt that code for your use-case.
Another option might be to look into JINJA_CONTEXT_ADDONS [https://github.com/apache/incubator-superset/blob/master/docs/installation.rst#sql-lab] and see whether you might be able to pass additional context to your query (e.g. your vendor_id) and restrict the scope of your query using that parameter.
Superset config has the below two configurations(DB_CONNECTION_MUTATOR, SQL_QUERY_MUTATOR), which can allow for multi-tenancy to an extent.
A callable that allows altering the database conneciton URL and params
on the fly, at runtime. This allows for things like impersonation or
arbitrary logic. For instance you can wire different users to
use different connection parameters, or pass their email address as the
username. The function receives the connection uri object, connection
params, the username, and returns the mutated uri and params objects.
Example:
def DB_CONNECTION_MUTATOR(uri, params, username, security_manager, source):
user = security_manager.find_user(username=username)
if user and user.email:
uri.username = user.email
return uri, params
Note that the returned uri and params are passed directly to sqlalchemy's
as such create_engine(url, **params)
DB_CONNECTION_MUTATOR = None
A function that intercepts the SQL to be executed and can alter it.
The use case is can be around adding some sort of comment header
with information such as the username and worker node information
def SQL_QUERY_MUTATOR(sql, username, security_manager):
dttm = datetime.now().isoformat()
return f"-- [SQL LAB] {username} {dttm}\n{sql}"
SQL_QUERY_MUTATOR = None
One easy way of solving this problem is by using pre-defined JINJA parameters.
Two parameters that can be used are '{{current_username() }}' and {{current_user_id() }}
First you need to ensure that you can use JINJA templates -
In superset_config.py add the following
FEATURE_FLAGS = {
"ENABLE_TEMPLATE_PROCESSING": True,
}
Restart
Now if you go to the SQL LAB and type the following -
SELECT '{{ current_username() }}',{{ current_user_id() }};
You should get an output
?column?
?column?__1
PayalC
5
Now all you have to do is append one of the two following sql snippet in all your queries.
select ........ from ...... where ...... vendorid={{ current_user_id() }}
select ........ from ...... where ...... vendorname='{{ current_username() }}'
vendorid={{ current_user_id() }} and/or
vendorname='{{ current_username() }}' will restrict the user to view only her data.
You could also make it more flexible by creating a table which has a mapping of user to vendorid. That table can be your added to all the queries and you could map multiple vendors to a single user or even all vendors to a single user for a super admin.

Django - How to access the verbose_name of a Model in its Admin Module?

How to access the verbose_name of a Model in its Admin Module? We can access the same if we have an instance of that model like below.
instance._meta.verbose_name.title()
Model._meta.verbose_name.title()
and
Model._meta.verbose_name_plural.title()
return singular and plural Model's verbose names accordingly. There's also Model._meta.verbose_name_raw property, it seems to return unicode string for me, while verbose_name.title() returns a normal string, but I'm not sure what's the real difference between this and verbose_name.title().
Model._meta.verbose_name.title() returns verbose name with First Character Uppercase while Model._meta.verbose_name_raw property returns the verbose name you wrote in the model class.