1from __future__ import annotations
2
3import binascii
4import os
5import uuid
6from datetime import datetime
7from uuid import UUID
8
9from plain import models
10from plain.models import types
11
12
13def generate_token() -> str:
14 return binascii.hexlify(os.urandom(20)).decode()
15
16
17@models.register_model
18class APIKey(models.Model):
19 uuid: UUID = types.UUIDField(default=uuid.uuid4)
20 created_at: datetime = types.DateTimeField(auto_now_add=True)
21 updated_at: datetime = types.DateTimeField(auto_now=True)
22 expires_at: datetime | None = types.DateTimeField(required=False, allow_null=True)
23 last_used_at: datetime | None = types.DateTimeField(required=False, allow_null=True)
24
25 name: str = types.CharField(max_length=255, required=False)
26
27 token: str = types.CharField(max_length=40, default=generate_token)
28
29 api_version: str = types.CharField(max_length=255, required=False)
30
31 query: models.QuerySet[APIKey] = models.QuerySet()
32
33 model_options = models.Options(
34 constraints=[
35 models.UniqueConstraint(
36 fields=["uuid"], name="plainapi_apikey_unique_uuid"
37 ),
38 models.UniqueConstraint(
39 fields=["token"], name="plainapi_apikey_unique_token"
40 ),
41 ],
42 )
43
44 def __str__(self) -> str:
45 return self.name or str(self.uuid)