splent_feature_orcid
The orcid feature of a SPLENT product line.
Sign in and sign up with ORCID, and connect an ORCID iD to an account from
its profile. identities runs the sign-in for every provider, and this feature
describes ORCID to it: its endpoints under ORCID_BASE_URL (the sandbox in
development), its scope (ORCID_SCOPE), and how to read who signed in from
its userinfo endpoint. An ORCID iD always signs in to the account it is
linked to, and never to an existing account because an email matches. A new
account is opened once the person checks the name ORCID gives and types an
address, which ORCID never verifies: where the product confirms addresses, a
link goes to it, and the account is opened when the person follows it and
signs in with the same iD once more (identities' README). It needs auth,
profile and identities, which keeps the linked accounts.
A SPLENT feature is a Python package that a product composes with others.
Its models, routes, services, templates and hooks are registered when the
product starts. What this feature provides and requires is listed in the
[tool.splent.contract] section of pyproject.toml, which
splent feature:contract --write keeps in sync with the source.
Settings
| Setting | Default | What it is |
|---|---|---|
ORCID_CLIENT_ID |
empty | The client id of the application registered at https://orcid.org/developer-tools |
ORCID_CLIENT_SECRET |
empty | Its secret |
ORCID_BASE_URL |
https://orcid.org |
The ORCID the application is registered with. https://sandbox.orcid.org for development and tests, whose iDs and credentials only exist there |
ORCID_SCOPE |
/authenticate |
What the sign-in asks ORCID for. /authenticate gives the iD and the name, all a sign-in needs. A product that reads or writes records on ORCID asks for more, and registers its application for it |
Without both credentials ORCID sign-in is off: the app logs a warning at
start, and whoever tries is told it is not available. The sign-in, the
token, the userinfo and the link to an iD's record all follow
ORCID_BASE_URL. The callback registered with ORCID is
<OAUTH_REDIRECT_BASE_URL>/orcid/authorize (identities' setting).
Where it shows
It fills the slots other features open, by name, so it composes with whatever the product has and overrides nothing.
| Slot | Opened by | What ORCID draws |
|---|---|---|
auth.login.providers |
auth | The ORCID button, under "or continue with" |
signup.providers |
signup, when the product has it | The same button, after the sign-up form |
profile.edit.sections |
profile | The linked iD, as a link to its record on ORCID, with a disconnect button, or a "Connect ORCID" link |
layout.head.css |
the product's app shell | Its stylesheet, assets/css/orcid.css |
It takes order 20 in the first three, after GitHub's 10. The button carries
where the reader was heading (?next=), and only a path on this site.
ORCID's green is in assets/css/orcid.css, never on the elements. The public
shell loads the file from the asset registry (register_asset), and the app
shell, which does not render the registry, through layout.head.css. A
product that wants another look overrides .btn.btn-orcid and the
orcid-identity__* classes in a stylesheet of its own.
A product without signup
A product that does not install splent_feature_signup is closed, and its
accounts are opened by an administrator. ORCID follows the rule identities
holds for every provider.
| Visitor | With signup | Without signup |
|---|---|---|
| Signs in with an ORCID iD already linked | Signed in | Signed in |
| Connects ORCID from their profile | Linked | Linked |
| Signs in with an ORCID iD linked to nobody | Asked for an address and the details of a new account | Sent back to the login page with a translated message that asks them to request access from an administrator, or to connect ORCID from their profile if they have an account |
The button goes straight to ORCID either way. An address is asked for afterwards, by identities, and only when the sign-in opens a new account.
What it adds to the profile
| What | How | Needs |
|---|---|---|
get_orcid() on profile's UserProfile, the linked iD or None, which dataset authors and the API read |
A refinement declared in pyproject.toml ([tool.splent.refinement]), applied by the framework when the product starts. It reads the account's ORCID identity in external_identity |
profile |
The orcid key of /api/v1/profile/me, the linked iD or null |
profile's register_profile_payload |
profile |
| The name, surname and affiliation ORCID gives, on the form a new account is opened with | PROFILE_CLAIMS maps each claim to the profile field it starts. A field no feature asks for is not on the form |
academic_profile, for the affiliation |
{"name": "Ada", "surname": "Lovelace", "email": "ada@example.com", "orcid": "0000-0002-1825-0097"}
get_orcid() is a method and adds no column. It sits beside the other
refiners of UserProfile, such as academic_profile, which adds
affiliation to the same model, so a product can have both.
register_profile_payload is new in the profile released with 0.1.0.
Against an older profile ORCID still starts and leaves the orcid key out
with a warning in the log. Only a missing module or function counts as an
older profile. An error inside profile's own code stops the start as it
is, rather than passing for one.
Which iDs are linked here
OrcidService, on the service locator, tells another feature which iDs this
product can vouch for: an iD is linked only once its holder signed in with
it at ORCID. dataset's upload API credits an author's iD only when it is.
| Call | Answers |
|---|---|
is_linked(orcid_id) |
Whether the iD, as written or as its URL, is linked to an account here |
orcid_of(user_id) |
The account's iD, or None |
repository.get_by_orcid_id(orcid_id) |
The ORCID identity in external_identity, or None. What dataset 0.1 calls |
A feature that uses it finds it through the locator and does without it when ORCID is not installed, so it never imports this feature.
The orcid table
Earlier versions kept every iD twice: in external_identity, which signs
people in, and in an orcid table keyed by profile, which get_orcid()
read. orcid0002_into_external_identity folds the table into
external_identity and drops it. Each row becomes the account's ORCID
identity, or completes the one it already has (the iD as its username, the
earlier date). A row that would lose a link or give it to another account
(its profile is gone, the iD is linked to someone else, the account has
another iD) stops the migration before anything changes, and the message
names the rows. The downgrade puts the table back with a row for every
ORCID identity of an account with a profile.
Translations
The edit-profile row and the messages about ORCID's answers ship with a Spanish catalog.
Use it in a product
splent feature:add splent_feature_orcid
Develop
The tests simulate ORCID (tests/conftest.py): the flow's OAuth client
answers the token exchange and /oauth/userinfo as each test chooses.
splent feature:test splent_feature_orcid --with identities --with github
splent feature:contract splent_feature_orcid
Release
splent feature:release splent_feature_orcid --dry-run --bump patch
splent feature:release splent_feature_orcid
The first command rehearses the release and changes nothing. The second
publishes it to the git forge and to PyPI, and a PyPI version is permanent.
This version needs the identities that brings the shared flow and
provider_email_verified, so the two are released together.
Metadata
Release files for splent-feature-orcid 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| splent_feature_orcid-0.3.0.tar.gz | 31.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| splent_feature_orcid-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 68.1 kB
Release files / splent_feature_orcid-0.3.0.tar.gz
| Download URL | splent_feature_orcid-0.3.0.tar.gz |
|---|---|
| Size | 31.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6cb89c957b217cff754d13dd02e28654fa36a13af157f0057be625854b12ded5
|
|
BLAKE2b-256 checksum How to use checksums |
d6a7698f25ff54d18b61c0ae881e00e4a6e29e12d6133d0653802ba23caf40e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.16
|
Release files / splent_feature_orcid-0.3.0-py3-none-any.whl
| Download URL | splent_feature_orcid-0.3.0-py3-none-any.whl |
|---|---|
| Size | 36.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ee77092523c59db722612ce33918fa1dbf893671eb571ed543a25cbbed919236
|
|
BLAKE2b-256 checksum How to use checksums |
c431528cb03e06e7a6c8d61b295fa9c8f9032a785cc3cc9a65c243ac49a52306
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.16
|
Security for splent-feature-orcid 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.