Link Search Menu Expand Document

Shareable Module Factory Developer Documentation

Introduction - Shareable Modules

What is a shareable module? A shareable module is a self-contained piece of reusable code designed to be used across multiple Crowdbotics projects. Modules are structured as a set of files and folders, generally written in React Native and/or Django.

What are modules used for? Modules provide a robust, easy to use set of building blocks for many common features you’ll encounter building an application. Because they are reusable, modules provide a simple, clean way to avoid rewriting application code over and over again. Rather than rebuilding the same feature for every project, modules empower you to reuse code and save time so that you can focus on the more interesting parts of building software.

How can I use modules?

  • To install a module in your project, start by clicking on the modules tab from the Storyboard panel of the Crowdbotics dashboard.
  • Drag and drop a module onto your app.
  • Once your module is on the storyboard, click and drag between the white dots to create a link between screens.
  • Finally, click save on the top right to finalize your changes.

Module Storyboard Editor

For some modules, that’s all the setup required. Your app should be ready following another deploy. Other, more involved modules may require further configuration. See the module’s README.md files for more specific information.

Why write a module? If you’re working on multiple software projects, writing a module will allow you to save time and development cost by reusing module content across those projects. If you have to write a feature you know you’ll need to use again in future projects, that should probably be a module.

Use Cases Modules can be as simple as one page Terms and Conditions Screens, and as complex as you like. There is a healthy and continually expanding library of modules already available on the crowdbotics platform. Have a look at some of these modules to get a sense of what they can offer your future software projects:


Writing a Module: An overview of the process:

Writing a shareable module is a multi-step process that includes the following steps:

  1. Forking the crowdbotics/modules repo and setting up your module’s file structure.
  2. Writing your module code.
  3. Testing your module code in a demo project, which you can deploy on the web.
  4. Submitting your module for acceptance testing by Crowdbotics.
  5. Releasing your module for use in the Crowdbotics ecosystem.

Writing a Module, Part 1: Fork the code and set up your file structure.

  1. You’ll begin by forking the crowdbotics/modules repo. In addition to being where your module code will eventually live, this repo also contains useful utility commands and other module examples you can use as examples. https://github.com/crowdbotics/modules
  2. Begin writing your module code by creating a new folder within the modules/modules folder. You can confirm you are in the right directory by running ls in the terminal. In the output, you should see a handful of other modules in this folder, for example django-articles, django-push-notifications, etc. This folder you have just created will house your module code. You have two basic approaches you can use in creating a module:

    1. If your module will be purely Django or React Native code, make a new folder within the modules/modules repo that is prefixed with the appropriate name, either django-my-new-module or react-native-my-new-module. For example, (run these commands from modules repository root): cd /modules/ && mkdir django-my-new-module or cd /modules/ && mkdir react-native-my-new-module

    2. If you need more flexibility for your module, or want to include both frontend and backend components, simply name your module folder without a prefix: (run this from the modules repo root again): cd modules && mkdir my-new-module

      Note that if you go with option B, you’ll need to create some additional folders within your newly created module directory. There’s an example of this in the Gotchas and Common Errors section below, though the best way to understand what you’ll need is to look at the terms-and-conditions or privacy-policy modules.

  3. Give your new module a meta.json. Specify a name, description, and root path for your module here. You should create this within the folder you created in the previous step. The meta.json specifies the root install path for your module, relative to the top-level domain of the app that you are installing the module into. Here’s an example meta.json for the Terms And Conditions app, which installs at the root directory level.
    {
      "title": "Terms and Conditions",
      "description": "Terms and Conditions screen",
      "root": "/"
    }

And here’s the meta.json for the django-articles module, which is purely backend code. Note that since this is just backend, the root specifies the /backend/modules folder, where django modules (which are also django apps, more on this below) are generally installed.

{
  "title": "Articles (Django)",
  "description": "Backend for the Articles module.",
  "root": "/backend/modules"
}

Your meta.json should always be in the root of your module folder. This file will not be installed in an app. The purpose of the meta.json is that this is the main DSL mechanism we use for you as a modules author to specify options such as names, titles, and root paths.

Writing a Module, Part 2: Writing your Module Code

