Skip to main content

Templates and scripts to rapidly spin up a production-ready Eve-based API.

Project description

eve-utils

Templates and scripts to rapidly spin up a production-ready Eve-based API.

Please note: although I currently use these tools to create production-ready APIs, the tools themselves are still under development. Use at your own risk.

Introduction

Eve is amazing. The full power of Flask/Python, optimized for an API over mongodb. Nice.

It does take a bit of work to go from the simple example in the docs...

settings = {'DOMAIN': {'people': {}}}

app = Eve(settings=settings)
app.run()

...to a production-ready API, with robust exception handling, logging, control endpoints, configurability, (and so much more).

eve-utils helps make some of that work easier.

Install eve-utils with pip.

pip install eve-utils

Getting Started

Get started with three easy steps

  1. Create your API (I recommend creating a virtual environment first)

    mkapi my-api --with_docker

    (note: if you don't have docker installed, create the API without --with-docker, then later run the API with python run.py - assuming you have mongodb running on localhost:27127)

  2. Add domain resources

    cd my-api
    mkresource people
    
  3. Build and launch the API

    cd ..
    image-build
    docker-compose up -d
    

    (note: image-build is usually called with a version number so the new docker image is correctly tagged - see more in the docs below)

Try it out with the following curl commands (or use Postman if you prefer)

curl http://localhost:2112
curl http://localhost:2112/_settings
curl -X POST http://localhost:2112/people -H "Content-type: application/json" -d "{\"name\":\"Michael\"}"
curl http://localhost:2112/people

If you followed the above, be sure to clean up after playing around with your new API:

docker-compose down

docker image rm my-api

Commands

  • mkapi <api-name>

    • creates folder named api-name

    • creates a skeleton Eve API in that folder

    • for more details run mkapi -h

  • mkresource <resource-name>

    • adds resource-name to the domain

    • default fields are name, description

    • add fields by modifying domain/resource-name.py - as you would any Eve resource

    • NOTE: resources in Eve are collections, so eve-utils names resources as plural by convention,

      • i.e. if you enter mkresource dog it will create an endpoint named /dogs

      • eve-utils rely on the inflect library for pluralization, which is very accurate but can make mistakes

  • mkrel <parent-resource> <child-resource>

    • For example:

      mkresource person
      mkresource cars
      mkrel person car
      
      • you could also have typed mkrel people cars or mkrel person cars - they all are equivalent
    • If you followed the example above, you have already POSTed a person named Michael:

      curl -X POST http://localhost:2112/people -H "Content-type: application/json" -d "{\"name\":\"Michael\"}"

    • Normally GET a person by _id. eve-utils wires up the name field as an additonal_lookup, so you can also GET by name.

      curl http://localhost:2112/people/Michael?pretty

      {
        "_id": "606f5453b43a8f480a1b8fc6",
        "name": "Michael",
        "_updated": "2021-04-08T19:06:59",
        "_created": "2021-04-08T19:06:59",
        "_etag": "6e91d500cbb0a2f6645d9b4dced422d429a69820",
        "_links": {
          "self": { "href": "/people/606f5453b43a8f480a1b8fc6", "title": "person" },
          "parent": { "title": "home", "href": "/" },
          "collection": { "title": "people", "href": "people" },
          "cars": { "href": "/people/606f5453b43a8f480a1b8fc6/cars", "title": "cars" }
        }
      }
      
    • Notice the _links field includes a rel named cars. You can POST a car to that href (I'll demonstrate with Javascript):

      const axios = require('axios')
      axios.defaults.baseURL = 'http://localhost:2112'
      
      axios.get('/people/Michael').then((response) => {
          const person = response.data
          const car = {
              name: 'Mustang'
          }
          axios.post(person._links.cars.href, car)
      })
      
    • -p --as_parent_ref: field name defaults to _ parent-resource _ref, e.g. if the parent name was dogs the field would be _dog_ref. Using this parameter, the field name become literally _parent_ref. Useful to implement generic parent traversals.

  • add_docker <api-name> - run this in the folder above the root api folder to create a basic docker files and some useful build scripts (to be further documented later).

    • NOTE: not necessary if you have created the API using --with_docker

    • Adds the following files:

      Dockerfile

      docker-compose.yml (note: by default this file does not use a volume for mongodb, so killing the container also kills your data)

      .docker-ignore

      image-build

      image-build.bat

  • add_auth - run this in the API folder. It will add a folder named auth with modules to add authorization to your API (docs to come)

    • NOTE: not necessary if you have created the API using --with_auth
    • NOTE: the only supported IdP is Auth0 at the moment, but it will be fairly easy to manually tweak to use any OAuth2 JWT issuer. (I have used a forked Glewlwyd with very minimal changes)
  • add_val - run this in the API folder. It will add a folder named validation with a module that adds custom validator to EveService. Use this to extend custom validations. It comes with two:

    • NOTE: not necessary if you have created the API using --with_val

    • unique_ignorecase - works exactly like the built-in unique validator except case is ignored

    • unique_to_parent - set this to a string of a resource's parent (singular!). Uniqueness will only be applied to sibling resources, i.e. the same name can be used if the resource has a different parent.

      • e.g.

        mkresource region
        mkresource store
        mkrel region store
        

        Now in domain.store, change the name field definition from this:

        'name": {
          'type': 'string',
                ...
          'unique': True
        }
        

        to this:

        'name": {
          'type': 'string',
                ...
          'unique_to_parent': 'region'
        }
        

MORE TO COME!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for eve-utils, version 0.9.2
Filename, size File type Python version Upload date Hashes
Filename, size eve_utils-0.9.2-py3-none-any.whl (53.4 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size eve-utils-0.9.2.tar.gz (39.6 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page