Developing on CTFd
Developing new code for CTFd is easy and fun! CTFd is organized into components which each serve a distinct purpose.
The core routes are identified in blueprints in the main CTFd folder for user facing routes and in the CTFd/admin folder for the admin panel. These core routes are used to display theme content and render the main server response that the user will receive.
The API routes are implemented in the
CTFd/api folder as seperate
blueprints for each type of resource used in CTFd. Most behavior that
manipulates data should be implemented at the API level and seperated by
method and resource level. The most common API methods are
CTFd makes heavy usage of the SQLAlchemy ORM to access database contents. The core CTFd models are defined here. Plugins are however capable of adding their own models.
CTFd makes use of
Flask-Migrate to perform database
migrations between versions.
Schemas provide an abstraction layer on top of the database models for permissioning and filtering of data. Schemas and the API work together to make distinctions about what data to show users and what data a user can edit.
Python code in CTFd is linted with flake8, isort, and black.
TipThe recommendation is to integrate all linters into your editor as your changes will fail to pass if the lint checks fail. See the
Python tests are run using
pytest on Github Actions. To run the test
suite locally you can run make test. By default tests run against sqlite
but this can be configured by setting the
CTFd v3 is Python 3 only. CTFd v2 supported Python 2 and 3.
Tests are run in parallel with
pytest-xdist and each test is run in
isolation from other tests by creating it’s own database and CTFd instance.
To build the documentation, you should go to the documentation repo and follow the build instructions there.
Tips & Tricks
Typically while developing CTFd, developers use the provided
script or its
make serve wrapper and access CTFd at
Very often you will need to generate testing data so that you can
exercise CTFd’s behavior. The included
populate.py script will insert
randomized testing data into the CTFd database.
export.py script can be used to create a CTFd export on the
import.py script can be used to load in a CTFd export on the
If you need to wipe CTFd completely, you should:
- delete the database (CTFd/ctfd.db by default)
- empty the cache. By default it will be stored in the
.datafolder if Redis is unavailable
- (optional) remove the contents of the CTFd/uploads folder
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.