Modules can be as simple or as complex as you like. They can be made up of numerous new files and directories, or very few. Good modules are written to accomplish one thing, however complex that thing is, and they should be made as simple and reusable as possible. If you are writing a module, always keep in mind that future developers will use this module in a wide variety of contexts — hence, simplicity and reusability are key.

  • There are example modules to look at in modules/modules . This is highly recommended, as it will give you some ideas about how modules function and are structured.
  • In particular, modules/modules/django-articles and andmodules/modules/react-native-articles, which work together to provide a CRUD backend and frontend, are a great starting place for understanding how modules work.
  • These docs provide a guide on how to approach authoring a module, particularly a React Native module.

What kind of code/filetypes can I include in my module? You can include any filetype you’d like in a module. Generally speaking, your module will be made up of some combination of .py, .js, .json, and .md (for readme) files, as you will generally be writing python and React Native code in your modules. But you can also include other files, as needed. Should you, for instance, need static files, like images, or Terraform config files, like .tf or .tf.json, those may also be included.

A bit about Django:

Modules are Django Applications As of May 2021, all new backend modules will be structured as Django Applications. This means that backend modules can include their own migrations and configurations, and generally work like normal Django Applications. Purely frontend modules are unaffected by this change, and are still written in React native.

Modules should use PEP 8 style Your Django modules should conform to PEP 8 standards whenever possible, which includes using snake case (naming with an underscore). More here: https://www.python.org/dev/peps/pep-0008/

Namespacing and Configuring your Module Your module exists in the modules namespace. This means that you need to define an

__init__.py

file, which should look something like this:

default_app_config = "modules.privacy_policy.apps.PrivacyPolicyConfig"

This file should point to another file you’ll need to add, apps.py. This should look something like this:

from django.apps import AppConfig

class PrivacyPolicyConfig(AppConfig):
    name = "modules.privacy_policy"
    verbose_name = "Privacy Policy"

More information about Django apps can be found here (links to the 2.2 docs, but confirm you are using the same version of django as appears in the scaffold): https://docs.djangoproject.com/en/2.2/ref/applications/#configuring-applications

Writing a Module, Part 3: Testing your Module

After you’ve written your module, you can test it before submitting by creating a demo app and installing your module in there. You can then test by running the demo app locally or deploying it using the crowdbotics dashboard.

