Skip to content

Files

BaseFile

Bases: ResponseModel

A base file model. Not meant to be instantiated directly.

Parameters:

Name Type Description Default
id int

The ID of the file

required
type FileType

The type of the file

required
location str

The location of the file

required
sha1sum str

The SHA-1 checksum of the file

required

Attributes:

Name Type Description
id int

The ID of the file

type FileType

The type of the file

location str

The location of the file

sha1sum str

The SHA-1 checksum of the file

Source code in ctfdpy\models\files.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class BaseFile(ResponseModel):
    """
    A base file model. Not meant to be instantiated directly.

    Parameters
    ----------
    id : int
        The ID of the file
    type : FileType
        The type of the file
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file

    Attributes
    ----------
    id : int
        The ID of the file
    type : FileType
        The type of the file
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    """

    id: int = Field(frozen=True, exclude=True)
    type: FileType
    location: str
    sha1sum: str

StandardFile

Bases: BaseFile

Represents a standard file in CTFd.

This model cannot be edited since there is no endpoint to update files in CTFd.

Parameters:

Name Type Description Default
id int

The ID of the file

required
type Literal[STANDARD]

The type of the file. This should always be "standard"

required
location str

The location of the file

required
sha1sum str

The SHA-1 checksum of the file

required

Attributes:

Name Type Description
id int

The ID of the file

type Literal[STANDARD]

The type of the file. This should always be "standard"

location str

The location of the file

sha1sum str

The SHA-1 checksum of the file

Source code in ctfdpy\models\files.py
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class StandardFile(BaseFile):
    """
    Represents a standard file in CTFd.

    This model cannot be edited since there is no endpoint to update files in CTFd.

    Parameters
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.STANDARD]
        The type of the file. This should always be `"standard"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file

    Attributes
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.STANDARD]
        The type of the file. This should always be `"standard"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    """

    type: Literal[FileType.STANDARD]

ChallengeFile

Bases: BaseFile

Represents a challenge file in CTFd.

This model cannot be edited since there is no endpoint to update files in CTFd.

Parameters:

Name Type Description Default
id int

The ID of the file

required
type Literal[CHALLENGE]

The type of the file. This should always be "challenge"

required
location str

The location of the file

required
sha1sum str

The SHA-1 checksum of the file

required
challenge_id int

The ID of the challenge associated with the file

required
challenge int

Alias for challenge_id

required

Attributes:

Name Type Description
id int

The ID of the file

type Literal[CHALLENGE]

The type of the file. This should always be "challenge"

location str

The location of the file

sha1sum str

The SHA-1 checksum of the file

challenge_id int

The ID of the challenge associated with the file

Source code in ctfdpy\models\files.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
class ChallengeFile(BaseFile):
    """
    Represents a challenge file in CTFd.

    This model cannot be edited since there is no endpoint to update files in CTFd.

    Parameters
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.CHALLENGE]
        The type of the file. This should always be `"challenge"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    challenge_id : int
        The ID of the challenge associated with the file
    challenge : int
        Alias for `challenge_id`

    Attributes
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.CHALLENGE]
        The type of the file. This should always be `"challenge"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    challenge_id : int
        The ID of the challenge associated with the file
    """

    type: Literal[FileType.CHALLENGE]
    challenge_id: int = Field(
        validation_alias=AliasChoices("challenge_id", "challenge")
    )

PageFile

Bases: BaseFile

Represents a page file in CTFd.

This model cannot be edited since there is no endpoint to update files in CTFd.

Parameters:

Name Type Description Default
id int

The ID of the file

required
type Literal[PAGE]

The type of the file. This should always be "page"

required
location str

The location of the file

required
sha1sum str

The SHA-1 checksum of the file

required
page_id int

The ID of the page associated with the file

required
page int

Alias for page_id

required

Attributes:

Name Type Description
id int

The ID of the file

type Literal[PAGE]

The type of the file. This should always be "page"

location str

The location of the file

sha1sum str

The SHA-1 checksum of the file

page_id int

The ID of the page associated with the file

Source code in ctfdpy\models\files.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class PageFile(BaseFile):
    """
    Represents a page file in CTFd.

    This model cannot be edited since there is no endpoint to update files in CTFd.

    Parameters
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.PAGE]
        The type of the file. This should always be `"page"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    page_id : int
        The ID of the page associated with the file
    page : int
        Alias for `page_id`

    Attributes
    ----------
    id : int
        The ID of the file
    type : Literal[FileType.PAGE]
        The type of the file. This should always be `"page"`
    location : str
        The location of the file
    sha1sum : str
        The SHA-1 checksum of the file
    page_id : int
        The ID of the page associated with the file
    """

    type: Literal[FileType.PAGE]
    page_id: int = Field(validation_alias=AliasChoices("page_id", "page"))

