Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add roles support #684

Closed
wants to merge 1 commit into from
Closed

Add roles support #684

wants to merge 1 commit into from

Conversation

Bobronium
Copy link
Contributor

Change Summary

Got working implementation of what @JrooTJunior has mentioned in #660 (comment) so far

Before moving on I'd love to know what you think about questions down below and changes in general

Questions

  • Should roles support nested models?
    • If they are, what to do if role doesn't exist in sub-models config (should we check somehow that now we exporting a sub-model?)
  • How it should behave when params included in role also given to export method? Now params specified in role will be overwritten by method params.

Working demo from #660 (comment):

import datetime
from typing import Optional, List

from pydantic import BaseModel

class Article(BaseModel):
    id: int
    label: str
    text: Optional[str]

class User(BaseModel):
    id: int
    login: str
    email: str
    password: str
    first_name: str
    last_name: Optional[str] = None
    articles: Optional[List[Article]] = None
    register_date: datetime.datetime
    last_login: Optional[datetime.datetime] = None

    class Config:
        roles = {
            "self": {"exclude": {"password", "register_date", "last_login"}},
            "admin": {"exclude": {"password"}},
            "public": {"include": {"id", "email", "first_name", "last_name"}}
        }

user = User(
    id=42,
    login="mylogin",
    email="email@example.com",
    password="hashed secret password",
    first_name="Some",
    last_name="User",
    articles=[Article(id=1, label="foo"), Article(id=2, label="bar")],
    register_date=datetime.datetime.now(),
    last_login=datetime.datetime.now()
)

for role in User.Config.roles:
    print(f'{role}: {user.json(role=role, indent=4)}\n')
Outputs:
self: {
    "id": 42,
    "login": "mylogin",
    "email": "email@example.com",
    "first_name": "Some",
    "last_name": "User",
    "articles": [
        {
            "id": 1,
            "label": "foo",
            "text": null
        },
        {
            "id": 2,
            "label": "bar",
            "text": null
        }
    ]
}

admin: {
    "id": 42,
    "login": "mylogin",
    "email": "email@example.com",
    "first_name": "Some",
    "register_date": "2019-07-25T03:49:59.573446",
    "last_name": "User",
    "articles": [
        {
            "id": 1,
            "label": "foo",
            "text": null
        },
        {
            "id": 2,
            "label": "bar",
            "text": null
        }
    ],
    "last_login": "2019-07-25T03:49:59.573452"
}

public: {
    "id": 42,
    "email": "email@example.com",
    "first_name": "Some",
    "last_name": "User"
}

Related issue number

#660

Checklist

  • Unit tests for the changes exist
  • Tests pass on CI and coverage remains at 100%
  • Documentation reflects the changes where applicable
  • HISTORY.rst has been updated
    • if this is the first change since a release, please add a new section
    • include the issue number or this pull request number #<number>
    • include your github username @<whomever>

@codecov
Copy link

codecov bot commented Jul 25, 2019

Codecov Report

Merging #684 into master will decrease coverage by 0.25%.
The diff coverage is 50%.

@@            Coverage Diff             @@
##           master     #684      +/-   ##
==========================================
- Coverage     100%   99.74%   -0.26%     
==========================================
  Files          15       15              
  Lines        2719     2723       +4     
  Branches      538      540       +2     
==========================================
- Hits         2719     2716       -3     
- Misses          0        4       +4     
- Partials        0        3       +3

@JrooTJunior
Copy link

  • If they are, what to do if role doesn't exist in sub-models config

I see three ways:

  1. Raise an exception with information about "Nested model {model} doesn't have {role} role" or something like that
  2. Export nested model with all fields
  3. Add "default" role. if custom role is not specified in nested model should use the default. By default "default" include all fields and if "default" is overriden then use this changed default role. Or.. Maybe.. If default is not specified will raise exception but in other cases use this role

@samuelcolvin
Copy link
Member

leaving this open, but not reviewing yet. I'll give my opinions/suggestions on #660.

@samuelcolvin
Copy link
Member

closing as per my comments on #660.

@orfisko
Copy link

orfisko commented Oct 17, 2021

@tiangolo , I think fast api would really benefit from this feature. Having different roles and excluding fields based on them is, to me at least, a must have ....

alexdrydew pushed a commit to alexdrydew/pydantic that referenced this pull request Dec 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants