Registry
Registry servers have no preferred language but must contain the following endpoints to be valid.
The default registry URL is .
Note
To change the registry URL, run:nessemble registry <URL>
Endpoints
Endpoint | Method | Description | Needs Auth |
---|---|---|---|
/ | GET | List of all packages | |
/status | GET | API status page | |
/search/<string:term> | GET | Search for packages by term |
|
/package/<string:package> | GET | Display information about package package |
|
/package/<string:package>/README | GET | Display README for package package |
|
/package/<string:package>/data | GET | A tarball containing all data for package |
|
/package/publish | POST/PUT | Publish a new package | |
/user/create | POST | Create a user in the registry | |
/user/login | POST | Log into the registry | |
/user/logout | GET/POST | Log out of the registry | |
/user/forgotpassword | POST | Send an email to reset password | |
/user/resetpassword | POST | Reset password | |
/reference | GET | Display reference categories | |
/reference/<path:path> | GET | Display reference information for term path |
Root
GET /
List of all packages.
Request:
GET / HTTP/1.1
Host: xxxxx
Accept: application/json
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
{
"packages": [
{
"title": "foo",
"description": "Foo bar baz qux",
"tags": [
"foo",
"bar",
"baz"
],
"url": "http://xxxxx.xxx/foo"
},
...
],
"pagination": {
"page": 1,
"per_page": 10,
"total": xx,
"prev": null,
"next": "http://xxxxx.xxx/?page=2&per_page=10"
}
}
Pagination request query options:
?page=x
- Page of results to return.?per_page=x
- Results per page to return.?sort_by=xxx
- Key to sort by (title
ordescription
)?order=xxx
- Order of results (asc
ordesc
)
Pagination result information:
page
- Number. Number of current page.per_page
- Number. Number of results per page.total
- Number. Total number of results (items)prev
- String or null. URL of previous page.next
- String or null. URL of next page.
GET /status
API status page.
Request:
GET / HTTP/1.1
Host: xxxxx
Accept: text/html
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/html
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
/search
GET /search/<string:term>
Search for packages by term
.
Request:
GET /search/foo HTTP/1.1
Host: xxxxx
Accept: application/json
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
{
"term": "foo",
"results": [
{
"title": "foo",
"description": "Foo bar baz qux",
"tags": [
"foo",
"bar",
"baz"
],
"url": "http://xxxxx.xxx/foo"
},
...
]
}
/package
Note
The following endpoints also work with/package/<string:version>
in whichversion
is a valid, specific version of the package.
GET /package/<string:package>
Display information about package package
.
Request:
GET /package/foo HTTP/1.1
Host: xxxxx
Accept: application/json
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
{
"title": "foo",
"description": "Foo bar baz qux",
"version": "1.0.1",
"version": {
"1.0.1": "1997-08-29T22:14:00.000Z"
},
"author": "joe.somebody",
"license": "GPLv3",
"tags": [
"foo",
"bar",
"baz"
],
"resource": "http://xxxxx.xxx/foo/data",
"readme": "http://xxxxx.xxx/foo/README",
"shasum": "0123456789abcdef0123456789abcdef12345678"
}
GET /package/<string:package>/README
Display README for package package
.
Request:
GET /package/foo/README HTTP/1.1
Host: xxxxx
Accept: text/plain
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: text/plain
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
# foo
Foo bar baz quz
...
GET /package/<string:package>/data
A tarball containing all data for package
.
Request:
GET /package/foo/data HTTP/1.1
Host: xxxxx
Accept: application/tar+gzip
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/tar+gzip
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
Content-Disposition: attachment; filename="foo-1.0.1.tar.gz"
X-Integrity: 0123456789abcdef0123456789abcdef12345678
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
<raw data>...
POST /package/publish
Publish a new package.
Note
This request must be authorized. See the section on Authorization to learn more.
Request:
POST /package/publish HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/tar+gzip
User-Agent: nessemble/1.0.1
Authorization: HMAC-SHA1 <base64 username:hmac-sha1>
Content-Length: xxx
<content>
Response:
HTTP/1.1 201 CREATED
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{
"title": "foo",
"description": "Foo bar baz qux",
"version": "1.0.1",
"author": "joe.somebody",
"license": "GPLv3",
"tags": [
"foo",
"bar",
"baz"
]
}
If the package is published successfully, a 201
HTTP response code will be
returned along with the contents of the published package.json
.
To update an existing package, the request must be sent as a PUT
request and
the package.json
must contain an updated version
:
PUT /package/publish HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/tar+gzip
User-Agent: nessemble/1.0.1
Authorization: HMAC-SHA1 <base64 username:hmac-sha1>
Content-Length: xxx
<content>
To learn more about the gzipped package content, see the section on Packages.
/user
POST /user/create
Create a user in the registry.
Request:
POST /user/create HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/json
User-Agent: nessemble/1.0.1
Content-Length: xxx
{
"name": "<name>",
"username": "<username>",
"email": "<email>",
"password": "<password>"
}
Response:
HTTP/1.1 201 CREATED
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{}
If the user already exists, the response will be:
HTTP/1.1 409 CONFLICT
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{
"status": 409,
"error": "User already exists"
}
POST /user/login
Log into the registry.
Request:
POST /user/login HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/json
User-Agent: nessemble/1.0.1
Authorization: Basic <base64 username:password>
Content-Length: xxx
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{
"token": "<token>"
}
POST /user/logout
Log out of the registry.
Note
This request must be authorized. See the section on Authorization to learn more.
Request:
POST /user/logout HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/json
User-Agent: nessemble/1.0.1
Authorization: HMAC-SHA1 <base64 username:hmac-sha1>
Content-Length: xxx
{}
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: application/json
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{}
POST /user/forgotpassword
Send an email to reset password.
Request:
POST /user/forgotpassword HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/json
User-Agent: nessemble/1.0.1
Content-Length: xxx
{
"username": "<username>"
}
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{
"email": false,
"url": "http://xxxxx/user/2FA/<id>",
"data": "..."
}
email
- Boolean that indicates whether an email was senturl
- URL of QR code that can be used to provide a token when used in conjunction with apps like Google Authenticator.data
- Response-specific Base64-encoded data.
POST /user/resetpassword
Reset password.
Note
Authorization in terms of generating the HMAC-SHA1 works just as described in the Authorization section, but thetoken
used must be the one emailed to the user after utilizing the/user/forgotpassword
endpoint.
Request:
POST /user/resetpassword HTTP/1.1
Host: xxxxx
Accept: application/json
Content-Type: application/json
User-Agent: nessemble/1.0.1
Authorization: HMAC-SHA1 <base64 username:hmac-sha1>
Content-Length: xxx
{
"username": "<username>",
"password": "<password>"
}
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0
Expires: -1
{}
/reference
GET /reference
Display reference categories.
Request:
GET /reference HTTP/1.1
Host: xxxxx
Accept: text/plain
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: text/plain
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
foo
bar
baz
GET /reference/<path:path>
Display reference information for term path
.
Request:
GET /reference/foo/bar HTTP/1.1
Host: xxxxx
Accept: text/plain
User-Agent: nessemble/1.0.1
Response:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: text/plain
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
baz
qux
If no such path exists, the response will be:
HTTP/1.1 404 NOT FOUND
Content-Length: xxx
Content-Type: text/plain
Access-Control-Allow-Origin: *
Server: Nessemble
X-Response-Time: x.xxx
X-RateLimit-Limit: xx
X-RateLimit-Remaining: xx
X-RateLimit-Reset: xxxxxxxxxx
Retry-After: xx
Date: Fri, 29 Aug 1997 22:14:00 GMT
Cache-Control: max-age=xxxx
Expires: xxxxxxxxxx
{
"status": 404,
"error": "Not Found"
}
Versioning
Versioning may be done in a few ways: header versioning or URL versioning.
Header Versioning
To indicate which version of the API to use, send the version along with the
Accept
header:
GET /foo/bar HTTP/1.1
Host: xxxxx
Accept: application/json;version=1
User-Agent: nessemble/1.0.1
URL Versioning
To change the version in a URL versioned registry, use the
registry
command to update the URL.
nessemble registry http://foo.com/v1
Authorization
Some requests must be authorized. Here is the workflow:
- Get a
token
from the/user/login
endpoint. - Generate a
HMAC-SHA1
using thetoken
as thekey
and a concatenation of the method and endpoint (with a+
) as themessage
. (Ex:POST+/user/logout
) - Set the
Authorization
header toHMAC-SHA1 <base64 email:hmac-sha1>
where the user's email and theHMAC-SHA1
are concatenated (with a:
) and Base64 encoded.
Here is an example in Python:
#!/usr/bin/env python
"""Authorization example"""
import base64
import hmac
from hashlib import sha1
import requests
# get token
login_request = requests.post('http://[DOMAIN]/user/login', auth=('[USERNAME]', '[PASSWORD]'))
if login_request.status_code != 200:
print 'Login failed!'
exit(1)
print 'Login successful!'
data = login_request.json()
token = data['token']
# generate HMAC-SHA1
hmac_hash = hmac.new(str(token), 'POST+/user/logout', sha1)
hmac_sha1 = hmac_hash.hexdigest()
# send authorized request
base64_auth = base64.b64encode('%s:%s' % ('[USERNAME]', hmac_sha1))
headers = {
'Authorization': 'HMAC-SHA1 %s' % (base64_auth)
}
logout_request = requests.post('http://[DOMAIN]/user/logout', headers=headers)
if logout_request.status_code != 200:
print 'Logout failed!'
exit(1)
print 'Logout successful!'
GraphQL
GraphQL
is also (partially) supported via the /graphql
endpoint.
Try it live: /graphql