I’ve added an ActivityPub plugin so content here will easily be shared on the fediverse, hopefully.
You can follow me @uda@x59.co
Me, the Internet and more
I’ve added an ActivityPub plugin so content here will easily be shared on the fediverse, hopefully.
You can follow me @uda@x59.co
If you aren’t familiar with Python, FastAPI or Timezones, this might not be the post for you, sorry.
For the rest of you geeks (like me), here is an example how to validate supported timezones in an input (Query, Path etc.). Scratch that, this is about how to validate dynamic lists of values in FastAPI by using timezones as an example.
As you know, in FastAPI you can validate predefined values by using String Enums (A class sub-classed from str
and Enum
), so how do you validate dynamic lists of values?
According to the docs, this is how you create a dynamic Enum
:
>>> from datetime import timedelta
>>> class Period(timedelta, Enum):
... "different lengths of time"
... _ignore_ = 'Period i'
... Period = vars()
... for i in range(367):
... Period['day_%d' % i] = i
The _ignore_
part is to remove the variable generated by the property Period
and the for
loop, of course.
Back to Timezones, according to the docs you can get the list of timezones supported by the locally installed IANA timezone DB:
import zoneinfo
zoneinfo.available_timezones()
And to our mini validation example:
import zoneinfo
from datetime import datetime
from enum import Enum
from fastapi import FastAPI, Query
app = FastAPI()
class Timezone(str, Enum):
_ignore_ = 'Timezone z'
Timezone = vars()
for z in zoneinfo.available_timezones():
Timezone[z] = z
@app.get('/')
def get_time(zone: Timezone = Query(Timezone.UTC)):
return {'now': datetime.now(tz=zoneinfo.ZoneInfo(zone))}
This way you can accept a timezone string, but not inserting it into any function without validating it is a string you can trust, and in the same time you don’t have to maintain that list on your own.
Remember #1: that the timezone list is recalculated every time the function is called (app start in this case), so if you run this directly on a machine, remember to restart the app after updating the timezone DB.
Remember #2: that most of the Enum
items aren’t accessible in the class instance notation, Timezone.America/New_York
, but you can access it using the dict notation Timezone['America/New_York']
, The common names of course are accessible, like Timezone.UTC
and Timezone.EST
.