class VocabulariesResourceConfig(RecordResourceConfig): """Vocabulary resource configuration.""" blueprint_name = "vocabularies" url_prefix = "/vocabularies" routes = { "list": "/<type>", "item": "/<type>/<pid_value>", } request_view_args = { "pid_value": ma.fields.Str(), "type": ma.fields.Str(required=True), } request_args = VocabularySearchRequestArgsSchema response_handlers = { "application/json": ResponseHandler(JSONSerializer(), headers=etag_headers), "application/vnd.inveniordm.v1+json": ResponseHandler( MarshmallowJSONSerializer( schema_cls=VocabularyL10NItemSchema, many_schema_cls=VocabularyL10NListSchema, ), headers=etag_headers, ), }
class TestConfig(ResourceConfig): blueprint_name = "test" response_handlers = { "application/json": ResponseHandler( MarshmallowJSONSerializer(TestSchema), headers=my_headers ), "application/vnd.test+json": ResponseHandler( MarshmallowJSONSerializer(TestSchema), ), }
class RecordResourceConfig(ResourceConfig): """Record resource config.""" # Blueprint configuration blueprint_name = None url_prefix = "/records" routes = { "list": "", "item": "/<pid_value>", } # Request parsing request_read_args = {} request_view_args = {"pid_value": ma.fields.Str()} request_search_args = SearchRequestArgsSchema request_headers = {"if_match": ma.fields.Int()} request_body_parsers = { "application/json": RequestBodyParser(JSONDeserializer()) } default_content_type = "application/json" # Response handling response_handlers = { "application/json": ResponseHandler(JSONSerializer(), headers=etag_headers) } default_accept_mimetype = "application/json"
class TodoResourceConfig(ResourceConfig): blueprint_name = "todo" url_prefix = "/todos" response_handlers = { "application/json": ResponseHandler(JSONSerializer()), }
def with_iiif_content_negotiation(serializer): """Always response as JSON LD regardless of the request type.""" return with_content_negotiation( response_handlers={ "application/ld+json": ResponseHandler(serializer()), }, default_accept_mimetype="application/ld+json", )
class RDMPIDProviderResourceConfig(RecordResourceConfig): """PID provider resource configuration.""" blueprint_name = "reserve" url_prefix = "/records/<pid_value>/draft/pids" routes = {"item": "/<providers>"} request_view_args = { "provider": ma.fields.Str(), "pid_value": ma.fields.Str(), } response_handlers = {"application/json": ResponseHandler(JSONSerializer())} error_handlers = record_links_error_handlers
class Marc21ParentRecordLinksResourceConfig(RecordResourceConfig): """User records resource configuration.""" blueprint_name = "marc21_access" url_prefix = f"{url_prefix}/<pid_value>/access" routes = { "search": "", "list": "/links", "item": "/links/<link_id>", } links_config = {} request_view_args = { "pid_value": ma.fields.Str(), "link_id": ma.fields.Str() } response_handlers = {"application/json": ResponseHandler(JSONSerializer())}
class IIIFResourceConfig(ResourceConfig): """IIIF resource configuration.""" blueprint_name = "iiif" url_prefix = "/iiif" routes = { "manifest": "/<uuid>/manifest", "sequence": "/<uuid>/sequence/default", "canvas": "/<uuid>/canvas/<file_name>", "image_base": "/<uuid>", "image_info": "/<uuid>/info.json", "image_api": "/<uuid>/<region>/<size>/<rotation>/<quality>.<image_format>", } request_view_args = { "uuid": ma.fields.Str(), "file_name": ma.fields.Str(), "region": ma.fields.Str(), "size": ma.fields.Str(), "rotation": ma.fields.Str(), "quality": ma.fields.Str(), "image_format": ma.fields.Str(), } response_handler = {"application/json": ResponseHandler(JSONSerializer())} supported_formats = { "gif": "image/gif", "jp2": "image/jp2", "jpeg": "image/jpeg", "jpg": "image/jpeg", "pdf": "application/pdf", "png": "image/png", "tif": "image/tiff", "tiff": "image/tiff", }
DataCite43XMLSerializer, StringCitationSerializer, UIJSONSerializer def csl_url_args_retriever(): """Returns the style and locale passed as URL args for CSL export.""" style = resource_requestctx.args.get("style") locale = resource_requestctx.args.get("locale") return style, locale # # Response handlers # record_serializers = { "application/json": ResponseHandler(JSONSerializer()), "application/vnd.inveniordm.v1+json": ResponseHandler(UIJSONSerializer()), "application/vnd.citationstyles.csl+json": ResponseHandler(CSLJSONSerializer()), "application/vnd.datacite.datacite+json": ResponseHandler(DataCite43JSONSerializer()), "application/vnd.datacite.datacite+xml": ResponseHandler(DataCite43XMLSerializer()), "text/x-bibliography": ResponseHandler( StringCitationSerializer(url_args_retriever=csl_url_args_retriever), headers={"content-type": "text/plain"}), }
"""Resources configuration.""" import marshmallow as ma from flask_resources import HTTPJSONException, JSONSerializer, \ ResponseHandler, create_error_handler from invenio_drafts_resources.resources import RecordResourceConfig from invenio_records_resources.resources.files import FileResourceConfig from .serializers import CSLJSONSerializer, UIJSONSerializer # # Response handlers # record_serializers = { "application/json": ResponseHandler(JSONSerializer()), "application/vnd.inveniordm.v1+json": ResponseHandler(UIJSONSerializer()), "application/vnd.citationstyles.csl+json": ResponseHandler(CSLJSONSerializer()), } # # Records and record versions # class RDMRecordResourceConfig(RecordResourceConfig): """Record resource configuration.""" blueprint_name = "records" url_prefix = "/records"
"""Resources configuration.""" import marshmallow as ma from flask_resources import HTTPJSONException, JSONSerializer, \ ResponseHandler, create_error_handler from invenio_drafts_resources.resources import RecordResourceConfig from invenio_records_resources.resources.files import FileResourceConfig from .serializers import UIJSONSerializer # # Response handlers # record_serializers = { "application/json": ResponseHandler(JSONSerializer()), "application/vnd.inveniordm.v1+json": ResponseHandler(UIJSONSerializer()) } # # Records and record versions # class RDMRecordResourceConfig(RecordResourceConfig): """Record resource configuration.""" blueprint_name = "records" url_prefix = "/records" routes = RecordResourceConfig.routes routes["item-files-import"] = "/<pid_value>/draft/actions/files-import"
class RecordResource(RecordResourceBase): """Draft-aware RecordResource.""" def create_blueprint(self, **options): """Create the blueprint.""" # We avoid passing url_prefix to the blueprint because we need to # install URLs under both /records and /user/records. Instead we # add the prefix manually to each route (which is anyway what Flask # does in the end) options["url_prefix"] = "" return super().create_blueprint(**options) def create_url_rules(self): """Create the URL rules for the record resource.""" routes = self.config.routes def p(route): """Prefix a route with the URL prefix.""" return f"{self.config.url_prefix}{route}" def s(route): """Suffix a route with the URL prefix.""" return f"{route}{self.config.url_prefix}" rules = [ route("GET", p(routes["list"]), self.search), route("POST", p(routes["list"]), self.create), route("GET", p(routes["item"]), self.read), route("PUT", p(routes["item"]), self.update), route("DELETE", p(routes["item"]), self.delete), route("GET", p(routes["item-versions"]), self.search_versions), route("POST", p(routes["item-versions"]), self.new_version), route("GET", p(routes["item-latest"]), self.read_latest), route("GET", p(routes["item-draft"]), self.read_draft), route("POST", p(routes["item-draft"]), self.edit), route("PUT", p(routes["item-draft"]), self.update_draft), route("DELETE", p(routes["item-draft"]), self.delete_draft), route("POST", p(routes["item-publish"]), self.publish), route("GET", s(routes["user-prefix"]), self.search_user_records), ] if self.service.draft_files: rules.append(route( "POST", p(routes["item-files-import"]), self.import_files, apply_decorators=False )) return rules @request_search_args @request_view_args @response_handler(many=True) def search_user_records(self): """Perform a search over the record's versions. GET /user/records """ hits = self.service.search_drafts( identity=g.identity, params=resource_requestctx.args, es_preference=es_preference(), ) return hits.to_dict(), 200 @request_search_args @request_view_args @response_handler(many=True) def search_versions(self): """Perform a search over the record's versions. GET /records/:pid_value/versions """ hits = self.service.search_versions( g.identity, resource_requestctx.view_args["pid_value"], params=resource_requestctx.args, es_preference=es_preference() ) return hits.to_dict(), 200 @request_view_args @response_handler() def new_version(self): """Create a new version. POST /records/:pid_value/versions """ item = self.service.new_version( g.identity, resource_requestctx.view_args["pid_value"], ) return item.to_dict(), 201 @request_view_args @response_handler() def edit(self): """Edit a record. POST /records/:pid_value/draft """ item = self.service.edit( g.identity, resource_requestctx.view_args["pid_value"], ) return item.to_dict(), 201 @request_view_args @response_handler() def publish(self): """Publish the draft.""" item = self.service.publish( g.identity, resource_requestctx.view_args["pid_value"], ) return item.to_dict(), 202 @request_view_args @with_content_negotiation( response_handlers={ 'application/json': ResponseHandler(JSONSerializer()) }, default_accept_mimetype='application/json', ) @response_handler(many=True) def import_files(self): """Import files from previous record version.""" files = self.service.import_files( g.identity, resource_requestctx.view_args["pid_value"], ) return files.to_dict(), 201 @request_view_args def read_latest(self): """Redirect to latest record. GET /records/:pid_value/versions/latest """ item = self.service.read_latest( g.identity, resource_requestctx.view_args["pid_value"], ) raise RedirectException(item["links"]["self"]) @request_read_args @request_view_args @response_handler() def read_draft(self): """Edit a draft. GET /records/:pid_value/draft """ item = self.service.read_draft( g.identity, resource_requestctx.view_args["pid_value"], ) return item.to_dict(), 200 @request_headers @request_view_args @request_data @response_handler() def update_draft(self): """Update a draft. PUT /records/:pid_value/draft """ item = self.service.update_draft( g.identity, resource_requestctx.view_args["pid_value"], resource_requestctx.data or {}, revision_id=resource_requestctx.headers.get("if_match"), ) return item.to_dict(), 200 @request_headers @request_view_args def delete_draft(self): """Delete a draft. DELETE /records/:pid_value/draft """ self.service.delete_draft( g.identity, resource_requestctx.view_args["pid_value"], revision_id=resource_requestctx.headers.get("if_match"), ) return "", 204
import marshmallow as ma from flask_resources import ( JSONDeserializer, JSONSerializer, RequestBodyParser, ResponseHandler, ) from flask_resources.serializers import JSONSerializer from invenio_drafts_resources.resources import RecordResourceConfig from invenio_records_resources.resources.files import FileResourceConfig from invenio_records_resources.resources.records.args import SearchRequestArgsSchema from .serializers.ui import UIJSONSerializer record_serializer = { "application/json": ResponseHandler(UIJSONSerializer()), "application/vnd.inveniomarc21.v1+json": ResponseHandler(UIJSONSerializer()), } url_prefix = "/marc21" record_ui_routes = { "search": f"{url_prefix}", "list": f"{url_prefix}/list", "item": f"{url_prefix}/<pid_value>", "item-versions": f"{url_prefix}/<pid_value>/versions", "item-latest": f"{url_prefix}/<pid_value>/versions/latest", "item-draft": f"{url_prefix}/<pid_value>/draft", "item-publish": f"{url_prefix}/<pid_value>/draft/actions/publish", "item-files-import":