def root(request, format=None, **kwargs): """ The documentation for the Open Science Framework API can be found at [developer.osf.io](https://developer.osf.io). The contents of this endpoint are variable and subject to change without notification. """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None flags = [name for name in Flag.objects.values_list('name', flat=True) if flag_is_active(request, name)] kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, 'active_flags': flags, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'schemas': utils.absolute_reverse('schemas:registration-schema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), }, } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def optimize_node_queryset(self, queryset): auth = get_user_auth(self.request) admin_scope = has_admin_scope(self.request) abstract_node_contenttype_id = ContentType.objects.get_for_model( AbstractNode).id guid = Guid.objects.filter( content_type_id=abstract_node_contenttype_id, object_id=OuterRef('parent_id')) parent = NodeRelation.objects.annotate( parent__id=Subquery(guid.values('_id')[:1])).filter( child=OuterRef('pk'), is_node_link=False) wiki_addon = WikiNodeSettings.objects.filter(owner=OuterRef('pk'), deleted=False) contribs = Contributor.objects.filter(user=auth.user, node=OuterRef('pk')) return queryset.prefetch_related('root').prefetch_related( 'subjects').annotate( user_is_contrib=Exists(contribs), contrib_read=Subquery(contribs.values('read')[:1]), contrib_write=Subquery(contribs.values('write')[:1]), contrib_admin=Subquery(contribs.values('admin')[:1]), has_wiki_addon=Exists(wiki_addon), annotated_parent_id=Subquery(parent.values('parent__id')[:1], output_field=CharField()), annotated_tags=ArrayAgg('tags__name'), has_admin_scope=Value(admin_scope, output_field=BooleanField()), )
def root(request, format=None, **kwargs): """ The documentation for the Open Science Framework API can be found at [developer.osf.io](https://developer.osf.io). """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'metaschemas': utils.absolute_reverse('metaschemas:metaschema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), } } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def get_object(self): user = utils.get_user_auth(self.request).user file = self.get_file() if self.request.GET.get('create_guid', False): # allows quickfiles to be given guids when another user wants a permanent link to it if (self.get_node().has_permission(user, 'admin') and utils.has_admin_scope(self.request)) or file.node.is_quickfiles: file.get_guid(create=True) return file
def get_object(self): user = utils.get_user_auth(self.request).user if (self.request.GET.get('create_guid', False) and self.get_node().has_permission(user, 'admin') and utils.has_admin_scope(self.request)): self.get_file(check_permissions=True).get_guid(create=True) return self.get_file()
def optimize_node_queryset(self, queryset): OSFUserGroup = apps.get_model('osf', 'osfuser_groups') auth = get_user_auth(self.request) admin_scope = has_admin_scope(self.request) abstract_node_contenttype_id = ContentType.objects.get_for_model( AbstractNode).id guid = Guid.objects.filter( content_type_id=abstract_node_contenttype_id, object_id=OuterRef('parent_id')) parent = NodeRelation.objects.annotate( parent__id=Subquery(guid.values('_id')[:1])).filter( child=OuterRef('pk'), is_node_link=False) wiki_addon = WikiNodeSettings.objects.filter(owner=OuterRef('pk'), deleted=False) preprints = Preprint.objects.can_view(user=auth.user).filter( node_id=OuterRef('pk')) region = Region.objects.filter(id=OuterRef('region_id')) node_settings = NodeSettings.objects.annotate( region_abbrev=Subquery(region.values('_id')[:1])).filter( owner_id=OuterRef('pk')) admin_permission = Permission.objects.get( codename=permissions.ADMIN_NODE) write_permission = Permission.objects.get( codename=permissions.WRITE_NODE) read_permission = Permission.objects.get( codename=permissions.READ_NODE) contrib = Contributor.objects.filter(user=auth.user, node=OuterRef('pk')) user_group = OSFUserGroup.objects.filter( osfuser_id=auth.user.id if auth.user else None, group_id=OuterRef('group_id')) node_group = NodeGroupObjectPermission.objects.annotate( user_group=Subquery(user_group.values_list('group_id') [:1])).filter(user_group__isnull=False, content_object_id=OuterRef('pk')) # user_is_contrib means user is a traditional contributor, while has_read/write/admin are permissions the user has either through group membership or contributorship return queryset.prefetch_related('root').prefetch_related( 'subjects').annotate( user_is_contrib=Exists(contrib), has_read=Exists( node_group.filter(permission_id=read_permission.id)), has_write=Exists( node_group.filter(permission_id=write_permission.id)), has_admin=Exists( node_group.filter(permission_id=admin_permission.id)), has_wiki_addon=Exists(wiki_addon), annotated_parent_id=Subquery(parent.values('parent__id')[:1], output_field=CharField()), has_viewable_preprints=Exists(preprints), has_admin_scope=Value(admin_scope, output_field=BooleanField()), region=Subquery(node_settings.values('region_abbrev')[:1]), )
def optimize_node_queryset(self, queryset): auth = get_user_auth(self.request) admin_scope = has_admin_scope(self.request) abstract_node_contenttype_id = ContentType.objects.get_for_model(AbstractNode).id guid = Guid.objects.filter(content_type_id=abstract_node_contenttype_id, object_id=OuterRef('parent_id')) parent = NodeRelation.objects.annotate(parent__id=Subquery(guid.values('_id')[:1])).filter(child=OuterRef('pk'), is_node_link=False) wiki_addon = WikiNodeSettings.objects.filter(owner=OuterRef('pk'), deleted=False) contribs = Contributor.objects.filter(user=auth.user, node=OuterRef('pk')) return queryset.prefetch_related('root').prefetch_related('subjects').annotate( contrib_read=Subquery(contribs.values('read')[:1]), contrib_write=Subquery(contribs.values('write')[:1]), contrib_admin=Subquery(contribs.values('admin')[:1]), has_wiki_addon=Exists(wiki_addon), annotated_parent_id=Subquery(parent.values('parent__id')[:1], output_field=CharField()), annotated_tags=ArrayAgg('tags__name'), has_admin_scope=Value(admin_scope, output_field=BooleanField()))
def root(request, format=None, **kwargs): """ The documentation for the Open Science Framework API can be found at [developer.osf.io](https://developer.osf.io). """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'metaschemas': utils.absolute_reverse('metaschemas:registration-metaschema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), } } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def root(request, format=None, **kwargs): """Welcome to the V2 Open Science Framework API. With this API you can access users, projects, components, logs, and files from the [Open Science Framework](https://osf.io/). The Open Science Framework (OSF) is a free, open-source service maintained by the [Center for Open Science](http://cos.io/). The OSF serves as a repository and archive for study designs, materials, data, manuscripts, or anything else associated with your research during the research process. Every project and file on the OSF has a permanent unique identifier, and every registration (a permanent, time-stamped version of your projects and files) can be assigned a DOI/ARK. You can use the OSF to measure your impact by monitoring the traffic to projects and files you make public. With the OSF you have full control of what parts of your research are public and what remains private. Beta notice: This API is currently a beta service. You are encouraged to use the API and will receive support when doing so, however, while the API remains in beta status, it may change without notice as a result of product updates. The temporary beta status of the API will remain in place while it matures. In a future release, the beta status will be removed, at which point we will provide details on how long we will support the API V2 and under what circumstances it might change. #General API Usage The OSF API generally conforms to the [JSON-API v1.0 spec](http://jsonapi.org/format/1.0/). Where exceptions exist, they will be noted. Each endpoint will have its own documentation, but there are some general principles. Assume undocumented routes/features/fields are unstable. ##Requests ###Canonical URLs All canonical URLs have trailing slashes. A request to an endpoint without a trailing slash will result in a 301 redirect to the canonical URL. There are some exceptions when working with the Files API, so if a URL in a response does not have a slash, do not append one. ###Plurals Endpoints are always pluralized. `/users/`, not `/user/`, `/nodes/`, not `/node/`. ###Common Actions Every endpoint in the OSF API responds to `GET`, `HEAD`, and `OPTION` requests. You must have adequate permissions to interact with the endpoint. Unauthorized use will result in 401 Unauthorized or 403 Forbidden responses. Use `HEAD` to probe an endpoint and make sure your headers are well-formed. `GET` will return a representation of the entity or entity collection referenced by the endpoint. An `OPTIONS` request will return a JSON object that describes the endpoint, including the name, a description, the acceptable request formats, the allowed response formats, and any actions available via the endpoint. ###Versioning Versioning can be specified in three different ways: 1. URL Path Versioning, e.g. `/v2/` or `/v3/` + A version specified via the URL path is a **required** part of the URL. + Only a major version can be specified via the URL path, i.e. `/v2.0.6/` is invalid, additionally, paths such as `/v2.0/` are invalid. + If the default version of the API is within the major version specified in the URL path, the default version will be applied (i.e. if the default version is `2.3` and the URL path is `/v2/`, then version returned will be `2.3`). + If the default version of the API is not within the major version specified in the URL path, the URL path version will be applied (i.e. if the default version is `3.0` and the URL path is `/v2/`, then the version returned will be `2.0`) 2. Query Parameter Versioning, e.g. `/v2/nodes/?version=2.1.6` + Pinning to a specific version via a query parameter is **optional**. + A specific version (major, minor, or patch) for a single request can be specified via the `version` query parameter, as long as it is an allowed version. + If the version specified in the query parameter does not fall within the same major version specified in the URL path, i.e `/v2/nodes/?version=3.1.4` a `409 Conflict` response will be returned. 3. Header Versioning, e.g. `Accept-Header=application/vnd.api+json;version=3.0.1` + Pinning to a specific version via request header is **optional**. + A specific version (major, minor, or patch) for a single request can be specified via the `Accept Header` of the request, as long as it is an allowed version. + If the version specified in the header does not fall within the same major version specified in the URL path a `409 Conflict` response will be returned. + If both a header version and query parameter version are specified, the versions must match exactly or a `409 Conflict` response will be returned (i.e. one does not take precedence over the other). ###Filtering Entity collections can be filtered by adding a query parameter in the form: filter[<fieldname>]=<matching information> String queries are filtered using substring matching. For example, if you were trying to find [Lise Meitner](http://en.wikipedia.org/wiki/Lise_Meitner): /users/?filter[full_name]=meitn You can filter on multiple fields, or the same field in different ways, by &-ing the query parameters together. /users/?filter[full_name]=lise&filter[family_name]=mei Boolean fields should be queried with `true` or `false`. /nodes/?filter[registered]=true You can request multiple resources by filtering on id and placing comma-separated values in your query parameter. /nodes/?filter[id]=aegu6,me23a You can filter with case-sensitivity or case-insensitivity by using `contains` and `icontains`, respectively. /nodes/?filter[tags][icontains]=help ###Embedding All related resources that appear in the `relationships` attribute are embeddable, meaning that by adding a query parameter like: /nodes/?embed=contributors it is possible to fetch a Node and its contributors in a single request. The embedded results will have the following structure: {relationship_name}: {full_embedded_response} Where `full_embedded_response` means the full API response resulting from a GET request to the `href` link of the corresponding related resource. This means if there are no errors in processing the embedded request the response will have the format: data: {response} And if there are errors processing the embedded request the response will have the format: errors: {errors} Multiple embeds can be achieved with multiple query parameters separated by "&". /nodes/?embed=contributors&embed=comments Some endpoints are automatically embedded. ###Pagination All entity collection endpoints respond to the `page` query parameter behavior as described in the [JSON-API pagination spec](http://jsonapi.org/format/1.0/#crud). However, pagination links are provided in the response, and you are encouraged to use that rather than adding query parameters by hand. ###Formatting POST/PUT/PATCH request bodies The OSF API follows the JSON-API spec for [create and update requests](http://jsonapi.org/format/1.0/#crud). This means all request bodies must be wrapped with some metadata. Each request body must be an object with a `data` key containing at least a `type` member. The value of the `type` member must agree with the `type` of the entities represented by the endpoint. If not, a 409 Conflict will be returned. The request should also contain an `attributes` member with an object containing the key-value pairs to be created/updated. PUT/PATCH requests must also have an `id` key that matches the id part of the endpoint. If the `id` key does not match the id path part, a 409 Conflict error will be returned. ####Example 1: Creating a Node via POST POST /v2/nodes/ { "data": { "type": "nodes", "attributes": { "title" : "A Phylogenetic Tree of Famous Internet Cats", "category" : "project", "description" : "How closely related are Grumpy Cat and C.H. Cheezburger? Is memefulness inheritable?" } } } ####Example 2: Updating a User via PUT PUT /v2/users/me/ { "data": { "id": "3rqxc", "type": "users", "attributes": { "full_name" : "Henrietta Swan Leavitt", "given_name" : "Henrietta", "middle_names" : "Swan", "family_name" : "Leavitt" } } } **NB:** If you PUT/PATCH to the `/users/me/` endpoint, you must still provide your full user id in the `id` field of the request. We do not support using the `me` alias in request bodies at this time. ###PUT vs. PATCH For most endpoints that support updates via PUT requests, we also allow PATCH updates. The only difference is that PUT requests require all mandatory attributes to be set, even if their value is unchanged. PATCH requests may omit mandatory attributes, whose value will be unchanged. ###Attribute Validation Endpoints that allow creation or modification of entities generally limit updates to certain attributes of the entity. If you attempt to set an attribute that does not permit updates (such as a `date_created` timestamp), the API will silently ignore that attribute. This will not affect the response from the API: if the request would have succeeded without the updated attribute, it will still report as successful. Likewise, if the request would have failed without the attribute update, the API will still report a failure. Typoed or non-existent attributes will behave the same as non-updatable attributes and be silently ignored. If a request is not working the way you expect, make sure to double check your spelling. ##Responses ###Entities An entity is a single resource that has been retrieved from the API, usually from an endpoint with the entity's id as the final path part. A successful response from an entity request will be a JSON object with a top level `data` key pointing to a sub-object with the following members: + `id` The identifier for the entity. This MUST be included with [PUT and PATCH requests](#formatting-postputpatch-request-bodies). + `type` The type identifier of this entity. This MUST be included with [all create/update requests](#formatting-postputpatch-request-bodies). + `attributes` The properties of the entity. Names, descriptions, etc. + `relationships` Relationships are urls to other entities or entity collections that have a relationship to the entity. For example, the node entity provides a `contributors` relationship that points to the endpoint to retrieve all contributors to that node. It is recommended to use these links rather than to id-filter general entity collection endpoints. They'll be faster, easier, and less error-prone. Generally a relationship will have the following structure: {relationship_name}: { "links": { "related": { "href": {url_to_related_entity_or_entity_collection}, "meta": {} } } } If there are no related entities, `href` will be null. + `embeds` Please see `Embedding` documentation under `Requests`. + `links` Links are urls to alternative representations of the entity or actions that may be performed on the entity. Most entities will provide a `self` link that is the canonical endpoint for the entity where update and delete requests should be sent. In-depth documentation of actions is available by navigating to the `self` link in the Browsable API. Most entities will also provide an `html` link that directs to the entity's page on the [OSF](http://osf.io/). ###Entity Collections Entity collection endpoints return a list of entities and an additional data structure with pagination links, such as "next", "prev", "first", and "last". The OSF API limits all entity collection responses to a maximum of 10 entities. The response object has two keys: + `data` `data` is an array of entities that match the query. Each entity in the array is the same representation that is returned from that entity's `self` link, meaning that refetching the entity is unnecessary. + `links` `links` contains pagination information, including links to the previous, next, first, and last pages of results. The meta key contains the total number of entities available, as well as the current number of results displayed per page. If there are only enough results to fill one page, the `first`, `last`, `prev`, and `next` values will be null. ###Errors When a request fails for whatever reason, the OSF API will return an appropriate HTTP error code and include a descriptive error in the body of the response. The response body will be an object with a key, `errors`, pointing to an array of error objects. Generally, these error objects will consist of a `detail` key with a detailed error message and a `source` object that may contain a field `pointer` that is a [JSON Pointer](https://tools.ietf.org/html/rfc6901) to the error-causing attribute. The `error` objects may include additional information in accordance with the [JSON-API error spec](http://jsonapi.org/format/1.0/#error-objects). ####Example: Error response from an incorrect create node request { "errors": [ { "source": { "pointer": "/data/attributes/category" }, "detail": "This field is required." }, { "source": { "pointer": "/data/type" }, "detail": "This field may not be null." }, { "source": { "pointer": "/data/attributes/title" }, "detail": "This field is required." } ] } ##OSF Enum Fields Some entities in the OSF API have fields that only take a restricted set of values. Those fields are listed here for reference. Fuller descriptions are available on the relevant entity pages. ###OSF Node Categories value description ========================================== project Project hypothesis Hypothesis methods and measures Methods and Measures procedure Procedure instrumentation Instrumentation data Data analysis Analysis communication Communication other Other ###OSF Node Permission keys value description ========================================== read Read-only access write Write access (make changes, cannot delete) admin Admin access (full write, create, delete, contributor add) ###Storage Providers Valid storage providers are: value description ========================================== bitbucket Bitbucket box Box.com dataverse Dataverse dropbox Dropbox figshare figshare github GitHub googledrive Google Drive osfstorage OSF Storage s3 Amazon S3 """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'metaschemas': utils.absolute_reverse('metaschemas:metaschema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), } } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def root(request, format=None, **kwargs): """Welcome to the V2 Open Science Framework API. With this API you can access users, projects, components, logs, and files from the [Open Science Framework](https://osf.io/). The Open Science Framework (OSF) is a free, open-source service maintained by the [Center for Open Science](http://cos.io/). The OSF serves as a repository and archive for study designs, materials, data, manuscripts, or anything else associated with your research during the research process. Every project and file on the OSF has a permanent unique identifier, and every registration (a permanent, time-stamped version of your projects and files) can be assigned a DOI/ARK. You can use the OSF to measure your impact by monitoring the traffic to projects and files you make public. With the OSF you have full control of what parts of your research are public and what remains private. Beta notice: This API is currently a beta service. You are encouraged to use the API and will receive support when doing so, however, while the API remains in beta status, it may change without notice as a result of product updates. The temporary beta status of the API will remain in place while it matures. In a future release, the beta status will be removed, at which point we will provide details on how long we will support the API V2 and under what circumstances it might change. #General API Usage The OSF API generally conforms to the [JSON-API v1.0 spec](http://jsonapi.org/format/1.0/). Where exceptions exist, they will be noted. Each endpoint will have its own documentation, but there are some general principles. Assume undocumented routes/features/fields are unstable. ##Requests ###Canonical URLs All canonical URLs have trailing slashes. A request to an endpoint without a trailing slash will result in a 301 redirect to the canonical URL. There are some exceptions when working with the Files API, so if a URL in a response does not have a slash, do not append one. ###Plurals Endpoints are always pluralized. `/users/`, not `/user/`, `/nodes/`, not `/node/`. ###Common Actions Every endpoint in the OSF API responds to `GET`, `HEAD`, and `OPTION` requests. You must have adequate permissions to interact with the endpoint. Unauthorized use will result in 401 Unauthorized or 403 Forbidden responses. Use `HEAD` to probe an endpoint and make sure your headers are well-formed. `GET` will return a representation of the entity or entity collection referenced by the endpoint. An `OPTIONS` request will return a JSON object that describes the endpoint, including the name, a description, the acceptable request formats, the allowed response formats, and any actions available via the endpoint. ###Versioning Versioning can be specified in three different ways: 1. URL Path Versioning, e.g. `/v2/` or `/v3/` + A version specified via the URL path is a **required** part of the URL. + Only a major version can be specified via the URL path, i.e. `/v2.0.6/` is invalid, additionally, paths such as `/v2.0/` are invalid. + If the default version of the API is within the major version specified in the URL path, the default version will be applied (i.e. if the default version is `2.3` and the URL path is `/v2/`, then version returned will be `2.3`). + If the default version of the API is not within the major version specified in the URL path, the URL path version will be applied (i.e. if the default version is `3.0` and the URL path is `/v2/`, then the version returned will be `2.0`) 2. Query Parameter Versioning, e.g. `/v2/nodes/?version=2.1.6` + Pinning to a specific version via a query parameter is **optional**. + A specific version (major, minor, or patch) for a single request can be specified via the `version` query parameter, as long as it is an allowed version. + If the version specified in the query parameter does not fall within the same major version specified in the URL path, i.e `/v2/nodes/?version=3.1.4` a `409 Conflict` response will be returned. 3. Header Versioning, e.g. `Accept-Header=application/vnd.api+json;version=3.0.1` + Pinning to a specific version via request header is **optional**. + A specific version (major, minor, or patch) for a single request can be specified via the `Accept Header` of the request, as long as it is an allowed version. + If the version specified in the header does not fall within the same major version specified in the URL path a `409 Conflict` response will be returned. + If both a header version and query parameter version are specified, the versions must match exactly or a `409 Conflict` response will be returned (i.e. one does not take precedence over the other). ###Filtering Entity collections can be filtered by adding a query parameter in the form: filter[<fieldname>]=<matching information> String queries are filtered using substring matching. For example, if you were trying to find [Lise Meitner](http://en.wikipedia.org/wiki/Lise_Meitner): /users/?filter[full_name]=meitn You can filter on multiple fields, or the same field in different ways, by &-ing the query parameters together. /users/?filter[full_name]=lise&filter[family_name]=mei Boolean fields should be queried with `true` or `false`. /nodes/?filter[registered]=true You can request multiple resources by filtering on id and placing comma-separated values in your query parameter. /nodes/?filter[id]=aegu6,me23a You can filter with case-sensitivity or case-insensitivity by using `contains` and `icontains`, respectively. /nodes/?filter[tags][icontains]=help ###Embedding All related resources that appear in the `relationships` attribute are embeddable, meaning that by adding a query parameter like: /nodes/?embed=contributors it is possible to fetch a Node and its contributors in a single request. The embedded results will have the following structure: {relationship_name}: {full_embedded_response} Where `full_embedded_response` means the full API response resulting from a GET request to the `href` link of the corresponding related resource. This means if there are no errors in processing the embedded request the response will have the format: data: {response} And if there are errors processing the embedded request the response will have the format: errors: {errors} Multiple embeds can be achieved with multiple query parameters separated by "&". /nodes/?embed=contributors&embed=comments Some endpoints are automatically embedded. ###Pagination All entity collection endpoints respond to the `page` query parameter behavior as described in the [JSON-API pagination spec](http://jsonapi.org/format/1.0/#crud). However, pagination links are provided in the response, and you are encouraged to use that rather than adding query parameters by hand. ###Formatting POST/PUT/PATCH request bodies The OSF API follows the JSON-API spec for [create and update requests](http://jsonapi.org/format/1.0/#crud). This means all request bodies must be wrapped with some metadata. Each request body must be an object with a `data` key containing at least a `type` member. The value of the `type` member must agree with the `type` of the entities represented by the endpoint. If not, a 409 Conflict will be returned. The request should also contain an `attributes` member with an object containing the key-value pairs to be created/updated. PUT/PATCH requests must also have an `id` key that matches the id part of the endpoint. If the `id` key does not match the id path part, a 409 Conflict error will be returned. ####Example 1: Creating a Node via POST POST /v2/nodes/ { "data": { "type": "nodes", "attributes": { "title" : "A Phylogenetic Tree of Famous Internet Cats", "category" : "project", "description" : "How closely related are Grumpy Cat and C.H. Cheezburger? Is memefulness inheritable?" } } } ####Example 2: Updating a User via PUT PUT /v2/users/me/ { "data": { "id": "3rqxc", "type": "users", "attributes": { "full_name" : "Henrietta Swan Leavitt", "given_name" : "Henrietta", "middle_names" : "Swan", "family_name" : "Leavitt" } } } **NB:** If you PUT/PATCH to the `/users/me/` endpoint, you must still provide your full user id in the `id` field of the request. We do not support using the `me` alias in request bodies at this time. ###PUT vs. PATCH For most endpoints that support updates via PUT requests, we also allow PATCH updates. The only difference is that PUT requests require all mandatory attributes to be set, even if their value is unchanged. PATCH requests may omit mandatory attributes, whose value will be unchanged. ###Attribute Validation Endpoints that allow creation or modification of entities generally limit updates to certain attributes of the entity. If you attempt to set an attribute that does not permit updates (such as a `created` timestamp), the API will silently ignore that attribute. This will not affect the response from the API: if the request would have succeeded without the updated attribute, it will still report as successful. Likewise, if the request would have failed without the attribute update, the API will still report a failure. Typoed or non-existent attributes will behave the same as non-updatable attributes and be silently ignored. If a request is not working the way you expect, make sure to double check your spelling. ##Responses ###Entities An entity is a single resource that has been retrieved from the API, usually from an endpoint with the entity's id as the final path part. A successful response from an entity request will be a JSON object with a top level `data` key pointing to a sub-object with the following members: + `id` The identifier for the entity. This MUST be included with [PUT and PATCH requests](#formatting-postputpatch-request-bodies). + `type` The type identifier of this entity. This MUST be included with [all create/update requests](#formatting-postputpatch-request-bodies). + `attributes` The properties of the entity. Names, descriptions, etc. + `relationships` Relationships are urls to other entities or entity collections that have a relationship to the entity. For example, the node entity provides a `contributors` relationship that points to the endpoint to retrieve all contributors to that node. It is recommended to use these links rather than to id-filter general entity collection endpoints. They'll be faster, easier, and less error-prone. Generally a relationship will have the following structure: {relationship_name}: { "links": { "related": { "href": {url_to_related_entity_or_entity_collection}, "meta": {} } } } If there are no related entities, `href` will be null. + `embeds` Please see `Embedding` documentation under `Requests`. + `links` Links are urls to alternative representations of the entity or actions that may be performed on the entity. Most entities will provide a `self` link that is the canonical endpoint for the entity where update and delete requests should be sent. In-depth documentation of actions is available by navigating to the `self` link in the Browsable API. Most entities will also provide an `html` link that directs to the entity's page on the [OSF](http://osf.io/). ###Entity Collections Entity collection endpoints return a list of entities and an additional data structure with pagination links, such as "next", "prev", "first", and "last". The OSF API limits all entity collection responses to a maximum of 10 entities. The response object has two keys: + `data` `data` is an array of entities that match the query. Each entity in the array is the same representation that is returned from that entity's `self` link, meaning that refetching the entity is unnecessary. + `links` `links` contains pagination information, including links to the previous, next, first, and last pages of results. The meta key contains the total number of entities available, as well as the current number of results displayed per page. If there are only enough results to fill one page, the `first`, `last`, `prev`, and `next` values will be null. ###Errors When a request fails for whatever reason, the OSF API will return an appropriate HTTP error code and include a descriptive error in the body of the response. The response body will be an object with a key, `errors`, pointing to an array of error objects. Generally, these error objects will consist of a `detail` key with a detailed error message and a `source` object that may contain a field `pointer` that is a [JSON Pointer](https://tools.ietf.org/html/rfc6901) to the error-causing attribute. The `error` objects may include additional information in accordance with the [JSON-API error spec](http://jsonapi.org/format/1.0/#error-objects). ####Example: Error response from an incorrect create node request { "errors": [ { "source": { "pointer": "/data/attributes/category" }, "detail": "This field is required." }, { "source": { "pointer": "/data/type" }, "detail": "This field may not be null." }, { "source": { "pointer": "/data/attributes/title" }, "detail": "This field is required." } ] } ##OSF Enum Fields Some entities in the OSF API have fields that only take a restricted set of values. Those fields are listed here for reference. Fuller descriptions are available on the relevant entity pages. ###OSF Node Categories value description ========================================== project Project hypothesis Hypothesis methods and measures Methods and Measures procedure Procedure instrumentation Instrumentation data Data analysis Analysis communication Communication other Other ###OSF Node Permission keys value description ========================================== read Read-only access write Write access (make changes, cannot delete) admin Admin access (full write, create, delete, contributor add) ###Storage Providers Valid storage providers are: value description ========================================== bitbucket Bitbucket box Box.com dataverse Dataverse dropbox Dropbox figshare figshare github GitHub gitlab GitLab googledrive Google Drive onedrive Microsoft OneDrive osfstorage OSF Storage s3 Amazon S3 """ if request.user and not request.user.is_anonymous: user = request.user current_user = UserSerializer(user, context={'request': request}).data else: current_user = None kwargs = request.parser_context['kwargs'] return_val = { 'meta': { 'message': 'Welcome to the OSF API.', 'version': request.version, 'current_user': current_user, }, 'links': { 'nodes': utils.absolute_reverse('nodes:node-list', kwargs=kwargs), 'users': utils.absolute_reverse('users:user-list', kwargs=kwargs), 'collections': utils.absolute_reverse('collections:collection-list', kwargs=kwargs), 'registrations': utils.absolute_reverse('registrations:registration-list', kwargs=kwargs), 'institutions': utils.absolute_reverse('institutions:institution-list', kwargs=kwargs), 'licenses': utils.absolute_reverse('licenses:license-list', kwargs=kwargs), 'metaschemas': utils.absolute_reverse('metaschemas:metaschema-list', kwargs=kwargs), 'addons': utils.absolute_reverse('addons:addon-list', kwargs=kwargs), } } if utils.has_admin_scope(request): return_val['meta']['admin'] = True return Response(return_val)
def has_permission(self, request, view): if has_admin_scope(request): return True raise exceptions.NotFound()