The MANTIS Cyber-Intelligence Management Framework

The MANTIS (Model-based Analysis of Threat Intelligence Sources) Framework consists of several Django Apps that, in combination, support the management of cyber threat intelligence expressed in standards such as STIX, CybOX, OpenIOC, IODEF (RFC 5070), etc.

Important resources:

  • Access to the Mantis source code for installation:

  • There is a mailing list for dicussions, questions, etc.:

    • Subscribe to the mailing list by sending a mail to
    • The archives of the mailing list are available via Nabble.

    Many thanks to the TF-CSIRT Trusted Introducer for their support in hosting the list!

  • All issues regarding Mantis and its components are tracked on the Mantis Issue Tracker.

  • Documentation:

    MANTIS Architecture

    The MANTIS (Model-based Analysis of Threat Intelligence Sources) Framework consists of several Django Apps that, in combination, support the management of cyber threat intelligence expressed in standards such as STIX, CybOX, OpenIOC, IODEF (RFC 5070), etc.

    The heavy lifting is done in the following Django Apps:


    MANTIS architecture


    To get an idea of what MANTIS currently provides, take a look at the following screenshots.


    Django’s standard login screen, rendered with the Grappelli skin that is used by Mantis. You can customize Django to do authentication differently (see the Django documentation on customizing authentication.)


    The login screen

    Viewing imported information objects

    The screenshot below shows the overview of imported information objects right after import of MITRE’s conversion of the MITRE STIX conversion of APT-1 report. We imported the top-level STIX package and the Appendix G with full indicators of compromise (i.e., Mandiant OpenIOC is embedded into the STIX XML). The count shows a quite large number of objects, and we obviously need a way to find our way around. So in the next step, we filter the list a bit.


    The list of information objects (standard URL: /mantis/View/InfoObject)


    The filter box on the page showing the information object list allows filtering with respect to several commonly used criteria. Here, we filter by information object type, and chose the STIX_Package.


    Filtering with respect to information object types

    Filtering results for STIX_Packages yields two results: the package that represents the top-level of the APT-1 report and the package that represents appendix G.


    Result of filtering for STIX_Packages

    Viewing an info object

    Clicking on the STIX package for the top-level of the APT-1 report shows MANTIS’s representation of the info object:


    View of STIX package presenting top-level of APT 1 report

    • At the top, we have identifiying information.

    • The bulk of the display in the center concerns the facts contained in the object (the color coding shows the structuring of the facts – it takes a bit of getting used to ... but this is just a view after all: you can create a view that suits you better.)

      The fact values that appear in blue are actually links to other info objects that have been extracted from the STIX package. You see two objects called PLACEHOLDER: as it turns out, the STIX package references these two objects without actually defining them. Would they be imported at a later point of time (identified by identifier and namespace of the identifier), the placeholders would be overwritten.

    • The view also shows the marking that has been extracted and associated with this info object and all other info objects extracted from the STIX package.

    • Curently, there is a single revision of the object in the system. If there were more revisions, these would be shown (as well as whether the revision you are looking at is the most recent revision).

    • This information object is not embedded in another info object; if it were, information about these objects would be displayed.

    Viewing another info object

    Clicking on the value of the third fact with fact term TTPs\TTP, we see the facts contained in this info object ... and now there is also information about info objects in which this info object is embedded.


    Viewing a TTP object. Standard URL for viewing is mantis/View/InfoObject/<object-nr>

    Clicking once more, this time into an address object (here, the pre-defined naming schema did not work and produced the name AddressObject (4 facts) – but you can configure additional naming schemas), we view another info object:


    Viewing an address object

    Again, we have information about which objects this particular object is embedded in: we get two results, and two times the same object, because it has been referenced two times (once by mistake, it seems.)

    Viewing the JSON representation

    Mantis stores objects internally as lists of facts (refer to the DINGOS model description to learn more about the internal data model), but can also produce a JSON representation of each object.


    JSON representation of a STIX TTP object. Standard url is mantis/View/InfoObject/<object-nr>/json

    Unfortunately, the JSON representation has still a slight problem: in the last few lines, the identifiers for @phase_id and @kill_chain_id would have to be treated akin to the “normal” references using idref.

    Dealing with embeddings of different standards

    STIX is very flexible and allows the embedding of other standards, such as Mandiant’s OpenIOC. For example, the MITRE STIX conversion of APT-1 report contains one version of the “Appendix G”, that contains embedded OpenIOC indicators. The Mantis STIX importer recognizes such occurrences and hands off to the Mantis OpenIOC importer.


    STIX indicator with embedded OpenIOC indicator (fact with fact term Test_Mechanisms/Test_Mechanism/ioc).

    Clicking on the embedded ioc object (here, the naming went wrong, it should display the value of the short_description element in the IOC) in line Test_Mechanisms/Test_Mechanism/ioc yields a view of the imported OpenIOC info object.


    An OpenIOC indicator

    Searching and viewing results

    We also can search for facts:


    Searching for values

    The search page allows us to search for values, e.g. the word ugly. This yields several results. The display shows the info objects in which the value occurs, the info object type of these objects, and the fact term under which the value occurs.

    Clicking on one of the objects shows the object and marks in red the occurrence of the searched term.


    Viewing a search result

    Editing user-specific data

    Currently, each user can edit his user configurations and saved searches.

    Edit user configurations


    The view for editing the user configurations

    Currently, there is only a minimum of user configurations available – these will be extended in future releases of MANTIS. Also, the framework for managing user configurations is very flexible and can be used for own development (see the relevant documentation of DINGOS.)

    Edit user configurations


    The view for editing saved searches

    After pressing the ‘Save Search’ button on the filter view, users are presented with a view that allows them to add the new search and edit the exiting ones; the view is also available via the user-specific menu in the top right of the screen.

    A look at the admin interface

    Django features a very powerful admin interface. We us it to view and manage enumerables such as info object types, fact data types, etc.


    The Django admin interface with overview of DINGOS’s models

    For example, here the list of info object types in the system.


    Admin overview of the info object types

    Access to the info object types via the admin interface is especially relevant, because naming schemas that govern how objects are named are defined per info object type.


    Configuration of naming schemas for file objects

    What MANTIS is and isn’t


    • isn’t a finished tool or even project: we like to think that it provides a solid basis on which cyber-threat intelligence management can be built up upon, but if you expect something that out of the box covers all aspects of cyber-threat intelligence management, MANTIS isn’t for you.

    • (currently) isn’t a tool fit for importing huge datasets. It can import fairly large XML documents such as the MITRE STIX conversion of the APT-1 report, but this takes a while (expect 20-30 minutes or so.) So do not expect to be able to throw, e.g., dozens and dozens of MAEC files with sizes of several 100MBs into the system: the generic importer is not fit for such sizes.

      This situation may change at some point of time with more stream-lined importers, but MANTIS is really not intended to deal with very big data the way log management solutions such as Splunk et al. are.

    What MANTIS is:

    • MANTIS provides an example implementation of a framework for managing cyber threat intelligence expressed in standards such as STIX, CybOX, IODEF, etc. The aims of providing such an example implementation are:
      • To aide discussions about emerging standards such as STIX, CybOX et al. with respect to questions regarding tooling: how would a certain aspect be implemented, how do changes affect an implementation? Such discussions become much easier and have a better basis if they can be lead in the context of example tooling that is known to the community.
      • To lower the entrance barrier for organizations and teams (esp. CERT teams) in using emerging standards for cyber-threat intelligence management and exchange.
      • To provide a platform on the basis of which research and community-driven development in the area of cyber-threat intelligence management can occur.
    • Even though MANTIS is in no way a complete system, it already does cover a first use case: MANTIS provides an information repository into which cyber threat intelligence received in STIX/CybOX, OpenIOC and IODEF can be imported in a meaningful way that allows browsing, filtering and searching for information. Thus, MANTIS can be used as information base for keeping all the information you receive and information you generate yourself that is expressed in one of the currently supported standards. Because the importer is highly configurable, importers for other structured data should not be too difficult to write (and will hopefully be shared with the community ...).


    0.2.1 (2014-03-06)

    • Changed dependencies for Mantis components

      • Mantis now requires DINGOS in version 0.2.1. The differences to 0.2.0 are as follows:

        • Bugfixes

          • CRITICAL Remediation of painfully slow import for systems with lot’s of imported data

            An illformed query led to extremely slow import of new data in systems that already have lot’s of data inside. This bug has been fixed.

          • Problem in link to InfoObjects in which a certain fact can be found on Unique Search Page fixed

            The link was faulty in that it carried a ‘&page=...’ parameter that needed to be removed.

          • Long repetition of ‘_’ in a string lead to HTML display spilling over, because ‘_’ was not regarded as place to insert a possible line break. This has been changed.

        • New/Modified views

          • View for listing all InfoObjects, also those used internally by DINGOS for bookkeeping (e.g., user preferences). The view is restricted to Django-superusers.
        • New/Modified command-line commands

          • In ‘dingos_manage_user_settings’, added the ability to overwrite settings for ‘ALL’ users.

    0.2.0 (2014-02-26)

    • Changed dependencies for Mantis components

      • Mantis now requires DINGOS in version 0.2.0. The differences to 0.1.0 are as follows:

        • New base functionality

          • Added framework for managing user-specific data (user configurations, saved searches, etc.) and querying user-specific data in templates and views.
          • Added tracking of namespace information per component of a fact term
        • New/Modified views

          • Modifications to all views
            • Added possibility to switch between horizontal and vertical layout ... or have automatic adjustment of the layout depending on screen width.
          • Modifications to filter views
            • Modified date-picker in filters to enable addition of timespans without changing saved searches or messing up order of timespans
            • Added several further filter criteria in InfoObject filter
          • Added view with basic and still rather restricted editing capabilities for InfoObjects – currently only used for editing user preferences or edits by the superuser
          • Added view to edit user configuration
          • Added view to edit saved searches
          • Added per-column ordering to list views
          • Added new filter/search that shows unique Facts rather than all InfoObjects containing a certain fact.
        • New/added capabilities for writing views

          • Added framework for ordering list views
          • Added per-user configuration for:
            • layout (horizontal vs. vertical)
            • number of rows to show in list views
            • number of rows to show in widget displaying objects in which a displayed object is embedded
        • Bug fixes / Improvements

          • Generation of filter views became unbearably slow when many (> 40,000) InfoObjects are in the system. This was, because of a badly built query within the dynamically built filter form. This has been fixed.
          • Further development of JSON export (still needs work to make the to_dict function of InfoObjects generic and configurable such as the from_dict function)
          • Fixed bug in generation of InfoObjects: when a placeholder for a given ID already existed, it was not reliably found.
        • New/Modified command-line commands

          • Import command now fails gracefully if import of a file throws an exception: it continues with import of the next file.

          • Added command line arguments to basic import command:

            • ability to add IDs of marking objects to be added to imported objects
            • ability to automatically move imported XML files to other folder after import
          • Added command to reset user-settings and saved searches for a given user.

          • Added command to re-calculate object names.

            This is useful to run right after an import, recalculating the names of ‘Observable’ InfoObjects created in the past few minutes. Thus, the problem that those Observables that are to be named after the (single) object they contain do not carry a proper name (because at creation time of the Observable, the Object usually does not exist, yet) can be fixed.

      • Mantis now requires the Mantis-Core in version 0.2.0. The differences to 0.1.0 are as follows:

        • Added corresponding abstract model classes for models introduced in DINGOS 0.2.0.
      • Mantis now requires the STIX/CybOX Importer in version 0.2.0. The differences to 0.1.0 are as follows:

        • Added ability to generate identifier for top-level element (usually a STIX_Package) if an identifier for that element is missing: if a default namespace has been defined, then an identifier is generated by taking the MD5-hash of the xml file.

        • Markings present in STIX_Package are read out and attached to all InfoObjects generated from the STIX_Package.

          Note: Mantis does currently not interpret the XPATH expression that specifies the scope of the marking (which is not much of an issue, since it seems that the feature to restrict the scope of a marking is not much used at the moment).

        • Timestamp present in STIX_Header/Information_Source/Time/Produced_Time is read.

        • Added a command-line argument to add a default-timestamp to the STIX import command.

        • Bug fixes:

          • Attributes other than id and idref that contained a namespace were not handled correctly. The handler function attr_with_namespace_handler fixes this.
          • In 0.1.0, the xsi:type attribute was not recorded, because in most cases, its information is used for determining the data type of elements and InfoObjects. But there are cases, e.g., in Markings, where this is not the case. For these cases, the xsi:type attribute is kept in the InfoObject.
          • Family revision info was not recorded; this has been fixed.
      • Mantis now requires the OpenIOC Importer in version 0.2.0. The differences to 0.1.0 are as follows:

        • Fixed bug in import of timestamp.

    0.1.0 (2013-12-19)

    • Initial release


    Manual installation

    ATTENTION: Please do not use the master branch for fresh installs; use the development branch and follow the installation instructions outlined in the development branch

    The installation instructions below have been tested on an out-of-the-box installation of Ubuntu Desktop 12.04 LTS (the Desktop rather than the Server version has been used, since the majority of installs are likely to be for testing and developing, where having a full working environment and X-server installed comes in handy.) If you are using a different *nix flavor, you have to find the corresponding installation packages used with apt-get below – the installation steps carried out with pip, however, will be exactly the same.

    Attention: If you are setting up a virtual machine, make sure to give it at least 3GB of memory if you want to import really large XML structures such as MITRE’s STIX conversion of the Mandiant APT-1 report ( – importing large files currently takes a lot of memory – there seems to be a memory leak which we still have to track down.

    1. Make sure that you have the required dependencies on OS level for building the XML-related packages. For example, on an Ubuntu system, execute the following commands:

      $ apt-get install libxml2 libxml2-dev python-dev libxslt1-dev

      Also, while you are at it, install git, if you do not have it already:

      $ apt-get install git

      If you are behind a proxy, you can configure a proxy for apt-get by putting a file 95proxy into /etc/apt/apt.conf.d that has the following contents:

      Acquire::http::proxy "<proxy_url>";
      Acquire::ftp::proxy "<proxy_url>";
      Acquire::https::proxy "<proxy_url>";
    2. It is recommended to use a virtual python environment.

      • Make sure that virtualenv and pip are installed:

        $ apt-get install python-virtualenv python-pip
      • Create a virtual environment:

        $ virtualenv <path_for_storing_environments>/mantis
        $ source <path_for_storing_environments>/mantis/bin/activate

        Now the virtual environment is activated – you should see a changed prompt that is prefixed with (mantis)

    3. Install the libxml2-python bindings

      Unfortunately, the process of getting libxml2-python installed using pip varies from OS to OS, because there is no proper library package available.

      • For Ubuntu 12.04 do the following:

        Use pip to install directly from an ftp source:

        (mantis)$ pip install

        If you are behind a proxy, you can either provide pip with the proxy information with the commandline argument --proxy  <proxy_url> or use the http_proxy environment variable – do not do both, because this confuses pip.

        If the download does not work via pip, download the file with your browser, and install from file with pip install <filename>.

      • For Ubuntu 13.10, do the following:

        • Downloadand unpack the libxml2 sources:

          (mantis)$ wget"
          (mantis)$ tar -zxvf libxml2-2.9.1.tar.gz

          If you are behind a proxy, append -e use_proxy=yes -e http_proxy=<proxy_url> after the URL when calling wget.

        • Install via pip:

          (mantis)$ pip install libxml2-2.9.1/python

          If you are behind a proxy, you can either provide pip with the proxy information with the commandline argument --proxy  <proxy_url> or use the http_proxy environment variable – do not do both, because this confuses pip.

    4. Go to a location where you want to have the Django Mantis files and check out the git repository:

      (mantis)$ git clone

      If you are behind a proxy, you can configure a proxy for git via the following:

      (mantis)$ git config --global http.proxy <proxy_url>
    5. Change into the django-mantis directory and do:

      (mantis)$ pip install -r requirements/local.txt
      (mantis)$ pip install django-simple-menu>=1.0.6

      (For some reason, django-simple-menu cannot be installed before Django itself has not been installed completely).

    6. Your are now all set for running MANTIS on top of an SQLite database. If that is what you want to do, have a look at QUICKSTART.

    7. For running MANTIS on top of Postgresql (which is recommended), you need to install and prepare Postgresql:

      • Install it:

        $ apt-get install postgresql
        $ apt-get install postgresql-server-dev-9.1
      • Install the Python module for working with postgresql:

        (mantis)$ pip install psycopg2
      • In /etc/postgresql/9.1/main/postgresql.conf set ssl = False

      • (Re)start the server:

        /etc/init.d/postgresql start
      • Create password for postgresql: as root user, do:

        passwd postgres
      • Give the postgresql user a database password; As user postgres do:

        su postgres
        \password postgres;
      • Prepare database:

        • As user postgresql do:

          createuser -P mantis;

          and do the following:

          • give it password mantis
          • do not make it super user
          • allow it to create databases (required for running python unit tests). If you forgot about this step here, you can later run (ALTER USER mantis CREATEDB;) on the database prompt to achieve the same.
          • do not allow it to create new roles
      • In database, do:

        CREATE DATABASE django OWNER mantis ENCODING 'UTF-8';
      • In /etc/postgresql/9.1/main/pg_hba.conf enter after the line for the postgres user:

        # TYPE  DATABASE        USER            ADDRESS                 METHOD
        local [tab] django [tab] mantis [tab][tab]  md5
    8. Continue with the QUICKSTART.

    (Semi-)automated installation with Vagrant

    Vagrant allows automated provisioning of virtual machines with preconfigured packages, configuration settings, etc.

    (Development of Vagrant deployment scripts for Mantis is an ongoing effort. Scripts and documentation will be published as they become ready.)


    In the django-mantis folder, do the following:

    • For easy demo usage with SQLite, do:

      (mantis)$ bash

      (Note that this uses a SQLite database file located in the /tmp directory: any imports you do in Mantis will therefore not survive a system restart. You can move the location of the SQLite database by modifying the line reading '/tmp/django-mantis_test.db' in mantis/settings/

    • For usage with exisiting and configured postgresql database, do:

      (mantis)$  bash quickstart_psql

    The script will ask, whether at this stage, you want to create an administrative user for Django. Answer with *yes* and provide user name, email address and password.

    In detail, the bash script will do the following:

    1. Run the Django syncdb command, which
      1. creates tables for the models of all applications that are not using the Django South application for database migrations.
      2. asks you for user name, email address and password of an administrative Django user (you will need this username and password later to log on)
    2. Carry out (initial) database migrations for all MANTIS components using the South migrations that are part of the components’ distribution (in subdirectory migrations)
    3. Configure default naming schemata for the exisiting importer modules of MANTIS via calling the command mantis_<format>_set_naming for each such module
    4. Carry out the Django collect_static command, which copies over the static files for all applications to the static folder configured in the settings of MANTIS
    5. Show you (via the less command) this file and (after you quit less), print the file to the console
    6. Start the testing web server running MANTIS via Django’s runserver command on port 8000.

    Then try out the following:

    • Download: and extract the files

    • For the files Mandiant_APT1_Report.xml and Appendix_G_IOCs_Full.xml do the following:

      • If you are using sqllite:

        python mantis_stix_import --settings=mantis.settings.local  --trace\
            --marking_pfill=source "Mandiant APT 1 Report"\
      • If you are using postgresql:

        python mantis_stix_import --settings=mantis.settings.local_psql  --trace\
            --marking_pfill=source "Mandiant APT 1 Report"\

      Start with Mandiant_APT1_Report.xml: that goes relatively fast; Appendix_G_IOCs_Full.xml will take about 20 minutes or so to import.

      ATTENTION: The import of large files takes quite a bit of memory (probably there is a memory leak somewhere, which will be ironed out in a future release). Be sure to give the system/virtual machine you are running the import of Appendix_G_IOCs_Full.xml on a fair amount of memory (4 GB definitely works).

    • Start the server (if the quickstart-script has not started it already for you) with

      • If you are using sqllite:

        python runserver 8000 --traceback --settings=mantis.settings.local
      • If you are using postgresql:

        python runserver 8000 --traceback --settings=mantis.settings.local_psql
    • Browse to:

    and start looking around:

    • Select a filter for in the filter box in the top-right corner.
    • This will show you all STIX_Package objects that are in the system (two, if you imported both Mandiant_APT1_Report.xml and Appendix_G_IOC_Full.xml).
    • Click on one of the two objects and start exploring (have a look at the screenshots in the documentation for a quick guide through the application.)

    You can also have a look at the Django admin interface at:

    MANTIS developers’ guide


    Before starting to develop

    Read up on techniques and styles used in MANTIS

    MANTIS profitted a lot from the advice provided in Two Scoops of Django.

    Unless you are an absolute Django expert (and maybe even then), please read Daniel Greenfield’s and Audrey Roy’s excellent Two Scoops of Django. Even though it provides best practices for Django 1.5, most of its advice is also valid for Django 1.6, and likely to be very relevant for quite a few minor revisions to come.

    Understand how django-dingos works

    The heart of MANTIS is the django-dingos Django application. Most aspects of modifying/adding to MANTIS will require a sound understanding of how django-dingos works. Please refer to the Django DINGOS developers’ guide

    Find the right place to modify/add to

    Writing your own Django application

    If you are adding completely new functionality to Mantis, the best way may very well be to create a new Django application.

    Keep django-dingos generic

    Although DINGOS is likely to be used mainly in the context of the Django MANTIS Cyber Threat Intelligence Management application, DINGOS should stay a /generic/ application for managing structured information. So whenever you find yourself adding/modifying stuff in DINGOS that is specific to cyber threat intelligence management, the STIX, CybOX standards, etc., DINGOS is the wrong place to modify/add to. The same goes for customizations that are particular to your instance of running MANTIS.

    Please consider the following places for development instead:

    • If you want to add Python code that is particular to cyber threat management, consider adding this in django-mantis-core
    • If you want to add Python code that is particular to a certain standard, consider adding it to the respective importer module, e.g., django-mantis-stix-importer or similar
    • If you want to make modifications to a DINGOS template that is required for your local instance of MANTIS (or whatever framework is using DINGOS), the right way is probably to override one of the DINGOS base templates. Have a look at how django-mantis overrides the templates/dingos/grappelli/base.html template; see also the Django documentation on overriding templates.
    • If you want to change the url paths of DINGOS views, do this in the of your instance rather than dingos/

    Setting up a development environment

    1. Refer to Contributing (section “Getting Started”) for information of how to (1) either fork a repository, clone it, and install it for development purposes, or (2) set up the directory structure for your own Django app that will contribute to the Mantis framework.

    2. Chose a development environment of your liking. Here is how you can setup PyCharm Professional Edition in support of development for Django: * Start up PyCharm and enter your license information. * Before opening a project/folder, go to Configure -> Settings and adjust the following:

      • Use the search box in the settings dialog to find the place where you can configure the proxy settings:
      • Configure the python environment under “Project Interpreter” -> “Python Interpreters” Click on the “+”, then on “Local...” Select <path_to_your_environment>/bin/python, and click “Ok”
      • Click on “Ok” to close the settings window.
      • Open the project folder: select “Open Directory” and choose your source directories
      • Before being able to run the django-mantis project, you have to adjust the “Run/Debug Confgurations” (wait for the indexer to finish...)
        • In the menubar, click on “Run” -> “Edit Configurations”
        • Select the “django-mantis” in the displayed tree on the left
        • In the right pane, add the following to the “Additional options:” --settings=mantis.settings.local_psql or --settings=mantis.settings.local
      • You should now be able to run the django server by clicking the play button.

    MANTIS Application Layout

    Overview of the directory layout

    The layout of the DINGOS Django application is as follows:

    ├── mantis
    │   ├── apps
    │   ├── assets
    │   ├── blobs
    │   ├──
    │   ├──
    │   ├── settings
    │   │   ├──
    │   │   ├──
    │   │   ├──
    │   │   ├──
    │   │   └──
    │   ├── static
    │   ├── templates
    │   │   ├── 404.html
    │   │   ├── 500.html
    │   │   ├── base.html
    │   │   ├── dingos
    │   │   │   └── grappelli
    │   │   │       └── base.html
    │   │   └── mantis
    │   │       └── grappelli
    │   ├──
    │   └──


    Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

    You can contribute in many ways:

    Types of Contributions

    Report Bugs

    MANTIS encompasses a number of components. For the following base components, please report issues at the central issue tracker for the whole Django MANTIS framework at :

    If you are reporting a bug, please include:

    • Your operating system name and version.
    • Any details about your local setup that might be helpful in troubleshooting.
    • Detailed steps to reproduce the bug.

    Fix Bugs

    Look through the GitHub issues for bugs. Anything tagged with “bug” is open to whoever wants to implement it.

    Implement Features

    Look through the GitHub issues for features. Anything tagged with “feature” is open to whoever wants to implement it.

    Write Documentation

    Djangos could always use more documentation, whether as part of the official Djangos docs, in docstrings, or even on the web in blog posts, articles, and such.

    Submit Feedback

    The best way to send feedback is to file an issue at

    If you are proposing a feature:

    • Explain in detail how it would work.
    • Keep the scope as narrow as possible, to make it easier to implement.
    • Remember that this is a volunteer-driven project, and that contributions are welcome :)

    Get Started!

    In your contribution, you may want to either modify/add to existing code or create a new Django application that interacts with the existing applications that are part of the Mantis framework.

    MANTIS profitted a lot from the advice provided in Two Scoops of Django. Unless you are an absolute Django expert (and maybe even then), please read Daniel Greenfield’s and Audrey Roy’s excellent Two Scoops of Django. Even though it provides best practices for Django 1.5, most of its advice is also valid for Django 1.6, and likely to be very relevant for quite a few minor revisions to come.

    Modifying/adding to existing code

    Here’s how to set up a repository for local development.

    1. Fork the relevant repository repo on GitHub.

    2. Clone your fork locally:

      $ git clone<repository>.git
    3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:

      $ mkvirtualenv <your_mantis_environment>
      $ cd <repository_folder>
      $ python develop
    4. Create a branch for local development:

      $ git checkout -b name-of-your-bugfix-or-feature

    Now you can make your changes locally.

    1. Commit your changes and push your branch to GitHub:

      $ git add .
      $ git commit -m "Your detailed description of your changes."
      $ git push origin name-of-your-bugfix-or-feature
    2. Submit a pull request through the GitHub website.

    Writing your own Django application

    Do yourself a favor and set up the directory structure of your Django application in the right way from the very start. The easiest way to do so is to use Daniel Greenfield’s cookiecutter-djangopackage template (which uses Audrey Roy’s excellent Cookiecutter for creating the directories): this layout has a very sensible directory structure with out-of-the-box configuration of for easy build, submission to PyPi, etc., as well as the start of a Sphinx documentation tree. Once you have the directory structure created, initialize a fresh git repository with it and get to work...

    Pull Request Guidelines

    Before you submit a pull request, check that it meets these guidelines:

    1. The pull request should include tests.
    2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
    3. The pull request should work for Python 2.7.