Package: sandman
sandmanHomepageVisit the home ofsandmanon the web:sandman.ioDiscussLooking for a place to ask questions about sandman? Check out the
sandman-discuss and sandman-users forums!DocumentationSandman documentationsandman“makes things REST”. Have an existing database you’d like to
expose via a REST API? Normally, you’d have to write a ton of
boilerplate code for the ORM you’re using, then integrate that into some
web framework.I don’t want to write boilerplate.Here’s what’s required to create a RESTful API service from an existing
database usingsandman:$sandmanctlsqlite:////tmp/my_database.dbThat’s it.sandmanwill then do the following:connect to your database and introspect its contentscreate and launch a REST API servicecreate an HTML admin interfaceopen your browser to the admin interfaceThat’s right. Given a legacy database,sandmannot only gives you a
REST API, it gives you a beautiful admin page andopens your browser to
the admin page. It truly does everything for you.Supported Databasessandman, by default, supports connections to the same set of
databases asSQLAlchemy. As of this
writing, that includes:MySQL (MariaDB)PostgreSQLSQLiteOracleMicrosoft SQL ServerFirebirdDrizzleSybaseIBM DB2SAP Sybase SQL AnywhereMonetDBAuthenticationAs of version 0.9.3,sandmanfully supports HTTP Basic
Authentication! See the documentation for more details.Behind the Scenessandmanctlis really just a simple wrapper around the following:fromsandmanimportappapp.config['SQLALCHEMY_DATABASE_URI']='sqlite:///chinook'fromsandman.modelimportactivateactivate()app.run()You don’t even need to tell ``sandman`` what tables your database
contains.Just pointsandmanat your database and let it do all
the heavy liftingLet’s start our new service and make a request. While we’re at it, lets
make use ofsandman’s awesome filtering capability by specifying a
filter term:>pythonrunserver.py&*Runningonhttp://127.0.0.1:5000/>curlGET"http://localhost:5000/artists?Name=AC/DC"...{"resources":[{"ArtistId":1,"Name":"AC/DC","links":[{"rel":"self","uri":"/artists/1"}]}]}All of that, including filtering/searching, is automagically available
from thosefivemeasly lines of code.Oh, that’s not enough? You also want a Django-style admin interface
built automatically? Fine. You may have noticed that when you ranrunserver.pythat a browser window popped up. Now’s the time to go
check that out. You’ll find it’s that Django-style admin interface
you’ve been bugging me about, looking something like this:admin interface awesomesauce screenshot(If you want to disable the browser from opening automatically each timesandmanstarts, callactivatewithbrowser=False)If you wanted to specify specific tables thatsandmanshould make
available, how do you do that? With this little ditty:fromsandman.modelimportregister,ModelclassArtist(Model):__tablename__='Artist'classAlbum(Model):__tablename__='Album'classPlaylist(Model):__tablename__='Playlist'register((Artist,Album,Playlist))And if you wanted to add custom logic for an endpoint? Or change the
endpoint name? Or change your top level json object name? Or add
validation? All supported. Here’s a “fancy” class definition:classStyle(Model):"""Model mapped to the "Genre" table

    Has a custom endpoint ("styles" rather than the default, "genres").
    Only supports HTTP methods specified.
    Has a custom validator for the GET method.

    """__tablename__='Genre'__endpoint__='styles'__methods__=('GET','DELETE')__top_level_json_name__='Genres'@staticmethoddefvalidate_GET(resource=None):"""Return False if the request should not be processed.

        :param resource: resource related to current request
        :type resource: :class:`sandman.model.Model` or None

        """ifisinstance(resource,list):returnTrueelifresourceandresource.GenreId==1:returnFalsereturnTrueWithsandman, zero boilerplate code is required. In fact, usingsandmanctl,no code is required at all. Your existing database
structure and schema is introspected and your database tables magically
get a RESTful API and admin interface. For each table,sandmancreates:proper endpointssupport for a configurable set of HTTP verbsGETPOSTPATCHPUTDELETEresponses with appropriaterellinks automaticallyforeign keys in your tables are represented by linkcustom validation by simply definingvalidate_<METHOD>methods on
your Modelexplicitly list supported methods for a Model by setting the__methods__attributecustomize a Models endpoint by setting the__endpoint__methodessentially a HATEOAS-based service sitting in front of your databasesandmanis under active development but should be usable in any
environment due to one simple fact:``sandman`` never alters your database unless you add or change a
record yourself. It adds no extra tables to your existing database and
requires no changes to any of your existing tables. If you start
``sandman``, use it to browse your database via cURL, then stop
``sandman``, your database will be in exactly the same state as it was
before you began.Installationpip install sandmanExample ApplicationTake a look in thesandman/testdirectory. The application found
there makes use of theChinooksample SQL database.Contact MeQuestions or comments aboutsandman? Hit me up atjeff@jeffknupp.com.ChangelogVersion 0.9.8Support for thewheeldistribution formatVersion 0.9.7Slightly better test coverage and documentationVersion 0.9.6Support for using existing declarative models alongsidesandmangenerated modelsIf you have an existing app and want to include sandman in it,
simply pass your existing models in to theregister()function
along with anysanmdmangenerated classes.sandmanwill
detect the existing models and augment them.Version 0.9.5Fixes a critical bug where code used by the newetagdecorators
was accidentally not included. Thanks to @mietek for the PR.Fixes an issue when showing the HTML representation of an empty
collection.Thanks to @mietek for reporting the issue.Version 0.9.4Fixes a critical bug in the requirements portion ofsetup.py,
addingFlask-HTTPAuthVersion 0.9.3Authentication supported!Entire API and admin can be protected by HTTP Basic Auth. See the
docs for more details.ETAGsResources return the proper ETAG header and should reply with a
304 after the first request. This greatly improves the throughput
and performance of the API.Version 0.9.2ThemetaendpointAll resources now have a/<resource>/metaendpoint that
describes the types of each of their fields (both in HTML and
JSON)The root endpointA “root” endpoint (/) has been created. It lists all resources
registered in the application and includes URLs to their various
endpoints. This allows a “dumb” client to navigate the API without
knowing URLs beforehand.Version 0.9.1Python 3 support!sandmantests now pass for both 2.7 and 3.4! Python 3.4 is
officially supported.Version 0.8.1New FeatureLinkheader now set to a resource’s linksLinks to related objects now user a properrelvalue:relatedThe link to the current resource still uses theselfrelvalueLinks are specified both in the header (as per RFC5988) and in the
resource itselfPagination added for JSON (and number of results per page being
returned is fixed)Nested JSON models no longer the default; hitting a URL with the
argument “expand” will show one level of nested resourcesThis conforms more closely to REST principles while not
sacrificing the functionality.Version 0.7.8Bug FixesFix multiple references to same table error (fixes #59)