Create pydantic model for Optional field with alias - python

Pydantic model for compulsory field with alias is created as follows
class MedicalFolderUpdate(RWModel):
id : str = Field(alias='_id')
university : Optional[str]
How to add optional field university's alias name 'school' as like of id?

It is not documented on the Pydantic website how to use the typing Optional with the Fields Default besides their allowed types in which they include the mentioned Optional:
Optional[x] is simply shorthand for Union[x, None]; see Unions below for more detail on parsing and validation and Required Fields for details about required fields that can receive None as a value.
for that, you would have to use their field customizations as in the example:
class Figure(BaseModel):
name: str = Field(alias='Name')
edges: str = Field(default=None, alias='Edges')
without the default value, it breaks because the optional does not override that the field is required and needs a default value. Which is the solution I used to overcome this problem while using Pydantic with fast API to manage mongo resources

Related

What is the point of using `MISSING` in hydra or pydantic?

I am creating a configuration management system in python and are exploring options between hydra/pydantic/both. I get a little confused over when to use MISSING versus just leaving it blank/optional. I will use an example of OmegaConf here since
the underlying structure of hydra uses it.
#dataclass
class User:
# A simple user class with two missing fields
name: str = MISSING
height: Height = MISSING
where it says that this MISSING field will convert to yaml's ??? equivalent. Can I just leave it blank?

Pydantic schema logic

So, I'm building an API to interact with my personal wine labels collections database.
For what I understand, a pydantic model purpose is to serve as a "verifier" of the schema that is sent to the API. So, my pydantic schema for adding a label is the following:
from pydantic import BaseModel
from typing import Optional
class WineLabels(BaseModel):
name: Optional[str]
type: Optional[str]
year = Optional[int]
grapes = Optional[str]
country = Optional[str]
region = Optional[str]
price = Optional[float]
id = Optional[str]
None of the fields is to be updated automatically. This is equal to the sqlalchemy model since I want to add all the fields manually.
So my question is, let's say I want to create a call to search by ID and another one to search by name. I do not believe these schema should be applied. Should I create another schema ? Should I create one like this?:
class SearchWineLabel(WineLabels):
id: str
Should a schema be created for each purpose that cannot be fulfilled by an already existing schema?
Sorry, but I can't understand the logic behind it.
Thanks!!
If you want to search by id or name, I'm not sure if you even need a schema - one or more get parameters would usually be enough in those cases (and is usually better semantically).
In any case, the schema would be written for what the endpoint is expected to receive, not by using a general schema that contains the field in some other way. Think of the schemas as the input/output definitions for given resources and endpoints.
You usually want to have different schemas for adding and updating (since adding will require certain fields to be present, while updating may allow null or a missing field in any location).
The Pydantic schemas will allow you to express these differences without writing code, and it will be reflected in your generated api docs under /docs

mypy and Django type checking

I'm trying to enable type hints for my Django REST project. I installed django-stubs and djangorestframework-stubs and I have the following mypy.ini file:
[mypy]
plugins =
mypy_django_plugin.main
mypy_drf_plugin.main
[mypy.plugins.django-stubs]
django_settings_module = "core.settings.base"
Some of the type hints do work; for example, if I have a variable inside of a method whose type is a model class, I get hints when I try to access a field or method defined on it.
However, if I try to access a Django-specific field on the model, for example a reverse relation, that does not typecheck and gives me an error. Moreover, if I try to access fields on a related model of my model variable, the related object has type Any
For example, with these two models:
class User(models.Model):
name = models.TextField()
role = models.ForeignKey(Role) # definition of Role model not relevant
class Badge(models.Model):
user = models.ForeignKey(User, related_name="badges")
then this will happen:
u: User = get_user()
print(u.name) # correctly hinted and typechecks
print(u.badges.all()) # type error
print(u.role.pk) # no hint on role.pk, role is Any
How do I get my project to correclty type check all the Django-specific features such as foreign key fields, querysets, and reverse relationships?

What's the diference between 'normal' Python Classes and Pydantic Classes?

I would like to know the difference between classes built normally in python and those built with the Pydantic lib, for example:
eg normal;
class Node:
def __init__(self, chave=None, esquerda=None, direita=None):
self.chave = chave
self.esquerda = esquerda
self.direita = direita
eg pydantic;
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel
class User(BaseModel):
id: int
name = 'John Doe'
signup_ts: Optional[datetime] = None
friends: List[int] = []
There are a few main differences.
Firstly, purpose. Pydantic models are designed to:
Data validation and settings management using python type annotations.
pydantic enforces type hints at runtime, and provides user friendly errors when data is invalid.
When you use type annotations you receive a lot of validators and some useful methods out of the box.
As Ahmed and John says, in your example you can't assign “hello” to id in BaseModel (pydantic) because you type id as an int. But you can pass a string “1” (must be a numerical, not float) and it will be mapped to int. In this case:
pydantic uses int(v) to coerce types to an int; see this warning on loss of information during data conversion
Also Pydantic models allows you to use many more types than standard python types, like urls and much more. It means that you can easily validate more data types.
You can easily create complex models using composition.
Pydantic has some kind of integration with orms: docs
There are a lot of other features, much more than I can describe in a single answer. I strongly recommend reading the documentation, it is very clear and useful.
The pydantic models are very useful for example in building microservices where you can share your interfaces as pydantic models. Also all models can easily generate the json schema. See: Schema, exporting models.
Pydantic is also a big part of a growing in popularity python web framework fastapi.

How to set a default value for a field in graphene

I am experimenting with graphene in setting
1.) A default value for a field (just like how defaultdict works in python)
Ex :-
Class something(graphene.ObjectType):
FieldA = graphene.Float() or return a defaultValue
2.) Set a field of multiple type
Ex:-
Class something(graphene.ObjectType):
FieldA = graphene.Float() or graphene.String() or None
I am new to graphene & I am going through the documentation.
Any help/pointer is appreciated in getting the above 2 done.
1. For default values...
The docs don't do a great job of showing examples but the info you need is here: https://docs.graphene-python.org/en/latest/types/scalars/
All Scalar types accept the following arguments. All are optional:
name: string
Override the name of the Field.
description: string
A description of the type to show in the GraphiQL browser.
required: boolean
If True, the server will enforce a value for this field. See NonNull.
Default is False.
deprecation_reason: string
Provide a deprecation reason for the Field.
default_value: any
Provide a default value for the Field.
i.e. you can do:
class Something(graphene.ObjectType):
field_a = graphene.Float(default_value=1.23)
(note the capitalization: class keyword must be lowercase in Python, while Something class name, by convention, should be "camel case" i.e. first letter of each word capitalized, also by convention the field_a attribute should be "snake case" i.e. all lower-case with underscores as word separator)
2. For field of multiple types...
The info you need is here: https://docs.graphene-python.org/en/latest/types/unions/
i.e. you can do:
class StringOrFloat(graphene.Union):
class Meta:
types = (graphene.String, graphene.Float)
class Something(graphene.ObjectType):
field_a = StringOrFloat()

Categories