Python InMojo API connector
Home Personal Python InMojo API connector

Python InMojo API connector

0 comment

InMojo is an excellent sales platform for open-source hardware products. However, it doesn’t have an official API to automate order and customer management. To work around this, I’ve put together a Python script that uses mechanize and BeautifulSoup to scrape order data from the website into a more API-friendly SQLite database. It also updates orders with new statuses, tracking numbers, and tracking URLs.

The InMojo system deals with sales by order number and by item name. The order number is unique, but the item name may repeat. However, present in hidden <input> elements on the sales list pages are unique ID values that are 48-byte alphanumeric strings. These identify both the order itself and the specific product variant ordered, regardless of the item name. This is handy for API-style interaction.

Here’s the syntax help that comes from running the script with no arguments:

inmojo_scrapi.py <command> [arg1 [arg2 [...]]]
    initialize              fetch complete sale history from InMojo
    update                  fetch status of all sales since last update/init
    getsale <sale_num>      output JSON-formatted sale record for given sale
    getsales [criteria]     output JSON-formatted sale/item collection
    getsales_csv [criteria] output CSV-formatted sale list
    getlines_csv [criteria] output CSV-formatted line item list

    CRITERIA:
        status=value                sales with the given status
        user=name                   sales from the given user
        beforeunix=timestamp        sales made before <timestamp>
        onafterunix=timestamp       sales made on or after <timestamp>
        beforedate=YYYY-mm-dd       sales made before <YYYY-mm-dd>
        onafterdate=YYYY-mm-dd      sales made on or after <YYYY-mm-dd>
        ubeforeunix=timestamp       sales updated before <timestamp>
        uonafterunix=timestamp      sales updated on or after <timestamp>
        ubeforedate=YYYY-mm-dd      sales updated before <YYYY-mm-dd>
        uonafterdate=YYYY-mm-dd     sales updated on or after <YYYY-mm-dd>

    setstatus <sale_num> <status> [tracking_number tracking_url]

Installation and Use

Using the script is pretty simple.

  1. Download inmojo_scrapi.py and credentials.json from Github OR just clone the repo
  2. Update credentials.json with your own InMojo username and password
  3. Install Python 2.7.x if you don’t already have it (haven’t tested Python 3)
  4. Use Python’s “easy_install” setup tool to install:
    • mechanize
    • BeautifulSoup
    • python-dateutil
  5. Run inmojo_scrapi.py initialize to get all existing sale records in your account so far
  6. Run inmojo_scrapi.py update from time to time to get all new or updated sale records
  7. Use the various get commands as desired to help integrate with any other tools you use

Output in JSON format with “getsale” or “getsales” will give you a structured list where each sale records includes items as a sub-object, easily parsed in a zillion different languages:

c:\Github\inmojo-api>inmojo_scrapi.py getsales onafterdate=2015-01-09

[{"status": "shipped", "updated": 1420815316, "items": [{"total": 80.0, "quantity": 2, "cost": 40.0, "id": "ag1zfmluLW1vam8taHJkchELEghNb2pvSXRlbRimxxxxxx", "name": "BLE112 Bluetooth Low Energy Breakout - Assembled"}, {"total": 0.0, "quantity": 1, "cost": 0.0, "id": "", "name": "Standard Domestic Shipping"}], "number": 5477579674999999, "tracking_url": "https://tools.usps.com/go/TrackConfirmAction_input?strOrigTrackNum=9400110200882465999999", "placed": 1420804567, "tracking_number": "9400110200882465999999", "user": "some_inmojo_user", "total": 80.0, "id": "ag1zfmluLW1vam8taHJkchYLEglNb2pvT3JkZXIYgICAtsxxxxxx"}]

The real output looks like the above (scrubbed of some customer and shipping data), but here’s what the JSON structure looks like formatted nicely:

[  
    {  
        "status":"shipped",
        "updated":1420815316,
        "items":[  
            {  
                "total":80.0,
                "quantity":2,
                "cost":40.0,
                "id":"ag1zfmluLW1vam8taHJkchELEghNb2pvSXRlbRimxxxxxx",
                "name":"BLE112 Bluetooth Low Energy Breakout - Assembled"
            },
            {  
                "total":0.0,
                "quantity":1,
                "cost":0.0,
                "id":"",
                "name":"Standard Domestic Shipping"
            }
        ],
        "number":5477579674999999,
        "tracking_url":"https://tools.usps.com/go/TrackConfirmAction_input?strOrigTrackNum=9400110200882465999999",
        "placed":1420804567,
        "tracking_number":"9400110200882465999999",
        "user":"some_inmojo_user",
        "total":80.0,
        "id":"ag1zfmluLW1vam8taHJkchYLEglNb2pvT3JkZXIYgICAtsxxxxxx"
    }
]

The CSV output is broken apart into separate sale list and line item detail list. Line items include order numbers for correlating data later. Note in the example output below (same as the JSON sale above) that there is one sale with two line items, one of which is a breakout board and the other of which is free shipping:

c:\Github\inmojo-api>inmojo_scrapi.py getsales_csv onafterdate=2015-01-09

Sale Number,Sale ID,Placed,Updated,User,Status,Items,Total,Tracking Number,Tracking URL
5477579674999999,ag1zfmluLW1vam8taHJkchYLEglNb2pvT3JkZXIYgICAtsxxxxxx,1420804567,1420815316,some_inmojo_user,shipped,1,$9400110200882465999999,https://tools.usps.com/go/TrackConfirmAction_input?strOrigTrackNum=9400110200882465999999

c:\Github\inmojo-api>inmojo_scrapi.py getlines_csv onafterdate=2015-01-09

Sale Number,Item ID,Item Name,Quantity,Cost,Total
5477579674999999,ag1zfmluLW1vam8taHJkchELEghNb2pvSXRlbRimxxxxxx,BLE112 Bluetooth Low Energy Breakout - Assembled,2,$40.00,$80.00
5477579674999999,,Standard Domestic Shipping,1,$0.00,$0.00

Note that the item count present in the CSV sale output does not include the shipping line, so the count is actually for the things that were ordered.

“ScrAPI” Limitations

There are certain things that are simply not possible from scraping the website, due to the fact that the information just isn’t there. For example:

  • There is no shipping address data available
  • There is no correlated PayPal payment data available

These things are only sent to sellers via email. For some reason, they’re not accessible through the web interface. Also, there are many things that this script could do which it doesn’t, such as:

  • Getting or setting inventory amounts
  • Listing, adding, or updating actual items or variants for sale

I did not add support for these things because they fall outside of the category of things that I need to automate (namely, order management).

I might add more features in the future, but I hope the site will incorporate an official API before then. For now, you can take the output of this script and integrate it into other systems such as QuickBooks, Endicia, PayPal, or inventory management tools.

You may also like

Leave a Comment