Skip to content

Commit

Permalink
Add Beta REST API: OpenAPI and autogenerated client
Browse files Browse the repository at this point in the history
  • Loading branch information
jrwdunham committed Jun 18, 2018
1 parent d596820 commit 2c4f950
Show file tree
Hide file tree
Showing 36 changed files with 7,108 additions and 9 deletions.
4 changes: 3 additions & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ django-extensions==1.7.9
django-model-utils==3.0.0
#tastypie 0.13.3 has breaking changes
django-tastypie==0.13.1
formencode==1.3.1
futures==3.0.5 # used by gunicorn's async workers
gevent==1.2.1 # used by gunicorn's async workers
gunicorn==19.7.1
inflect==0.2.1
jsonfield==2.0.1
logutils==0.3.4.1
lxml==3.7.3
metsrw==0.2.0
git+https://github.com/artefactual-labs/mets-reader-writer.git@dev/issue-11581-premis-parsing
ndg-httpsclient==0.4.2
pyasn1==0.2.3
python-gnupg==0.4.0
Expand Down
112 changes: 112 additions & 0 deletions storage_service/locations/api/beta/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
"""Version beta of the Storage Service API.
The Storage Service exposes the following resources via a consistent HTTP JSON
interface under the path namespace /api/beta/:
- /locations/ --- purpose-specific paths within a /spaces/ resource
- /spaces/ --- storage space with behaviour specific to backing system
- /pipelines/ --- an Archivematica instance that is the source of a package
The following resources are read-only (update, create, delete and related
operations are disabled):
- /packages/ --- Information Package (SIP, DIP or AIP)
- /file/ --- a file on disk (which is in a package), represented as db row.
All resources have endpoints that follow this pattern::
+-----------------+-------------+----------------------------+------------+
| Purpose | HTTP Method | Path | Method |
+-----------------+-------------+----------------------------+------------+
| Create new | POST | /<cllctn_name>/ | create |
| Get create data | GET | /<cllctn_name>/new/ | new |
| Read all | GET | /<cllctn_name>/ | index |
| Read specific | GET | /<cllctn_name>/<id>/ | show |
| Update specific | PUT | /<cllctn_name>/<id>/ | update |
| Get update data | GET | /<cllctn_name>/<id>/edit/ | edit |
| Delete specific | DELETE | /<cllctn_name>/<id>/ | delete |
| Search | SEARCH | /<cllctn_name>/ | search |
| Search | POST | /<cllctn_name>/search/ | search |
| Get search data | GET | /<cllctn_name>/new_search/ | new_search |
+-----------------+-------------+----------------------------+------------+
.. note:: To remove the search-related routes for a given resource, create a
``'searchable'`` key with value ``False`` in the configuration for the
resource in the ``RESOURCES`` dict. E.g., ``'location': {'searchable':
False}`` will make the /locations/ resource non-searchable.
.. note:: All resources expose the same endpoints. If a resource needs special
treatment, it should be done at the corresponding class level. E.g., if
``POST /packages/`` (creating a package) is special, then do special stuff
in ``resources.py::Packages.create``. Similarly, if packages are indelible,
then ``resources.py::Packages.delete`` should return 404.
"""

from locations.api.beta.remple import API
from locations.api.beta.resources import (
ArkivumSpaces,
# Asyncs,
Callbacks,
DataverseSpaces,
DSpaceSpaces,
DuracloudSpaces,
Events,
FedoraSpaces,
FixityLogs,
LockssomaticSpaces,
NFSSpaces,
S3Spaces,
SwiftSpaces,
Files,
GPGSpaces,
LocalFilesystemSpaces,
Locations,
Packages,
Pipelines,
PipelineLocalSpaces,
Spaces,
Users,
Groups,
Permissions,
ContentTypes,
)

API_VERSION = 'beta'
SERVICE_NAME = 'Archivematica Storage Service'

resources = {
'pipeline': {'resource_cls': Pipelines},
'location': {'resource_cls': Locations},
'space': {'resource_cls': Spaces},
'user': {'resource_cls': Users},

# Space sub-types
'local_filesystem_space': {'resource_cls': LocalFilesystemSpaces},
'gpg_space': {'resource_cls': GPGSpaces},
'arkivum_space': {'resource_cls': ArkivumSpaces},
'dataverse_space': {'resource_cls': DataverseSpaces},
'dspace_space': {'resource_cls': DSpaceSpaces},
'duracloud_space': {'resource_cls': DuracloudSpaces},
'fedora_space': {'resource_cls': FedoraSpaces},
'lockssomatic_space': {'resource_cls': LockssomaticSpaces},
'nfs_space': {'resource_cls': NFSSpaces},
's3_space': {'resource_cls': S3Spaces},
'swift_space': {'resource_cls': SwiftSpaces},
'pipeline_local_space': {'resource_cls': PipelineLocalSpaces},

# The following resources are read-only because of their super-classes
'file': {'resource_cls': Files},
'package': {'resource_cls': Packages},
'event': {'resource_cls': Events},
'callback': {'resource_cls': Callbacks},
'fixity_log': {'resource_cls': FixityLogs},
'group': {'resource_cls': Groups},
'permission': {'resource_cls': Permissions},
'contenttype': {'resource_cls': ContentTypes},
}

api = API(api_version=API_VERSION, service_name=SERVICE_NAME)
api.register_resources(resources)
urls = api.get_urlpatterns()

__all__ = ('urls', 'api')
14 changes: 14 additions & 0 deletions storage_service/locations/api/beta/remple/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
================================================================================
Remple: REST Simple
================================================================================

Usage::

>>> from remple import API, Resources
>>> class Users(Resources):
... model_cls = User # A Django model class
... schema_cls = UserSchema # A Formencode class
>>> resources = {'user': {'resource_cls': Users}}
>>> api = API(api_version='0.1.0', service_name='User City!')
>>> api.register_resources(resources)
>>> urls = api.get_urlpatterns() # Include these in Django urlpatterns
60 changes: 60 additions & 0 deletions storage_service/locations/api/beta/remple/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Remple: REST Simple
Usage::
>>> from remple import API, Resources
>>> class Users(Resources):
... model_cls = User # A Django model class
... schema_cls = UserSchema # A Formencode class
>>> resources = {'user': {'resource_cls': Users}}
>>> api = API(api_version='0.1.0', service_name='User City!')
>>> api.register_resources(resources)
>>> urls = api.get_urlpatterns() # Include thes in Django urlpatterns
"""

from __future__ import absolute_import

from .resources import Resources, ReadonlyResources
from .querybuilder import QueryBuilder
from .routebuilder import RouteBuilder as API
from .routebuilder import (
ID_PATT,
UUID_PATT,
get_collection_targeting_regex,
get_member_targeting_regex,
)
from .openapi import (
CustomEndPoint,
schema_name2path,
get_error_schema_path,
get_ref_response,
)
from . import utils
from .schemata import ResourceURI
from .constants import (
OK_STATUS,
NOT_FOUND_STATUS,
UNAUTHORIZED_MSG,
FORBIDDEN_STATUS,
)

__all__ = (
'API',
'CustomEndPoint',
'FORBIDDEN_STATUS',
'ID_PATT',
'NOT_FOUND_STATUS',
'OK_STATUS',
'QueryBuilder',
'ReadonlyResources',
'Resources',
'ResourceURI',
'UNAUTHORIZED_MSG',
'UUID_PATT',
'get_collection_targeting_regex',
'get_error_schema_path',
'get_ref_response',
'get_member_targeting_regex',
'schema_name2path',
'utils',
)
Loading

0 comments on commit 2c4f950

Please sign in to comment.