Submission¶
Models for the HEPData Submission Workflow. |
|
hepdata.modules.submission.admin¶
- class hepdata.modules.submission.admin.HEPSubmissionAdminView(model, session, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶
HEPSubmissionAdminView view.
- can_view_details = True¶
Setting this to true will enable the details view. This is recommended when there are too many columns to display in the list_view.
- can_delete = False¶
Is model deletion allowed
- column_list = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
Collection of the model field names for the list view. If set to None, will get them from the model.
For example:
class MyModelView(BaseModelView): column_list = ('name', 'last_name', 'email')
(Added in 1.4.0) SQLAlchemy model attributes can be used instead of strings:
class MyModelView(BaseModelView): column_list = ('name', User.last_name)
- When using SQLAlchemy models, you can reference related columns like this::
- class MyModelView(BaseModelView):
column_list = (‘<relationship>.<related column name>’,)
- form_columns = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
Collection of the model field names for the form. If set to None will get them from the model.
Example:
class MyModelView(BaseModelView): form_columns = ('name', 'email')
(Added in 1.4.0) SQLAlchemy model attributes can be used instead of strings:
class MyModelView(BaseModelView): form_columns = ('name', User.last_name)
SQLA Note: Model attributes must be on the same model as your ModelView or you will need to use inline_models.
- column_searchable_list = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
Collection of the searchable columns.
Example:
class MyModelView(ModelView): column_searchable_list = ('name', 'email')
You can also pass columns:
class MyModelView(ModelView): column_searchable_list = (User.name, User.email)
The following search rules apply:
If you enter
ZZZin the UI search field, it will generateILIKE '%ZZZ%'statement against searchable columns.If you enter multiple words, each word will be searched separately, but only rows that contain all words will be displayed. For example, searching for
abc defwill find all rows that containabcanddefin one or more columns.If you prefix your search term with
^, it will find all rows that start with^. So, if you entered^ZZZthenILIKE 'ZZZ%'will be used.If you prefix your search term with
=, it will perform an exact match. For example, if you entered=ZZZ, the statementILIKE 'ZZZ'will be used.
- column_filters = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
Collection of the column filters.
Can contain either field names or instances of
flask_admin.contrib.sqla.filters.BaseSQLAFilterclasses.Filters will be grouped by name when displayed in the drop-down.
For example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
or:
from flask_admin.contrib.sqla.filters import BooleanEqualFilter class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(column=User.name, name='Name'),)
or:
from flask_admin.contrib.sqla.filters import BaseSQLAFilter class FilterLastNameBrown(BaseSQLAFilter): def apply(self, query, value, alias=None): if value == '1': return query.filter(self.column == "Brown") else: return query.filter(self.column != "Brown") def operation(self): return 'is Brown' class MyModelView(BaseModelView): column_filters = [ FilterLastNameBrown( User.last_name, 'Last Name', options=(('1', 'Yes'), ('0', 'No')) ) ]
- column_details_list = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
Collection of the field names included in the details view. If set to None, will get them from the model.
- columns_sortable_list = ('id', 'publication_recid', 'overall_status', 'coordinator', 'doi', 'version')¶
- column_labels = {'_displayname': 'Display Name'}¶
Dictionary where key is column name and value is string to display.
For example:
class MyModelView(BaseModelView): column_labels = dict(name='Name', last_name='Last Name')
- action_view()¶
Mass-model action view.
- ajax_lookup()¶
- ajax_update()¶
Edits a single column of a record in list view.
- create_view()¶
Create model view
- delete_view()¶
Delete model view. Only POST method is allowed.
- details_view()¶
Details model view
- edit_view()¶
Edit model view
- export(export_type)¶
- index_view()¶
List view
- class hepdata.modules.submission.admin.DataResourceAdminView(model, session, name=None, category=None, endpoint=None, url=None, static_folder=None, menu_class_name=None, menu_icon_type=None, menu_icon_value=None)[source]¶
- can_view_details = True¶
Setting this to true will enable the details view. This is recommended when there are too many columns to display in the list_view.
- can_delete = True¶
Is model deletion allowed
- column_list = ('id', 'file_location', 'file_type', 'created')¶
Collection of the model field names for the list view. If set to None, will get them from the model.
For example:
class MyModelView(BaseModelView): column_list = ('name', 'last_name', 'email')
(Added in 1.4.0) SQLAlchemy model attributes can be used instead of strings:
class MyModelView(BaseModelView): column_list = ('name', User.last_name)
- When using SQLAlchemy models, you can reference related columns like this::
- class MyModelView(BaseModelView):
column_list = (‘<relationship>.<related column name>’,)
- form_columns = ('id', 'file_location', 'file_type', 'created')¶
Collection of the model field names for the form. If set to None will get them from the model.
Example:
class MyModelView(BaseModelView): form_columns = ('name', 'email')
(Added in 1.4.0) SQLAlchemy model attributes can be used instead of strings:
class MyModelView(BaseModelView): form_columns = ('name', User.last_name)
SQLA Note: Model attributes must be on the same model as your ModelView or you will need to use inline_models.
- column_searchable_list = ('id', 'file_location', 'file_type', 'created')¶
Collection of the searchable columns.
Example:
class MyModelView(ModelView): column_searchable_list = ('name', 'email')
You can also pass columns:
class MyModelView(ModelView): column_searchable_list = (User.name, User.email)
The following search rules apply:
If you enter
ZZZin the UI search field, it will generateILIKE '%ZZZ%'statement against searchable columns.If you enter multiple words, each word will be searched separately, but only rows that contain all words will be displayed. For example, searching for
abc defwill find all rows that containabcanddefin one or more columns.If you prefix your search term with
^, it will find all rows that start with^. So, if you entered^ZZZthenILIKE 'ZZZ%'will be used.If you prefix your search term with
=, it will perform an exact match. For example, if you entered=ZZZ, the statementILIKE 'ZZZ'will be used.
- column_filters = ('id', 'file_location', 'file_type', 'created')¶
Collection of the column filters.
Can contain either field names or instances of
flask_admin.contrib.sqla.filters.BaseSQLAFilterclasses.Filters will be grouped by name when displayed in the drop-down.
For example:
class MyModelView(BaseModelView): column_filters = ('user', 'email')
or:
from flask_admin.contrib.sqla.filters import BooleanEqualFilter class MyModelView(BaseModelView): column_filters = (BooleanEqualFilter(column=User.name, name='Name'),)
or:
from flask_admin.contrib.sqla.filters import BaseSQLAFilter class FilterLastNameBrown(BaseSQLAFilter): def apply(self, query, value, alias=None): if value == '1': return query.filter(self.column == "Brown") else: return query.filter(self.column != "Brown") def operation(self): return 'is Brown' class MyModelView(BaseModelView): column_filters = [ FilterLastNameBrown( User.last_name, 'Last Name', options=(('1', 'Yes'), ('0', 'No')) ) ]
- column_details_list = ('id', 'file_location', 'file_type', 'created')¶
Collection of the field names included in the details view. If set to None, will get them from the model.
- columns_sortable_list = ('id', 'file_location', 'file_type', 'created')¶
- column_labels = {'_displayname': 'Display Name'}¶
Dictionary where key is column name and value is string to display.
For example:
class MyModelView(BaseModelView): column_labels = dict(name='Name', last_name='Last Name')
- action_view()¶
Mass-model action view.
- ajax_lookup()¶
- ajax_update()¶
Edits a single column of a record in list view.
- create_view()¶
Create model view
- delete_view()¶
Delete model view. Only POST method is allowed.
- details_view()¶
Details model view
- edit_view()¶
Edit model view
- export(export_type)¶
- index_view()¶
List view
hepdata.modules.submission.api¶
- hepdata.modules.submission.api.is_resource_added_to_submission(recid, version, resource_url)[source]¶
Returns if a submission already has the given resource url :param recid: :param version: :param resource_url: :return:
- hepdata.modules.submission.api.get_latest_hepsubmission(*args, **kwargs)[source]¶
Gets the latest HEPSubmission record matching the given kwargs
- Returns:
the HEPSubmission object or None
- hepdata.modules.submission.api.get_submission_participants_for_record(publication_recid, roles=None, **kwargs)[source]¶
Gets the participants for a given publication record id
- Parameters:
publication_recid (int) – publication_recid of a submission.
**kwargs – Additional filter parameters to pass to filter_by.
- Returns:
List of participants relating to that record
- Return type:
- hepdata.modules.submission.api.get_primary_submission_participants_for_record(publication_recid)[source]¶
- hepdata.modules.submission.api.get_or_create_submission_observer(publication_recid, regenerate=False)[source]¶
Gets or re/generates a SubmissionObserver key for a given recid. Where an observer does not exist for a recid (with existing sub), it is created and returned instead.
- Parameters:
publication_recid – The publication record id
regenerate – Whether to regenerate/force generate the key
- Returns:
SubmissionObserver key, created, or None
hepdata.modules.submission.models¶
Models for the HEPData Submission Workflow.
- class hepdata.modules.submission.models.LargeBinaryString(*args: Any, **kwargs: Any)[source]¶
Decorator for unicode strings which are stored in the DB as LargeBinary objects, to allow them to be treated as strings in python3
- cache_ok = True¶
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): """a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. """ def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): ... # works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): """a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. """ cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple((key, lookup[key]) for key in sorted(lookup)) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): ... # works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
Added in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.Added in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
- impl¶
alias of
LargeBinary
- process_bind_param(value, dialect)¶
Encodes and returns string object.
- class hepdata.modules.submission.models.HEPSubmission(**kwargs)[source]¶
This is the main submission object. It maintains the submissions to HEPData and who the coordinator and who the reviewers/uploaders are (via participants).
- id¶
- publication_recid¶
- inspire_id¶
- data_abstract¶
- resources¶
- coordinator¶
- overall_status¶
- created¶
- last_updated¶
- version¶
- doi¶
- reviewers_notified¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.SubmissionObserver(publication_recid)[source]¶
Contains observer key entry for access per publication on the publication_recid field.
- observer_key¶
- publication_recid¶
- generate_observer_key()[source]¶
Generates a new observer key (UUID4/random) and sets the observer key.
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.DataSubmission(**kwargs)[source]¶
The submission object associated with a data table.
- id¶
- publication_recid¶
- publication_inspire_id¶
- location_in_publication¶
- name¶
- description¶
- keywords¶
- data_file¶
- resources¶
- doi¶
- associated_recid¶
- version¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.RelatedTable(**kwargs)[source]¶
The submission object associated with a related table entry.
- id¶
- table_doi¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.RelatedRecid(**kwargs)[source]¶
The submission object associated with a related record entry.
- id¶
- this_recid¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- hepdata.modules.submission.models.receive_before_flush(session, flush_context, instances)[source]¶
Listen for the ‘before_flush’ event to check for DataSubmission deletions and ensure related DataResource and DataReview entries are loaded by SQLAlchemy before deletion to ensure all cascades, event listeners, etc are run.
- class hepdata.modules.submission.models.Keyword(**kwargs)[source]¶
- id¶
- name¶
- value¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.License(**kwargs)[source]¶
- id¶
- name¶
- url¶
- description¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.DataResource(**kwargs)[source]¶
Details of a data resource, which could be a data table, an image, a script, a ROOT file, or a link to an external website or GitHub repo.
Data resources can be related to submissions in various ways:
Resources relating to a submission (HEPSubmission.resources) are linked via the data_resource_link table
Data files belonging to a data table (DataSubmission.data_file) are linked via the data_file field of datasubmission
Resources relating to a data table (DataSubmission.resources) are linked via the datafile_identifier table
- id¶
- file_location¶
- file_type¶
- file_description¶
- file_license¶
- created¶
- doi¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- hepdata.modules.submission.models.receive_data_resource_after_delete(mapper, connection, target)[source]¶
Delete the file on disk when a DataResource is deleted
- class hepdata.modules.submission.models.DataReview(**kwargs)[source]¶
Represent a data review including links to the messages made about a data record upload and its current status.
- id¶
- publication_recid¶
- data_recid¶
- creation_date¶
- modification_date¶
- status¶
- messages¶
- version¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.Message(**kwargs)[source]¶
General message structure.
- id¶
- user¶
- message¶
- creation_date¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.Question(**kwargs)[source]¶
Questions for a record are stored.
- id¶
- user¶
- publication_recid¶
- question¶
- creation_date¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
- class hepdata.modules.submission.models.RecordVersionCommitMessage(**kwargs)[source]¶
Stores messages that can be attached to each submission once.
- id¶
- recid¶
- creation_date¶
- version¶
- message¶
- query: t.ClassVar[Query]¶
A SQLAlchemy query for a model. Equivalent to
db.session.query(Model). Can be customized per-model by overridingquery_class.Warning
The query interface is considered legacy in SQLAlchemy. Prefer using
session.execute(select())instead.
hepdata.modules.submission.views¶
- hepdata.modules.submission.views.process_submission_payload(*args, **kwargs)[source]¶
Processes the submission payload.
- Parameters:
inspire_id
title
reviewer
uploader
send_upload_email
- Returns: