{"id":18123278,"url":"https://github.com/jay-johnson/train-ai-with-django-swagger-jwt","last_synced_at":"2025-04-14T23:04:28.087Z","repository":{"id":41512235,"uuid":"120073989","full_name":"jay-johnson/train-ai-with-django-swagger-jwt","owner":"jay-johnson","description":"Train AI (Keras + Tensorflow) to defend apps with Django REST Framework + Celery + Swagger + JWT - deploys to Kubernetes and OpenShift Container Platform","archived":false,"fork":false,"pushed_at":"2018-11-02T05:45:20.000Z","size":2826,"stargazers_count":70,"open_issues_count":1,"forks_count":23,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-14T23:03:55.898Z","etag":null,"topics":["ai","ai-security","anti-nex","celery","celery-tasks","deep-neural-networks","django-rest-framework","drf","jwt","keras","machine-learning","machine-learning-security","network-analysis","network-security","openshift","rest-api","swagger","tensorflow"],"latest_commit_sha":null,"homepage":"http://antinex.readthedocs.io/en/latest/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jay-johnson.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-03T08:39:46.000Z","updated_at":"2025-03-06T09:46:22.000Z","dependencies_parsed_at":"2022-08-26T10:10:30.876Z","dependency_job_id":null,"html_url":"https://github.com/jay-johnson/train-ai-with-django-swagger-jwt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Ftrain-ai-with-django-swagger-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Ftrain-ai-with-django-swagger-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Ftrain-ai-with-django-swagger-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jay-johnson%2Ftrain-ai-with-django-swagger-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jay-johnson","download_url":"https://codeload.github.com/jay-johnson/train-ai-with-django-swagger-jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248975315,"owners_count":21192208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-security","anti-nex","celery","celery-tasks","deep-neural-networks","django-rest-framework","drf","jwt","keras","machine-learning","machine-learning-security","network-analysis","network-security","openshift","rest-api","swagger","tensorflow"],"created_at":"2024-11-01T07:08:56.272Z","updated_at":"2025-04-14T23:04:28.049Z","avatar_url":"https://github.com/jay-johnson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"AntiNex REST API\n================\n\nAutomate training AI to defend applications with a Django 2.0+ REST Framework + Celery + Swagger + JWT using Keras and Tensorflow. \n\nNow supports building the same highly accurate deep neural networks as the `AntiNex Core`_ (**99.8%** accuracy with Django, Flask, React + Redux, Vue and Spring). This repository is fully dockerized and after the django celery worker finishes processing, it will auto-push predictions to the core's celery worker which is decoupled from django and the django database. The core's celery worker stores pre-trained AI neural networks in memory for faster predictions and supports re-training models as needed.\n\nFor those wanting to scale up their processing speeds, `AntiNex deploys on OpenShift Container Platform and Kubernetes \u003chttps://github.com/jay-johnson/train-ai-with-django-swagger-jwt/tree/master/openshift#antinex-on-openshift-container-platform\u003e`__ with persistent database volumes for Postgres (`Crunchy Data \u003chttps://github.com/CrunchyData/crunchy-containers\u003e`__) and Redis (`Bitnami \u003chttps://hub.docker.com/r/bitnami/redis/\u003e`__)\n\n.. image:: ./tests/images/django-rest-framework-with-swagger-and-jwt-trains-a-deep-neural-network-using-keras-and-tensorflow-with-83-percent-accuracy.gif\n    :width: 200px\n    :height: 400px\n\n.. _AntiNex Core: https://github.com/jay-johnson/antinex-core#antinex-core\n\nAntiNex Stack Status\n--------------------\n\nThe AntiNex REST API is part of the AntiNex stack:\n\n.. list-table::\n   :header-rows: 1\n\n   * - Component\n     - Build\n     - Docs Link\n     - Docs Build\n   * - `REST API \u003chttps://github.com/jay-johnson/train-ai-with-django-swagger-jwt\u003e`__\n     - .. image:: https://travis-ci.org/jay-johnson/train-ai-with-django-swagger-jwt.svg?branch=master\n           :alt: Travis Tests\n           :target: https://travis-ci.org/jay-johnson/train-ai-with-django-swagger-jwt.svg\n     - `Docs \u003chttp://antinex.readthedocs.io/en/latest/\u003e`__\n     - .. image:: https://readthedocs.org/projects/antinex/badge/?version=latest\n           :alt: Read the Docs REST API Tests\n           :target: https://readthedocs.org/projects/antinex/badge/?version=latest\n   * - `Core Worker \u003chttps://github.com/jay-johnson/antinex-core\u003e`__\n     - .. image:: https://travis-ci.org/jay-johnson/antinex-core.svg?branch=master\n           :alt: Travis AntiNex Core Tests\n           :target: https://travis-ci.org/jay-johnson/antinex-core.svg\n     - `Docs \u003chttp://antinex-core-worker.readthedocs.io/en/latest/\u003e`__\n     - .. image:: https://readthedocs.org/projects/antinex-core-worker/badge/?version=latest\n           :alt: Read the Docs AntiNex Core Tests\n           :target: http://antinex-core-worker.readthedocs.io/en/latest/?badge=latest\n   * - `Network Pipeline \u003chttps://github.com/jay-johnson/network-pipeline\u003e`__\n     - .. image:: https://travis-ci.org/jay-johnson/network-pipeline.svg?branch=master\n           :alt: Travis AntiNex Network Pipeline Tests\n           :target: https://travis-ci.org/jay-johnson/network-pipeline.svg\n     - `Docs \u003chttp://antinex-network-pipeline.readthedocs.io/en/latest/\u003e`__\n     - .. image:: https://readthedocs.org/projects/antinex-network-pipeline/badge/?version=latest\n           :alt: Read the Docs AntiNex Network Pipeline Tests\n           :target: https://readthedocs.org/projects/antinex-network-pipeline/badge/?version=latest\n   * - `AI Utils \u003chttps://github.com/jay-johnson/antinex-utils\u003e`__\n     - .. image:: https://travis-ci.org/jay-johnson/antinex-utils.svg?branch=master\n           :alt: Travis AntiNex AI Utils Tests\n           :target: https://travis-ci.org/jay-johnson/antinex-utils.svg\n     - `Docs \u003chttp://antinex-ai-utilities.readthedocs.io/en/latest/\u003e`__\n     - .. image:: https://readthedocs.org/projects/antinex-ai-utilities/badge/?version=latest\n           :alt: Read the Docs AntiNex AI Utils Tests\n           :target: http://antinex-ai-utilities.readthedocs.io/en/latest/?badge=latest\n   * - `Client \u003chttps://github.com/jay-johnson/antinex-client\u003e`__\n     - .. image:: https://travis-ci.org/jay-johnson/antinex-client.svg?branch=master\n           :alt: Travis AntiNex Client Tests\n           :target: https://travis-ci.org/jay-johnson/antinex-client.svg\n     - `Docs \u003chttp://antinex-client.readthedocs.io/en/latest/\u003e`__\n     - .. image:: https://readthedocs.org/projects/antinex-client/badge/?version=latest\n           :alt: Read the Docs AntiNex Client Tests\n           :target: https://readthedocs.org/projects/antinex-client/badge/?version=latest\n\nSupported API Requests\n----------------------\n\n- `Prepare a Dataset`_\n- `Train a Deep Neural Network from a Prepared Dataset using Keras and Tensorflow`_\n- `Multi-Tenant Deep Neural Network Training with Simulations`_\n- `Get recent Training jobs (including Models as json and weights)`_\n- `Get recent Training results (nice for reviewing historical accuracy)`_\n- `Get recent Prepared Datasets`_\n- `Creating and managing users`_\n\n.. _Prepare a Dataset:  https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#prepare-a-new-dataset-from-captured-recordings\n.. _Train a Deep Neural Network from a Prepared Dataset using Keras and Tensorflow: https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#train-a-keras-deep-neural-network-with-tensorflow\n.. _Multi-Tenant Deep Neural Network Training with Simulations: https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#multi-tenant-simulations\n.. _Get recent Training jobs (including Models as json and weights): https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#get-recent-ml-job-results\n.. _Get recent Training results (nice for reviewing historical accuracy): https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#get-recent-ml-jobs\n.. _Get recent Prepared Datasets: https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#get-recent-prepared-datasets\n.. _Creating and managing users: https://github.com/jay-johnson/train-ai-with-django-swagger-jwt#swagger\n\nThis repository was built to help capture ``non-attack`` network traffic and to improve the accuracy of the Keras + Tensorflow Deep Neural Networks by providing them a simple multi-tenant REST API that has Swagger + JWT authentication baked into a single web application. By default, all created Deep Neural Networks are automatically saved as JSON including model weights. It also does not require a database (unless you want to set it up), and will be scaled out with `Celery Connectors`_ in the future. Please refer to the `Network Pipeline`_ repository for more details. This Django application server also comes with a functional Celery worker for running heavyweight, time-intensive tasks required for asynchronous use cases. This is good for when you are trying to train a deep net that takes a few minutes, and you do not want your HTTP client to time out.\n\n.. _Network Pipeline: https://github.com/jay-johnson/network-pipeline\n.. _Celery Connectors: https://github.com/jay-johnson/celery-connectors\n\nI plan to automate the tests in a loop and then release the captured HTTP traffic to compile the first ``non-attack`` dataset for pairing up with the OWASP ``attack`` data which is already recorded and available in:\n\nhttps://github.com/jay-johnson/network-pipeline-datasets\n\nUpdate: 2018-02-25 - These merged datasets and accuracies are now available in the repository:\n\nhttps://github.com/jay-johnson/antinex-datasets\n\nWatch Getting Started\n=====================\n\nAssuming your host has the pips already cached locally this takes about a minute.\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/Ct8TS1PMPminXBr5xoojTZq89?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://imgur.com/LRVlbcv.png\"/\u003e\u003c/a\u003e\n\nInstall\n=======\n\nTested on Ubuntu 17.10, Ubuntu 18.04 and works on `OpenShift Container Platform with Kubernetes \u003chttps://github.com/jay-johnson/train-ai-with-django-swagger-jwt/tree/master/openshift\u003e`__.\n\n::\n\n    mkdir -p -m 777 /opt/antinex\n    git clone https://github.com/jay-johnson/train-ai-with-django-swagger-jwt.git /opt/antinex/api\n    cd /opt/antinex/api\n    ./install.sh\n\nGetting Started With Docker\n===========================\n\nYou can run without these optional steps and just use the default SQLite database. If you want to use docker and download all the containers, you can use the ``compose.yml`` file to start all of the containers and download the latest ``ai-core`` docker image which is ~2.5 GB on disk (built with `Dockerfile`_ and stored on `Docker Hub`_).\n\n.. _Dockerfile: https://github.com/jay-johnson/antinex-core/blob/master/docker/Dockerfile\n.. _Docker Hub: https://hub.docker.com/r/jayjohnson/ai-core/\n\nTo start all run:\n\n::\n\n    # if you do not have docker compose installed, you can try installing it with:\n    # pip install docker-compose\n    ./run-all.sh\n\nVerify the containers started\n\n::\n\n    docker ps\n    CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                    NAMES\n    d34c8973066b        jayjohnson/antinex-pipeline:latest   \"/bin/sh -c 'cd /opt…\"   2 hours ago         Up 2 hours                                   pipeline\n    12ef5482bc17        jayjohnson/antinex-worker:latest     \"/bin/sh -c 'cd /opt…\"   2 hours ago         Up 2 hours                                   worker\n    da7970ae165f        jayjohnson/antinex-api:latest        \"/bin/sh -c 'cd /opt…\"   2 hours ago         Up 2 hours                                   api\n    11a2c95b7247        jayjohnson/antinex-core:latest       \"/bin/sh -c 'cd /opt…\"   2 hours ago         Up 2 hours                                   core\n    1f26d89c8c2c        jayjohnson/antinex-jupyter:latest    \"/opt/antinex/core/d…\"   2 hours ago         Up 2 hours                                   jupyter\n    4905682ff3b4        postgres:10.4-alpine                 \"docker-entrypoint.s…\"   2 hours ago         Up 2 hours          0.0.0.0:5432-\u003e5432/tcp   postgres\n    fd8300740935        redis:4.0.9-alpine                   \"docker-entrypoint.s…\"   2 hours ago         Up 2 hours          0.0.0.0:6379-\u003e6379/tcp   redis\n    7c682ba78adb        jayjohnson/pgadmin4:1.0.0            \"python ./usr/local/…\"   2 hours ago         Up 2 hours          0.0.0.0:83-\u003e5050/tcp     pgadmin\n\nQuick links\n-----------\n\nIf you are running all the containers, you can use these links to move around:\n\n- Use Swagger to Train a new Deep Neural Network (login with ``trex`` and ``123321``)\n\n  http://localhost:8010/swagger/#!/ml/ml_create\n\n- Jupyter Notebook showing how the Deep Neural Networks are Trained (login with ``admin`` and ``ALT + r`` to view the slideshow)\n\n  http://localhost:8888/notebooks/AntiNex-Protecting-Django.ipynb\n  \n- Jupyter Notebook shoing how to use Pre-trained Deep Neural Networks with AntiNex\n\n  http://localhost:8888/notebooks/AntiNex-Using-Pre-Trained-Deep-Neural-Networks-For-Defense.ipynb\n\nIf you are interested in running locally without the large container image, you can run the broker and database stack with docker containers for simulating a more production-ready environment. Here's the containers these steps will start:\n\n#.  Postgres 10\n#.  Redis (Pub/Sub, Caching and Celery Tasks)\n#.  pgAdmin4 - Web app for managing Postgres\n\nHere's how to run it:\n\n#.  Source the environment\n\n    ::\n\n        source envs/drf-dev.env\n\n#.  Start the Stack\n\n    ::\n\n        ./run-stack.sh \n        Starting stack: full-stack-dev.yml\n        Creating postgres ... done\n        Creating pgadmin ... \n        Creating postgres ... \n\n#.  Verify the containers are running\n\n    ::\n\n        docker ps\n        CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                                                                                                       NAMES\n        2c7cfbd9328e        postgres:10.2-alpine        \"docker-entrypoint.s…\"   3 minutes ago       Up 3 minutes        0.0.0.0:5432-\u003e5432/tcp                                                                                      postgres\n        9c34c9588349        jayjohnson/pgadmin4:1.0.0   \"python ./usr/local/…\"   3 minutes ago       Up 3 minutes        0.0.0.0:83-\u003e5050/tcp                                                                                        pgadmin\n        75e325113424        redis:4.0.5-alpine          \"docker-entrypoint.s…\"   3 minutes ago       Up 3 minutes        0.0.0.0:6379-\u003e6379/tcp                                                                                      redis\n\n#.  Initialize the Postgres database\n\n    ::\n\n        export USE_ENV=drf-dev\n        ./run-migrations.sh\n\n#.  Login to pgAdmin4\n\n    http://localhost:83/browser/\n\n    User: ``admin@email.com``\n    Password: ``postgres``\n\n#.  Register the Postgres server\n\n    #.  Right click on \"Servers\" and then \"Create Server\"\n\n    #.  On the \"General\" tab enter a name like \"webapp\"\n\n    #.  On the \"Connection\" tab enter:\n\n        Host: postgres\n\n        Username: postgres\n\n        Password: postgres\n\n    #.  Click \"Save password?\" check box\n\n    #.  Click the \"Save\" button\n\n    #.  Navigate down the tree:\n\n        Servers \u003e webapp (or the name you entered) \u003e Databases \u003e webapp \u003e Schemas \u003e public \u003e Tables\n\n    #.  Confirm there's database tables with names like:\n\n        ::\n\n            pipeline_mljob\n            pipeline_mljobresult\n            pipeline_mlprepare\n\nStart\n=====\n\nBy default, this project uses `gunicorn`_ to start, but you can change to `uwsgi`_ by running ``export APP_SERVER=uwsgi`` before starting. Both app servers should work just fine.\n\nNote: if you are running the docker \"full stack\" please make sure to run: ``export USE_ENV=drf-dev`` before starting the django application, or you can use ``run-django.sh`` which should do the same as ``start.sh``.\n\n::\n\n    ./start.sh\n\n    Starting Django listening on TCP port 8010\n    http://localhost:8010/swagger\n\n    [2018-02-07 11:27:20 -0800] [10418] [INFO] Starting gunicorn 19.7.1\n    [2018-02-07 11:27:20 -0800] [10418] [INFO] Listening at: http://127.0.0.1:8010 (10418)\n    [2018-02-07 11:27:20 -0800] [10418] [INFO] Using worker: sync\n    [2018-02-07 11:27:20 -0800] [10418] [INFO] DJANGO_DEBUG=yes - auto-reload enabled\n    [2018-02-07 11:27:20 -0800] [10418] [INFO] Server is ready. Spawning workers\n    [2018-02-07 11:27:20 -0800] [10422] [INFO] Booting worker with pid: 10422\n    [2018-02-07 11:27:20 -0800] [10422] [INFO] Worker spawned (pid: 10422)\n    [2018-02-07 11:27:20 -0800] [10423] [INFO] Booting worker with pid: 10423\n    [2018-02-07 11:27:20 -0800] [10423] [INFO] Worker spawned (pid: 10423)\n    [2018-02-07 11:27:20 -0800] [10424] [INFO] Booting worker with pid: 10424\n    [2018-02-07 11:27:20 -0800] [10424] [INFO] Worker spawned (pid: 10424)\n    [2018-02-07 11:27:20 -0800] [10426] [INFO] Booting worker with pid: 10426\n    [2018-02-07 11:27:20 -0800] [10426] [INFO] Worker spawned (pid: 10426)\n    [2018-02-07 11:27:20 -0800] [10430] [INFO] Booting worker with pid: 10430\n    [2018-02-07 11:27:20 -0800] [10430] [INFO] Worker spawned (pid: 10430)\n\n.. _gunicorn: http://docs.gunicorn.org/\n.. _uwsgi: https://uwsgi-docs.readthedocs.io/en/latest/\n\nCelery Worker\n=============\n\nStart the Worker\n----------------\n\nStart the Celery worker in a new terminal to process published Django work tasks for heavyweight, time-intensive operations.\n\n::\n\n    ./run-worker.sh\n\nCreate User\n-----------\n\nCreate the user ``trex`` with password ``123321``:\n\n::\n\n    source tests/users/user_1.sh \\\n    \u0026\u0026 ./tests/create-user.sh \\\n    \u0026\u0026 env | grep API | sort\n\n    Creating user: trex on http://localhost:8010/users/\n    {\"id\":2,\"username\":\"trex\",\"email\":\"bugs@antinex.com\"}\n    Getting token for user: trex\n    {\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo2LCJ1c2VybmFtZSI6InRyZXgiLCJleHAiOjE1MjgyNjExMjgsImVtYWlsIjoiYnVnc0BhbnRpbmV4LmNvbSJ9.W6Lb2N1v8S3e6EMT7RuTvfUQMTbKjrmYzhMxtFQ9jhk\"}\n    API_DEBUG=false\n    API_EMAIL=bugs@antinex.com\n    API_FIRSTNAME=Guest\n    API_LASTNAME=Guest\n    API_PASSWORD=123321\n    API_URL=http://localhost:8010\n    API_USER=trex\n    API_VERBOSE=true\n\nAutomation\n==========\n\nAll of these scripts run in the ``tests`` directory:\n\n::\n\n    cd tests\n\nMake sure the virtual environment has been loaded:\n\n::\n\n    source ~/.venvs/venvdrfpipeline/bin/activate\n\nClone the datasets repository\n-----------------------------\n\ngit clone https://github.com/jay-johnson/network-pipeline-datasets /opt/antinex/datasets\n\nPrepare a new Dataset from Captured Recordings\n----------------------------------------------\n\n::\n\n    ./build-new-dataset.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/Py5OaIFOJJIMCdP5Ktjd0VhOu?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/Py5OaIFOJJIMCdP5Ktjd0VhOu.png\"/\u003e\u003c/a\u003e\n\nTrain a Keras Deep Neural Network with Tensorflow\n-------------------------------------------------\n\n::\n\n    ./create-keras-dnn.py\n\n    ...\n\n    2018-02-03 00:31:24,342 - create-keras-dnn - INFO - SUCCESS - Post Response status=200 reason=OK\n    2018-02-03 00:31:24,342 - create-keras-dnn - INFO - {'job': {'id': 1, 'user_id': 2, 'user_name': 'trex', 'title': 'Keras DNN - network-pipeline==1.0.9', 'desc': 'Tensorflow backend with simulated data', 'ds_name': 'cleaned', 'algo_name': 'dnn', 'ml_type': 'keras', 'status': 'initial', 'control_state': 'active', 'predict_feature': 'label_value', 'training_data': {}, 'pre_proc': {}, 'post_proc': {}, 'meta_data': {}, 'tracking_id': 'ml_701552d5-c761-4c69-9258-00d05ff81a48', 'version': 1, 'created': '2018-02-03 08:31:17', 'updated': '2018-02-03 08:31:17', 'deleted': ''}, 'results': {'id': 1, 'user_id': 2, 'user_name': 'trex', 'job_id': 1, 'status': 'finished', 'version': 1, 'acc_data': {'accuracy': 83.7837837300859}, 'error_data': None, 'created': '2018-02-03 08:31:24', 'updated': '2018-02-03 08:31:24', 'deleted': ''}}\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/FdtNSkcRK7VFktg5NGVAQA1In?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/FdtNSkcRK7VFktg5NGVAQA1In.png\"/\u003e\u003c/a\u003e\n\nCreate a Highly Accurate Deep Neural Network for Protecting Django\n------------------------------------------------------------------\n\nThis is the same API request the core uses to build the Django DNN with an accuracy of **99.8%**:\n\nhttps://github.com/jay-johnson/antinex-core#accuracy-and-prediction-report\n\nwith Notebook:\n\nhttps://github.com/jay-johnson/antinex-core/blob/master/docker/notebooks/AntiNex-Protecting-Django.ipynb\n\n::\n\n    ./create-keras-dnn.py -f ./scaler-full-django-antinex-simple.json \n\n    Please wait... this can take a few minutes\n\n    ...\n\n    2018-03-21 06:04:48,314 - ml_tasks - INFO - saving job=83 results\n    2018-03-21 06:04:50,387 - ml_tasks - INFO - updating job=83 results=83\n    2018-03-21 06:04:53,957 - ml_tasks - INFO - task - ml_job - done - ml_job.id=83 ml_result.id=83 accuracy=99.81788079470199 predictions=30200\n\nTrain and Predict with just a Dictionary List of Records\n--------------------------------------------------------\n\nThis will send a list of records to the API to train and make predictions. This mimics the live-prediction capability in the core for reusing pre-trained DNNs to make predictions faster. I use it to send the newest records to predict, so I do not have to generate lots of csv files everywhere + all-the-time.\n\n::\n\n    ./create-keras-dnn.py -f ./predict-rows-scaler-full-django.json \n\nTrain and Predict using the AntiNex Core\n----------------------------------------\n\nThis will train and cache a deep neural network using the `AntiNex Core \u003chttps://github.com/jay-johnson/antinex-core\u003e`__. Once trained, the core can make future predictions with the same API call without having to retrain. This makes predictions much faster.\n\n::\n\n    ./create-keras-dnn.py -f only-publish-scaler-full-django.json\n\nThe core trains a deep neural network and persists it in a dictionary that uses the `label value on the request \u003chttps://github.com/jay-johnson/antinex-core/blob/521c019469ac41958f64dcf9483b7ce902311438/antinex_core/antinex_processor.py#L150-L153\u003e`_ to store the trained model. Future predictions must continue to reuse the same ``label`` value on the request to avoid waiting for a retraining cycle. Here is the `label value used in the previous request \u003chttps://github.com/jay-johnson/train-ai-with-django-swagger-jwt/blob/0487fdc6b62d15a67754f131c02eb5d71faf3897/tests/only-publish-scaler-full-django.json#L2\u003e`__ which is:\n\n::\n\n    \"label\": \"Full-Django-AntiNex-Simple-Scaler-DNN\"\n\nMake Predictions for a List of Records\n--------------------------------------\n\nIf you have a list of records the API, Worker and Core support making predictions for each record in a list.\n\nPredict using the AntiNex Worker:\n\n::\n\n    ./create-keras-dnn.py -f predict-rows-scaler-full-django.json \n\nPredict using the AntiNex Core:\n\n::\n\n    ./create-keras-dnn.py -f only-publish-predict-rows-simple.json \n\nAdvanced Naming for Multi-Tenant Environments\n=============================================\n\nProblems will happen if multiple users are sharing the same host's ``/tmp/`` directory with the default naming conventions. To prevent issues, it is recommended to change the output dataset directory to separate directories per user and to make sure the directories are accessible by the Django server processes. Here's an example of changing the output directory to my user which triggers the custom name detection. This detection means I will see logs for the training command to run with my newly generated dataset and metadata files:\n\n::\n\n    mkdir /opt/jay\n    export OUTPUT_DIR=/opt/jay/\n    ./build-new-dataset.py\n\n    ...\n\n    Train a Neural Network with:\n    ./create-keras-dnn.py /opt/jay/cleaned_attack_scans.csv /opt/jay/cleaned_metadata.json\n\nIf changing the output directory is not possible, then users will need to make sure the file names are unique before running. Here's an example naming strategy for the csv datasets and metadata files to prevent collisions. The ``build-new-dataset.py`` script will also suggest the training command to run when you activate custom names:\n\nPrepare a Named Dataset\n-----------------------\n\n::\n\n    ./build-new-dataset.py /tmp/\u003cMyFirstName\u003e_$(date +\"%Y-%m-%d-%H-%m-%N\")_full.csv /tmp/\u003cMyFirstName\u003e_$(date +\"%Y-%m-%d-%H-%m-%N\")_readytouse.csv\n\nExample that shows the suggested training command to run using the named dataset files on disk:\n\n::\n\n    ./build-new-dataset.py /tmp/jay_$(date +\"%Y-%m-%d-%H-%m-%N\")_full.csv /tmp/jay_$(date +\"%Y-%m-%d-%H-%m-%N\")_readytouse.csv\n\n    ...\n\n    Train a Neural Network with:\n    ./create-keras-dnn.py /tmp/jay_2018-02-05-21-02-274468596_readytouse.csv /tmp/cleaned_meta-54525d8da8a54e9d9005a29c63f2918b.json\n\nConfirm the files were created:\n\n::\n\n    ls -lrth /tmp/jay_2018-02-05-21-02-274468596_readytouse.csv /tmp/cleaned_meta-54525d8da8a54e9d9005a29c63f2918b.json\n    -rw-rw-r-- 1 jay jay 143K Feb  5 21:23 /tmp/jay_2018-02-05-21-02-274468596_readytouse.csv\n    -rw-rw-r-- 1 jay jay 1.8K Feb  5 21:23 /tmp/cleaned_meta-54525d8da8a54e9d9005a29c63f2918b.json\n\nPlease note, if you use filenames and set the ``OUTPUT_DIR`` environment variable, the environment variable takes priority (even if you specify ``/path/to/some/dir/uniquename.csv``). The dataset and metadata files will be stored in the ``OUTPUT_DIR`` directory:\n\n::\n\n    echo $OUTPUT_DIR\n    /opt/jay/\n\n    ./build-new-dataset.py jay_$(date +\"%Y-%m-%d-%H-%m-%N\")_full.csv jay_$(date +\"%Y-%m-%d-%H-%m-%N\")_readytouse.csv\n\n    ...\n\n    Train a Neural Network with:\n    ./create-keras-dnn.py /opt/jay/jay_2018-02-05-22-02-521671337_readytouse.csv /opt/jay/cleaned_meta-2b961845162a4d6e9e382c6f540302fe.json\n\nSwagger\n=======\n\nCreate a User\n-------------\n\nhttp://localhost:8010/swagger/#!/users/users_create\n\nClick on the yellow ``Example Value`` section to paste in defaults or paste in your version of:\n\n::\n\n    {\n        \"username\": \"trex\",\n        \"password\": \"123321\",\n        \"email\": \"bugs@antinex.com\"\n    }\n\nLogin User\n----------\n\nIf you want to login as the super user:\n\n- Username: ``trex``\n- Password: ``123321``\n\nhttp://localhost:8010/api-auth/login/\n\nLogout User\n-----------\n\nhttp://localhost:8010/swagger/?next=/swagger/#!/accounts/accounts_logout_create\n\nJWT\n===\n\nGet a Token\n-----------\n\nThis will validate authentication with JWT is working:\n\n::\n\n    ./get_user_jwt_token.sh \n    {\"token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJ1c2VybmFtZSI6InJvb3QiLCJleHAiOjE1MTc1OTg3NTIsImVtYWlsIjoicm9vdEBlbWFpbC5jb20ifQ.ip3Lj5o4SCK4TARlDuLyw-Dc6qMkt8xUx8WsQwIn2uo\"}\n\n(Optional) If you have ``jq`` installed:\n\n::\n\n    ./get_user_jwt_token.sh | jq\n    {\n      \"token\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJ1c2VybmFtZSI6InJvb3QiLCJleHAiOjE1MTc1OTg3NDEsImVtYWlsIjoicm9vdEBlbWFpbC5jb20ifQ.WAIatDGkeFJbH6LL_4rRQaAydZXcE8j0KK7dBnA2GJU\"\n    }\n\nhttp://localhost:8010/swagger/?next=/swagger/#!/ml/ml_run_create\n\nDevelopment\n===========\n\nSwagger Prepare a new Dataset from Captured Recordings\n------------------------------------------------------\n\nhttp://localhost:8010/swagger/#!/mlprepare/mlprepare_create\n\nPaste in the following values and click **Try it Out**:\n\n::\n\n    {\n        \"title\": \"Prepare new Dataset from recordings\",\n        \"desc\": \"\",\n        \"ds_name\": \"new_recording\",\n        \"full_file\": \"/tmp/fulldata_attack_scans.csv\",\n        \"clean_file\": \"/tmp/cleaned_attack_scans.csv\",\n        \"meta_suffix\": \"metadata.json\",\n        \"output_dir\": \"/tmp/\",\n        \"ds_dir\": \"/opt/antinex/datasets\",\n        \"ds_glob_path\": \"/opt/antinex/datasets/*/*.csv\",\n        \"pipeline_files\": {\n            \"attack_files\": []\n        },\n        \"meta_data\": {},\n        \"post_proc\": {\n            \"drop_columns\": [\n                \"src_file\",\n                \"raw_id\",\n                \"raw_load\",\n                \"raw_hex_load\",\n                \"raw_hex_field_load\",\n                \"pad_load\",\n                \"eth_dst\",\n                \"eth_src\",\n                \"ip_dst\",\n                \"ip_src\"\n            ],\n            \"predict_feature\": \"label_name\"\n        },\n        \"label_rules\": {\n            \"set_if_above\": 85,\n            \"labels\": [\n                \"not_attack\",\n                \"attack\"\n            ],\n            \"label_values\": [\n                0,\n                1\n            ]\n        },\n        \"version\": 1\n    }\n\nSwagger Train a Keras Deep Neural Network with Tensorflow\n---------------------------------------------------------\n\nhttp://0.0.0.0:8010/swagger/#!/ml/ml_create\n\nPaste in the following values and click **Try it Out**:\n\n#.  Build the Django DNN for Predicting Network Attacks\n\n    ::\n\n        {\n            \"label\": \"Full-Django-AntiNex-Simple-Scaler-DNN\",\n            \"dataset\": \"/opt/antinex/antinex-datasets/v1/webapps/django/training-ready/v1_django_cleaned.csv\",\n            \"ml_type\": \"classification\",\n            \"predict_feature\": \"label_value\",\n            \"features_to_process\": [\n                \u003clist of comma separated column names\u003e\n            ],\n            \"ignore_features\": [\n                \u003coptional list of comma separated column names\u003e\n            ],\n            \"sort_values\": [\n                \u003coptional list of comma separated column names\u003e\n            ],\n            \"seed\": 42,\n            \"test_size\": 0.2,\n            \"batch_size\": 32,\n            \"epochs\": 15,\n            \"num_splits\": 2,\n            \"loss\": \"binary_crossentropy\",\n            \"optimizer\": \"adam\",\n            \"metrics\": [\n                \"accuracy\"\n            ],\n            \"histories\": [\n                \"val_loss\",\n                \"val_acc\",\n                \"loss\",\n                \"acc\"\n            ],\n            \"model_desc\": {\n                \"layers\": [\n                    {\n                        \"num_neurons\": 200,\n                        \"init\": \"uniform\",\n                        \"activation\": \"relu\"\n                    },\n                    {\n                        \"num_neurons\": 1,\n                        \"init\": \"uniform\",\n                        \"activation\": \"sigmoid\"\n                    }\n                ]\n            },\n            \"label_rules\": {\n                \"labels\": [\n                    \"not_attack\",\n                    \"not_attack\",\n                    \"attack\"\n                ],\n                \"label_values\": [\n                    -1,\n                    0,\n                    1\n                ]\n            },\n            \"version\": 1\n        }\n\n#.  Prototyping with a List of Records\n\n    I use this script to convert a configurable number of records from the bottom of a csv file which helps build these type of prediction json files:\n\n    https://github.com/jay-johnson/antinex-core/blob/master/antinex_core/scripts/convert_bottom_rows_to_json.py\n\n    ::\n\n         ./create-keras-dnn.py -f ./readme-predict-demo-1.json \n\n    Here are the contents of ``./tests/readme-predict-demo-1.json``\n\n    ::\n\n        {\n            \"label\": \"Prediction-Model-Prototyping\",\n            \"predict_rows\": [\n                {\n                    \"_dataset_index\": 1,\n                    \"label_value\": 1,\n                    \"more_keys\": 54.0\n                },\n                {\n                    \"_dataset_index\": 2,\n                    \"label_value\": 1,\n                    \"more_keys\": 24.0\n                },\n                {\n                    \"_dataset_index\": 2,\n                    \"label_value\": 0,\n                    \"more_keys\": 33.0\n                }\n            ],\n            \"ml_type\": \"classification\",\n            \"predict_feature\": \"label_value\",\n            \"features_to_process\": [\n                \"more_keys\"\n            ],\n            \"ignore_features\": [\n            ],\n            \"sort_values\": [\n            ],\n            \"seed\": 42,\n            \"test_size\": 0.2,\n            \"batch_size\": 32,\n            \"epochs\": 15,\n            \"num_splits\": 2,\n            \"loss\": \"binary_crossentropy\",\n            \"optimizer\": \"adam\",\n            \"metrics\": [\n                \"accuracy\"\n            ],\n            \"histories\": [\n                \"val_loss\",\n                \"val_acc\",\n                \"loss\",\n                \"acc\"\n            ],\n            \"model_desc\": {\n                \"layers\": [\n                    {\n                        \"num_neurons\": 200,\n                        \"init\": \"uniform\",\n                        \"activation\": \"relu\"\n                    },\n                    {\n                        \"num_neurons\": 1,\n                        \"init\": \"uniform\",\n                        \"activation\": \"sigmoid\"\n                    }\n                ]\n            },\n            \"label_rules\": {\n                \"labels\": [\n                    \"not_attack\",\n                    \"not_attack\",\n                    \"attack\"\n                ],\n                \"label_values\": [\n                    -1,\n                    0,\n                    1\n                ]\n            },\n            \"version\": 1\n        }\n\n\n#.  Deprecated - Using just CSV files\n\n    ::\n\n        {\n            \"csv_file\": \"/tmp/cleaned_attack_scans.csv\",\n            \"meta_file\": \"/tmp/cleaned_metadata.json\",\n            \"title\": \"Keras DNN - network-pipeline==1.0.9\",\n            \"desc\": \"Tensorflow backend with simulated data\",\n            \"ds_name\": \"cleaned\",\n            \"algo_name\": \"dnn\",\n            \"ml_type\": \"keras\",\n            \"predict_feature\": \"label_value\",\n            \"training_data\": \"{}\",\n            \"pre_proc\": \"{}\",\n            \"post_proc\": \"{}\",\n            \"meta_data\": \"{}\",\n            \"version\": 1\n        }\n\nVerify the Celery Worker Processes a Task without Django\n--------------------------------------------------------\n\nI find the first time I integrate Celery + Django + Redis can be painful. So I try to validate Celery tasks work before connecting Celery to Django over a message broker (like Redis). Here is a test tool for helping debug this integration with the `celery-loaders`_ project. It's also nice not having to click through the browser to debug a new task.\n\n#.  Run the task test script\n\n    ::\n\n        ./run-celery-task.py -t drf_network_pipeline.users.tasks.task_get_user -f tests/celery/task_get_user.json\n        2018-06-05 22:41:39,426 - run-celery-task - INFO - start - run-celery-task\n        2018-06-05 22:41:39,426 - run-celery-task - INFO - connecting Celery=run-celery-task broker=redis://localhost:6379/9 backend=redis://localhost:6379/10 tasks=['drf_network_pipeline.users.tasks']\n        2018-06-05 22:41:39,427 - get_celery_app - INFO - creating celery app=run-celery-task tasks=['drf_network_pipeline.users.tasks']\n        2018-06-05 22:41:39,470 - run-celery-task - INFO - app.broker_url=redis://localhost:6379/9 calling task=drf_network_pipeline.users.tasks.task_get_user data={'celery_enabled': True, 'cache_key': None, 'use_cache': False, 'data': {'user_id': 2}}\n        2018-06-05 22:41:39,535 - run-celery-task - INFO - calling task=drf_network_pipeline.users.tasks.task_get_user - started job_id=4931e1fc-3610-4259-8ccd-5724a1c50c79\n        2018-06-05 22:41:39,549 - run-celery-task - INFO - calling task=drf_network_pipeline.users.tasks.task_get_user - success job_id=4931e1fc-3610-4259-8ccd-5724a1c50c79 task_result={'status': 0, 'err': '', 'task_name': '', 'data': {'id': 2, 'username': 'trex', 'email': 'bugs@antinex.com'}, 'celery_enabled': True, 'use_cache': False, 'cache_key': None}\n        2018-06-05 22:41:39,549 - run-celery-task - INFO - end - run-celery-task\n\n#.  Verify the Celery Worker Processed the Task\n\n    If Redis and Celery are working as expected, the logs should print something similar to the following:\n\n    ::\n\n        2018-06-06 05:41:39,535 - celery.worker.strategy - INFO - Received task: drf_network_pipeline.users.tasks.task_get_user[4931e1fc-3610-4259-8ccd-5724a1c50c79]\n        2018-06-06 05:41:39,537 - user_tasks - INFO - task - task_get_user - start req_node={'celery_enabled': True, 'cache_key': None, 'use_cache': False, 'data': {'user_id': 2}}\n        2018-06-06 05:41:39,537 - user_tasks - INFO - finding user=2 cache=False\n        2018-06-06 05:41:39,539 - celery.worker.request - DEBUG - Task accepted: drf_network_pipeline.users.tasks.task_get_user[4931e1fc-3610-4259-8ccd-5724a1c50c79] pid:26\n        2018-06-06 05:41:39,547 - user_tasks - INFO - found user.id=2 name=trex\n        2018-06-06 05:41:39,547 - user_tasks - INFO - task - task_get_user result={'status': 0, 'err': '', 'task_name': '', 'data': {'id': 2, 'username': 'trex', 'email': 'bugs@antinex.com'}, 'celery_enabled': True, 'use_cache': False, 'cache_key': None} - done\n        2018-06-06 05:41:39,550 - celery.app.trace - INFO - Task drf_network_pipeline.users.tasks.task_get_user[4931e1fc-3610-4259-8ccd-5724a1c50c79] succeeded in 0.013342023004952352s: {'status': 0, 'err': '', 'task_name': '', 'data': {'id': 2, 'username': 'trex', 'email': 'bugs@antinex.com'}, 'celery_enabled': True, 'use_cache': False, 'cache_key': None}\n\n.. _celery-loaders: https://github.com/jay-johnson/celery-loaders\n\nAdditional Legacy Client API Tools\n----------------------------------\n\nThese tools and examples were created before the `AntiNex Python Client \u003chttps://github.com/jay-johnson/antinex-client\u003e`__ was released. Please use that for official API examples. \n\nGet a Prepared Dataset\n======================\n\n::\n\n    export PREPARE_JOB_ID=1\n    ./get-a-prepared-dataset.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/J0xedsJx5dJ1Z1LYPI2is7SjB?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/J0xedsJx5dJ1Z1LYPI2is7SjB.png\"/\u003e\u003c/a\u003e\n\nGet an ML Job\n=============\n\nAny trained Keras Deep Neural Network models are saved as an ``ML Job``.\n\n::\n\n    export JOB_ID=1\n    ./get-a-job.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/A8fJs0okBxltJDI2X1uTghddz?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://imgur.com/gFsh5q8.png\"/\u003e\u003c/a\u003e\n\nGet an ML Job Result\n====================\n\n::\n\n    export JOB_RESULT_ID=1\n    ./get-a-result.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/3nE0kab7oVyFIOAywQqM7BPyZ?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/3nE0kab7oVyFIOAywQqM7BPyZ.png\"/\u003e\u003c/a\u003e\n\nGet Recent Prepared Datasets\n============================\n\n::\n\n    ./get-recent-datasets.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/9O32uMMCj9NmTLuYqFoyIE1rk?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/9O32uMMCj9NmTLuYqFoyIE1rk.png\"/\u003e\u003c/a\u003e\n\nGet Recent ML Jobs\n==================\n\n::\n\n    ./get-recent-jobs.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/7TBpEj757q4crNHCDASlChWn2?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/7TBpEj757q4crNHCDASlChWn2.png\"/\u003e\u003c/a\u003e\n\n\nGet Recent ML Job Results\n=========================\n\nThis is nice for reviewing historical accuracy as your tune your models.\n\n::\n\n    ./get-recent-results.py\n\n.. raw:: html\n\n    \u003ca href=\"https://asciinema.org/a/TTjDnqc65voanvFq4HUxJ142k?autoplay=1\" target=\"_blank\"\u003e\u003cimg src=\"https://asciinema.org/a/TTjDnqc65voanvFq4HUxJ142k.png\"/\u003e\u003c/a\u003e\n\nRun Tests\n---------\n\nThe unit tests can be run:\n\n::\n\n    ./run-tests.sh\n\n    ...\n\n    PASSED - unit tests\n\nOr run a single test\n\n::\n\n    source envs/dev.env; cd webapp; source ~/.venvs/venvdrfpipeline/bin/activate\n    python manage.py test drf_network_pipeline.tests.test_ml.MLJobTest\n\nMulti-Tenant Simulations\n========================\n\nSimulations run from the ``./tests/`` directory.\n\n::\n\n    cd tests\n\n\nRun the default ``user1`` simulation in a new terminal:\n\n::\n\n    ./run-user-sim.py\n\nIn a new terminal start ``user2`` simulation:\n\n::\n\n    ./run-user-sim.py user2\n\nIn a new terminal start ``user3`` simulation:\n\n::\n\n    ./run-user-sim.py user3\n\nWant to check how many threads each process is using?\n-----------------------------------------------------\n\nIt appears that either Keras or Tensorflow are using quite a bit of threads behind the scenes. On Ubuntu you can view the number of threads used by ``gunicorn`` or ``uwsgi`` with these commands:\n\n::\n\n    ps -o nlwp $(ps awuwx | grep django | grep -v grep | awk '{print $2}')\n\nIf you're running ``uwsgi`` instead of the ``gunicorn`` use:\n\n::\n\n    ps -o nlwp $(ps awuwx | grep uwsgi | grep -v grep | awk '{print $2}')\n\nStop Full Stack\n===============\n\nIf you are running the \"full stack\", then you can run this command to stop the docker containers:\n\n::\n\n    ./stop-stack.sh \n\nTesting\n-------\n\n#.  Set up the Testing Runtime and Environment Variables\n\n    ::\n\n        source ~/.venvs/venvdrfpipeline/bin/activate\n        source ./envs/dev.env\n\n#.  Change to the ``webapp`` directory\n\n    Tests need to run in the same directory as the ``manage.py``\n\n    ::\n\n        cd webapp\n\n#.  Run all Tests\n\n    ::\n\n        python manage.py test\n\n#.  Run all Test Cases in a Test module\n\n    ::\n\n        python manage.py test drf_network_pipeline.tests.test_ml\n\n#.  Run a Single Test Case\n\n    ::\n        \n        python manage.py test drf_network_pipeline.tests.test_ml.MLJobTest.test_ml_predict_helper_works\n\n    or\n\n    ::\n\n        python manage.py test drf_network_pipeline.tests.test_user.AccountsTest.test_create_user_with_invalid_email\n\nLinting\n-------\n\nflake8 .\n\npycodestyle --exclude=.tox,.eggs,migrations\n\nLicense\n-------\n\nApache 2.0 - Please refer to the LICENSE_ for more details\n\n.. _License: https://github.com/jay-johnson/train-ai-with-django-swagger-jwt/blob/master/LICENSE\n\nCitations and Included Works\n============================\n\nSpecial thanks to these amazing projects for helping make this easier!\n\nOriginal Django project template from\n-------------------------------------\nhttps://github.com/jpadilla/django-project-template\n\nDjango REST Framework\n---------------------\nhttps://github.com/encode/django-rest-framework\n\nCelery\n------\n\nhttp://www.celeryproject.org/\n\nUser Registration\n-----------------\nhttps://github.com/szopu/django-rest-registration\n\nSwagger for Django\n------------------\nhttps://github.com/marcgibbons/django-rest-swagger\n\nJWT for Django REST\n-------------------\nhttps://github.com/GetBlimp/django-rest-framework-jwt\n\nKeras\n-----\nhttps://github.com/keras-team/keras\n\nTensorflow\n----------\nhttps://github.com/tensorflow\n\nSQLite\n------\nhttps://www.sqlite.org/index.html\n\nGunicorn\n--------\n\nhttp://docs.gunicorn.org/\n\nuWSGI\n-----\n\nhttps://uwsgi-docs.readthedocs.io/en/latest/\n\npgAdmin\n-------\n\nhttps://www.pgadmin.org/\n\nPostgreSQL\n----------\n\nhttps://www.postgresql.org/\n\nDjango Cacheops\n---------------\n\nhttps://github.com/Suor/django-cacheops\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjay-johnson%2Ftrain-ai-with-django-swagger-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjay-johnson%2Ftrain-ai-with-django-swagger-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjay-johnson%2Ftrain-ai-with-django-swagger-jwt/lists"}