CreateFilePayload

Bases: CreatePayloadModel

Payload to create files in CTFd

Parameters:

Name Type Description Default
files list[MultipartFileTypes]

The files to create

required
type FileType

The type of the files

required
challenge_id int | None

The ID of the challenge associated with the files. Required if type is "challenge"

required
challenge int | None

Alias for challenge_id

required
page_id int | None

The ID of the page associated with the files. Required if type is "page"

required
page int | None

Alias for page_id

required
location str | None

The location to upload the files to. Cannot be specified if multiple files are provided

required

Attributes:

Name Type Description
files list[MultipartFileTypes]

The files to create

type FileType

The type of the files

challenge_id int | None

The ID of the challenge associated with the files. Required if type is "challenge"

page_id int | None

The ID of the page associated with the files. Required if type is "page"

location str | None

The location to upload the files to. Cannot be specified if multiple files are provided

Source code in ctfdpy\models\files.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
class CreateFilePayload(CreatePayloadModel, arbitrary_types_allowed=True):
    """
    Payload to create files in CTFd

    Parameters
    ----------
    files : list[MultipartFileTypes]
        The files to create
    type : FileType
        The type of the files
    challenge_id : int | None
        The ID of the challenge associated with the files. Required if `type` is `"challenge"`
    challenge : int | None
        Alias for `challenge_id`
    page_id : int | None
        The ID of the page associated with the files. Required if `type` is `"page"`
    page : int | None
        Alias for `page_id`
    location : str | None
        The location to upload the files to. Cannot be specified if multiple files are provided

    Attributes
    ----------
    files : list[MultipartFileTypes]
        The files to create
    type : FileType
        The type of the files
    challenge_id : int | None
        The ID of the challenge associated with the files. Required if `type` is `"challenge"`
    page_id : int | None
        The ID of the page associated with the files. Required if `type` is `"page"`
    location : str | None
        The location to upload the files to. Cannot be specified if multiple files are provided
    """

    files: list[MultipartFileTypes]  # this might be slow...
    type: FileType = FileType.STANDARD
    challenge_id: int | None = Field(
        None, validation_alias=AliasChoices("challenge_id", "challenge")
    )
    page_id: int | None = Field(None, validate_alias=AliasChoices("page_id", "page"))
    location: str | None = Field(None)

    @model_serializer()
    def _model_ser(self) -> CreateFilePayloadDict:
        data = {"type": self.type}
        if self.challenge_id is not None:
            data["challenge_id"] = self.challenge_id
        if self.page_id is not None:
            data["page_id"] = self.page_id
        if self.location is not None:
            data["location"] = self.location

        return {"files": [("file", file) for file in self.files], "data": data}

    if TYPE_CHECKING:
        # Ensure type checkers see the correct return type
        def model_dump(
            self,
            *,
            mode: Literal["json", "python"] | str = "python",
            include: Any = None,
            exclude: Any = None,
            by_alias: bool = False,
            exclude_unset: bool = False,
            exclude_defaults: bool = False,
            exclude_none: bool = False,
            round_trip: bool = False,
            warnings: bool = True,
        ) -> CreateFilePayloadDict: ...

    @model_validator(mode="after")
    def check_file_type(self) -> CreateFilePayload:
        match self.type:
            case FileType.STANDARD:
                if self.challenge_id is not None or self.page_id is not None:
                    raise ValueError(
                        "Challenge ID and page ID must be None for standard files"
                    )
            case FileType.CHALLENGE:
                if self.challenge_id is None:
                    raise ValueError(
                        "Challenge ID must be provided for challenge files"
                    )
                if self.page_id is not None:
                    raise ValueError("Page ID must be None for challenge files")
            case FileType.PAGE:
                if self.page_id is None:
                    raise ValueError("Page ID must be provided for page files")
                if self.challenge_id is not None:
                    raise ValueError("Challenge ID must be None for page files")
        return self

    @model_validator(mode="after")
    def check_file_count(self) -> CreateFilePayload:
        if len(self.files) == 0:
            raise ValueError("At least one file must be provided")
        elif len(self.files) > 1 and self.location is not None:
            raise ValueError(
                "Location cannot be specified when multiple files are provided"
            )
        return self