schemas.py – Define validation for endpoint query parameters
This file contains the models we use for post requests and for type checking throughout the application. These object models should be used wherever possible to ensure consistency
Imports
These are listed in the order prescribed by PEP 8.
Standard library
Third-party imports
Local application imports
None.
Schema generation
Change the BaseModel.from_orm
method to return None
if the input was None
, instead of a class full of variables set to None
.
Enable ORM mode.
This creates then returns a Pydantic schema from a SQLAlchemy Table or ORM class.
This is copied from https://github.com/tiangolo/pydantic-sqlalchemy/blob/master/pydantic_sqlalchemy/main.py then lightly modified.
The SQLAlchemy model – either a Table object or a class derived from a declarative base.
An optional Pydantic model config class to embed in the resulting schema.
The base class from which the Pydantic model will inherit.
SQLAlchemy fields to exclude from the resulting schema, provided as a sequence of field names. Ignore the id field by default.
If provided an ORM model, get the underlying Table object.
Determine the name of this column.
Determine the Python type of the column.
Determine if the column can be null, meaning it’s optional from a Pydantic perspective. Make the id column optional, since it won’t be present when inserting values to the database.
Determine the default value for the column. Allow the id column to be null.
Build the schema based on this info.
See create_model.
Schemas
This class defines the schema for what we can expect to get from a logging event. Because we are using pydantic type verification happens automatically, if we want to add additional constraints we can do so.
used by parsons
used by dnd
used by unittest
used by timed exam
return datetime.fromisoformat(v)
@validator(“deadline”) def str_to_datetime(cls, value: str) -> datetime:
# TODO: this code probably doesn’t work. try:
deadline = parse(canonicalize_tz(value)) # TODO: session isn’t defined. Here’s a temporary fix # tzoff = session.timezoneoffset if session.timezoneoffset else 0 tzoff = 0 deadline = deadline + timedelta(hours=float(tzoff)) deadline = deadline.replace(tzinfo=None)
- except Exception:
# TODO: can this enclose just the parse code? Or can an error be raised in other cases? raise ValueError(f”Bad Timezone - {value}”)
return deadline
Schemas for Completion Data
todo: this should really be an int
We can automatically create the aliases!
class Config:
alias_generator = camelize
class LastPageData(BaseModelNone):
last_page_url: str
course_name: str = Field(None, alias="course_id")
completion_flag: int
last_page_scroll_location: int
last_page_chapter: str
last_page_subchapter: str
last_page_accessed_on: datetime
user_id: int
class SelectQRequest(BaseModel):
selector_id: str
questions: Optional[str]
proficiency: Optional[str]
points: Optional[int]
min_difficulty: Optional[float]
max_difficulty: Optional[float]
not_seen_ever: Optional[bool]
autogradable: Optional[bool]
primary: Optional[bool]
AB: Optional[str]
toggleOptions: Optional[str]
timedWrapper: Optional[str]
limitBaseCourse: Optional[str]
class PeerMessage(BaseModel):
type: str
sender: str
message: str
broadcast: bool