A demo app is a simple app that mirrors what you get when you start a new crowdbotics project: A Django backend and a React Native frontend, all combined in one folder with some configuration settings. This allows you to mimic the experience other developers will have when they install your module in their Crowdbotics app.

  1. Begin by running npm run demo within the root modules folder. This will initialize a new demo app inside modules/demo.
  2. You can now add your module to the demo app by using npm run add <module-name>. The module name is the same name as the folder you created in Part 1. If you have any problems with this step, check to make sure that your meta.json is configured with the project root, and that your names match.
    • We also recommend installing the [react-native-app-menu](http://react-native-app-menu) app if you are testing a module that includes react-native, as this will give you an automatically populated app menu from which you can easily see all available routes—including your new module.
    • If you are working on a backend project, you can get a similar functionality by using the django management command manage.py show_urls. On docker, this can be run (in a seperate window from where you run docker-compose up) with docker-compose exec web python3 manage.py show_urls. You can also add the following to filter for module-related urls: …manage.py show_urls | grep "modules"
  3. Try out your module inside the demo project. There are two basic ways to test your module within the demo project: locally or by deploying using the Crowdbotics dashboard. You can do both! Local testing may be a little bit quicker if you are already set up with the Crowdbotics scaffold and docker, though deploying using the Crowdbotics dashboard will allow you to test more network functionality.
    1. Running the app locally
      1. To run your app locally, first run cd demo after running the npm run demo and npm run add <module>commands above from the /modules root directory.
      2. To start the backend, cd backend and follow the instructions in the backend/README.md about setting up the app. Docker is recommended.
      3. To start the frontend, follow the instructions in demo/README.md to run your app using the iOS or Android emulator.
    2. Deploying the app using the Crowdbotics dashboard. Using the Crowdbotics dashboard, you can create a new project from a github repo. To do this, we’ll first create a repo for the demo app, then use the dashboard to deploy our app.
      1. Make sure you have initialized a demo app and added your module(s) using the npm run demo and npm run add <module>commands above.
      2. Clone the git repo by finding the associated github repository in your app’s setting panel.
      3. Remove all the code generated in this repo. You will replace this with the code from modules/demo. After running cd <path/to/your/new-project-repo>, you can simply run rm -r *
      4. Copy your demo app into your newly empty project. cp -r path/to/modules/demo path/to/your/new-project-repo
      5. Commit and push your changes to the remote repository.
      6. Deploy using the Crowdbotics dashboard.
      7. Once your app is deployed, you can use https://app.crowdbotics.com/dashboard/app//settings to generate admin credentials. You can then navigate to your app’s django admin panel by going to: .botics.co/admin/. API documentation is automatically generated and available at: .botics.co/api-docs/.

Writing a Module, Part 4: Submitting for Acceptance

After you’ve written and tested your module, it’s time to submit it for acceptance testing. Acceptance testing ensures that all modules on the Crowdbotics platform are functional, reusable, and conform to our quality standards.

Module Acceptance Criteria:

  • The module must have a clear name and description.
  • The module must work! We should be able to install, configure, and run your module using instructions in your README.md.
  • Speaking of README’s, Your module should contain at least one. Your README.md should include a detailed description of what your module does, as well as complete instructions for configuration, installation, and usage. If you have both backend and frontend components in your module, each of those should have its own README.
  • Your module should be reusable. The purpose of modules is to easily share code, but for that to work, the code in your module should work in almost every case — and ideally be extensible enough to cover all cases.

Submitting your module

  1. One you’ve finished writing and testing your module, make sure you have all of your changes saved in the modules repository, i.e. modules/modules/my-new-module.
    1. A common mistake is to make changes within your modules/demo project that you set up for testing in Part 3. Changes you make there will need to be imported back into the modules repo, which you can do manually or by copying your relevant module folders back into the modules repo.
  2. Make sure your git fork is in sync with with the master branch. You may need to git pull or git rebase from the development branch.
  3. Important! Within the modules repository, run **npm run parse. This command adds your module to the modules.json script which is generated. We use this for some of our own config and testing.
  4. Add your changes, commit them, and submit a PR against the crowdbotics/modules repository.
  5. Your module has been submitted for acceptance testing! We will be in touch with next steps, if any, required for acceptance.

Writing a Module, Part 5: Release!

After your module passes acceptance testing, we will release it to the rest of our developer community. You will see your module listed on the Crowdbotics storyboard as a module available to install in any Crowdbotics project. Congratulations, and thank you for writing a Crowdbotics module!

Gotchas and Common Errors - Under Construction

  • [pipenv.exceptions.InstallError]: ['THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes.
    • This error pops up if your backend’s Pipfile.lock has gone out of date. This is fairly rare, but can happen from time to time. The easiest way to fix this is to run pipenv lock from your demo/backend folder to rebuild the Pipfile with the appropriate requirements and hashes.
  • Problems with running npm run add or npm run parse: If you experience issues running these commands, you likely have an issue with your file structure. Ensure you are using the following structure to save your files:
    • Backend: $ modules/modules/my-module/backend/modules/my_module/(python code).
      • Migrations should be nested one folder deeper, e.g.: modules/modules/my-module/backend/modules/my_module/migrations/0001_my-first-migration.py
    • Frontend: $ modules/modules/my-module/modules/my-module/(js code)
      • Note that if you write a module with both backend and frontend components, your backend code will be nested one level deeper than your frontend code:
      terms-and-conditions <-the root of your module code, eg. /modules/modules/my-module.
      ├── backend 
      │   └── modules <-note that your backend code is nested one level deeper here.
      │       └── terms_and_conditions <- because this is django code, use snake case.
      │           ├── README.md
      │           ├── __init__.py
      │           ├── admin.py
      │           ├── apps.py
      │           ├── migrations
      │           │   ├── 0001_terms_initial.py
      │           │   └── __init__.py
      │           ├── models.py
      │           ├── serializers.py
      │           ├── urls.py
      │           └── viewsets.py
      ├── meta.json <-this is where you set the root that you want your files installed to in the app.
      └── modules <-this is the folder, one level higher, for your FE code.
          └── terms-and-conditions <-because this is RN, use hypens here.
              ├── README.md
              ├── index.js
              ├── package.json
              └── styles.js
    
    • Finally, make sure you have a meta.json here: $ modules/modules/my-module/meta.json
  • Proper Casing: React Native uses hyphenated folder names, while Django uses snake case. Your top level module directory should also use hyphens. For example,
    • $ modules/modules/my-module/backend/modules/my_module/(python code). Note that the first my-module folder is hyphenated. This is your top level module directory.

    • Then, notice how the snake-cased my_module folder is specifically nested under backend/modules.

    • However, for React Native, you use hyphens, for example: $ modules/modules/my-module/modules/my-module/(js code). Note here that there are two identically named folders called my-module. The top most folder stores all of your module code (if you are writing a module with both backend and frontend components), while the second folder stores only your RN code.