pharus package

pharus.error module

Error class library.

exception pharus.error.InvalidRestriction

Bases: Exception

Exception raised when restrictions result in no records when expected at least one.

exception pharus.error.UnsupportedTableType

Bases: Exception

Exception raised on unsupported table types.

pharus.interface module

Library for interfaces into DataJoint pipelines.

pharus.server module

Exposed REST API.

pharus.server.api_version() str

Handler for /version route.

Returns:

API version

Return type:

str

GET /version

Route to check server health returning the API version.

Example request:

GET /version HTTP/1.1
Host: fakeservices.datajoint.io

Example response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "version": "0.7.3"
}
Status Codes:
pharus.server.attribute(connection: Connection, schema_name: str, table_name: str) dict

Handler for /schema/{schema_name}/table/{table_name}/attribute route.

Parameters:
  • connection (dj.Connection) – User’s DataJoint connection object

  • schema_name (str) – Schema name.

  • table_name (str) – Table name.

Returns:

If successful then sends back dict of table attributes otherwise returns error.

Return type:

dict

GET /schema/{schema_name}/table/{table_name}/attribute

Route to get metadata on table attributes.

Example request:

GET /schema/alpha_company/table/Computer/attribute HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "attributeHeader": [
        "name",
        "type",
        "nullable",
        "default",
        "autoincrement"
    ],
    "attributes": {
        "primary": [
            [
                "computer_id",
                "uuid",
                false,
                null,
                false
            ]
        ],
        "secondary": [
            [
                "computer_serial",
                "varchar(9)",
                false,
                ""ABC101"",
                false
            ],
            [
                "computer_brand",
                "enum('HP','Dell')",
                false,
                null,
                false
            ],
            [
                "computer_built",
                "date",
                false,
                null,
                false
            ],
            [
                "computer_processor",
                "double",
                false,
                null,
                false
            ],
            [
                "computer_memory",
                "int",
                false,
                null,
                false
            ],
            [
                "computer_weight",
                "float",
                false,
                null,
                false
            ],
            [
                "computer_cost",
                "decimal(6,2)",
                false,
                null,
                false
            ],
            [
                "computer_preowned",
                "tinyint",
                false,
                null,
                false
            ],
            [
                "computer_purchased",
                "datetime",
                false,
                null,
                false
            ],
            [
                "computer_updates",
                "time",
                true,
                "null",
                false
            ],
            [
                "computer_accessories",
                "longblob",
                true,
                "null",
                false
            ]
        ]
    }
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could not
    understand.
Request Headers:
Response Headers:
Status Codes:
pharus.server.definition(connection: Connection, schema_name: str, table_name: str) str

Handler for /schema/{schema_name}/table/{table_name}/definition route.

Parameters:
  • connection (dj.Connection) – User’s DataJoint connection object

  • schema_name (str) – Schema name.

  • table_name (str) – Table name.

Returns:

If successful then sends back definition for table otherwise returns error.

Return type:

str

GET /schema/{schema_name}/table/{table_name}/definition

Route to get DataJoint table definition.

Example request:

GET /schema/alpha_company/table/Computer/definition HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/plain

# Computers that belong to the company
computer_id          : uuid                      # unique id
---
computer_serial="ABC101" : varchar(9)            # manufacturer serial number
computer_brand       : enum('HP','Dell')         # manufacturer brand
computer_built       : date                      # manufactured date
computer_processor   : double                    # processing power in GHz
computer_memory      : int                       # RAM in GB
computer_weight      : float                     # weight in lbs
computer_cost        : decimal(6,2)              # purchased price
computer_preowned    : tinyint                   # purchased as new or used
computer_purchased   : datetime                  # purchased date and time
computer_updates=null : time                     # scheduled daily update timeslot
computer_accessories=null : longblob             # included additional accessories

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could not
    understand.
Request Headers:
Response Headers:
Status Codes:
pharus.server.dependency(connection: Connection, schema_name: str, table_name: str) dict

Handler for /schema/{schema_name}/table/{table_name}/dependency route.

Parameters:
  • connection (dj.Connection) – User’s DataJoint connection object

  • schema_name (str) – Schema name.

  • table_name (str) – Table name.

Returns:

If sucessfuly sends back a list of dependencies otherwise returns error.

Return type:

dict

GET /schema/{schema_name}/table/{table_name}/dependency

Route to get the metadata in relation to the dependent records associated with a restricted subset of a table.

Example request:

GET /schema/alpha_company/table/Computer/dependency?restriction=W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3BlcmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo= HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "dependencies": [
        {
            "accessible": true,
            "count": 2,
            "schema": "alpha_company",
            "table": "computer"
        },
        {
            "accessible": true,
            "count": 2,
            "schema": "alpha_company",
            "table": "#employee"
        }
    ]
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could
    not understand.
Query Parameters:
  • schema_name – Schema name.

  • table_name – Table name.

  • restriction – Base64-encoded AND sequence of restrictions. For example, you could restrict as [{"attributeName": "computer_memory", "operation": ``- ``">=", "value": 16}] with this param set as W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3Bl- cmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo=. Defaults to no restriction.

Request Headers:
Response Headers:
Status Codes:
pharus.server.login() dict

WARNING: Currently, this implementation exposes user database credentials as plain text in POST body once and stores it within a bearer token as Base64 encoded for subsequent requests. That is how the server is able to submit queries on user’s behalf. Due to this, it is required that remote hosts expose the server only under HTTPS to ensure end-to-end encryption. Sending passwords in plain text over HTTPS in POST request body is common and utilized by companies such as GitHub (2021) and Chase Bank (2021). On server side, there is no caching, logging, or storage of received passwords or tokens and thus available only briefly in memory. This means the primary vulnerable point is client side. Users should be responsible with their passwords and bearer tokens treating them as one-in-the-same. Be aware that if your client system happens to be compromised, a bad actor could monitor your outgoing network requests and capture/log your credentials. However, in such a terrible scenario, a bad actor would not only collect credentials for your DataJoint database but also other sites such as github.com, chase.com, etc. Please be responsible and vigilant with credentials and tokens on client side systems. Improvements to the above strategy is currently being tracked in https://github.com/datajoint/pharus/issues/82.

Handler for /login route.

Returns:

Function output is an encoded JWT if successful, otherwise return error message

Return type:

dict

POST /login

Route to generate an authentication token.

Example request:

POST /login HTTP/1.1
Host: fakeservices.datajoint.io
Accept: application/json

{
    "databaseAddress": "tutorial-db.datajoint.io",
    "username": "user1",
    "password": "password1"
}

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "jwt": "<token>"
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could not
    understand.
Response Headers:
Status Codes:
pharus.server.protected_route(function: Callable) Callable

Protected route function decorator which authenticates requests.

Parameters:

function (Callable) – Function to decorate, typically routes

Returns:

Function output if JWT authetication is successful, otherwise return error message

Return type:

Callable

pharus.server.record(connection: Connection, schema_name: str, table_name: str) dict | str | tuple

Handler for /schema/{schema_name}/table/{table_name}/record route.

Parameters:
  • connection (dj.Connection) – User’s DataJoint connection object

  • schema_name (str) – Schema name.

  • table_name (str) – Table name.

Returns:

If successful performs desired operation based on HTTP method, otherwise returns error.

Return type:

Union[dict, str, tuple]

GET /schema/{schema_name}/table/{table_name}/record

Route to fetch records.

Example request:

GET /schema/alpha_company/table/Computer/record?limit=1&page=2&order=computer_id%20DESC&restriction=W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3BlcmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo= HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "recordHeader": [
        "computer_id",
        "computer_serial",
        "computer_brand",
        "computer_built",
        "computer_processor",
        "computer_memory",
        "computer_weight",
        "computer_cost",
        "computer_preowned",
        "computer_purchased",
        "computer_updates",
        "computer_accessories"
    ],
    "records": [
        [
            "4e41491a-86d5-4af7-a013-89bde75528bd",
            "DJS1JA17G",
            "Dell",
            1590364800,
            2.2,
            16,
            4.4,
            "700.99",
            0,
            1603181061,
            null,
            "=BLOB="
        ]
    ],
    "totalCount": 2
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could
    not understand.
Query Parameters:
  • schema_name – Schema name.

  • table_name – Table name.

  • limit – Limit of how many records per page. Defaults to 1000.

  • page – Page requested. Defaults to 1.

  • order – Sort order. Defaults to KEY ASC.

  • restriction – Base64-encoded AND sequence of restrictions. For example, you could restrict as [{"attributeName": "computer_memory", "operation": ``- ``">=", "value": 16}] with this param set as W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3Bl- cmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo=. Defaults to no restriction.

Request Headers:
Response Headers:
Status Codes:
POST /schema/{schema_name}/table/{table_name}/record

Route to insert a record. Omitted attributes utilize the default if set.

Example request:

POST /schema/alpha_company/table/Computer/record HTTP/1.1
Host: fakeservices.datajoint.io
Accept: application/json
Authorization: Bearer <token>

{
    "records": [
        {
            "computer_id": "ffffffff-86d5-4af7-a013-89bde75528bd",
            "computer_serial": "ZYXWVEISJ",
            "computer_brand": "HP",
            "computer_built": "2021-01-01",
            "computer_processor": 2.7,
            "computer_memory": 32,
            "computer_weight": 3.7,
            "computer_cost": 599.99,
            "computer_preowned": 0,
            "computer_purchased": "2021-02-01 13:00:00",
            "computer_updates": 0
        }
    ]
}

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/plain

{
    "response": "Insert Successful"
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could
    not understand.
Request Headers:
Response Headers:
Status Codes:
PATCH /schema/{schema_name}/table/{table_name}/record

Route to update a record. Omitted attributes utilize the default if set.

Example request:

PATCH /schema/alpha_company/table/Computer/record HTTP/1.1
Host: fakeservices.datajoint.io
Accept: application/json
Authorization: Bearer <token>

{
    "records": [
        {
            "computer_id": "ffffffff-86d5-4af7-a013-89bde75528bd",
            "computer_serial": "ZYXWVEISJ",
            "computer_brand": "HP",
            "computer_built": "2021-01-01",
            "computer_processor": 2.7,
            "computer_memory": 32,
            "computer_weight": 3.7,
            "computer_cost": 601.01,
            "computer_preowned": 0,
            "computer_purchased": "2021-02-01 13:00:00",
            "computer_updates": 0
        }
    ]
}

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/plain

{
    "response": "Update Successful"
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could
    not understand.
Request Headers:
Response Headers:
Status Codes:
DELETE /schema/{schema_name}/table/{table_name}/record

Route to delete a specific record.

Example request:

DELETE /schema/alpha_company/table/Computer/record?cascade=false&restriction=W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3BlcmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo= HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/plain

{
    "response": "Delete Successful"
}

Example conflict response:

HTTP/1.1 409 Conflict
Vary: Accept
Content-Type: application/json

{
    "error": "IntegrityError",
    "error_msg": "Cannot delete or update a parent row: a foreign key
        constraint fails (`alpha_company`.`#employee`, CONSTRAINT
        `#employee_ibfk_1` FOREIGN KEY (`computer_id`) REFERENCES `computer`
        (`computer_id`) ON DELETE RESTRICT ON UPDATE CASCADE",
    "child_schema": "alpha_company",
    "child_table": "Employee"
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could
    not understand.
Query Parameters:
  • cascade – Enable cascading delete. Accepts true or false. Defaults to false.

  • restriction – Base64-encoded AND sequence of restrictions. For example, you could restrict as [{"attributeName": "computer_memory", "operation": ``- ``">=", "value": 16}] with this param set as W3siYXR0cmlidXRlTmFtZSI6ICJjb21wdXRlcl9tZW1vcnkiLCAib3Bl- cmF0aW9uIjogIj49IiwgInZhbHVlIjogMTZ9XQo=. Defaults to no restriction.

Request Headers:
Response Headers:
Status Codes:
pharus.server.run()

Starts API server.

pharus.server.schema(connection: Connection) dict

Handler for /schema route.

Parameters:

connection (dj.Connection) – User’s DataJoint connection object

Returns:

If successful then sends back a list of schemas names otherwise returns error.

Return type:

dict

GET /schema

Route to get list of schemas.

Example request:

GET /schema HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "schemaNames": [
        "alpha_company"
    ]
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could not
    understand.
Request Headers:
Response Headers:
Status Codes:
pharus.server.spec(connection: Connection) dict
pharus.server.table(connection: Connection, schema_name: str) dict

Handler for /schema/{schema_name}/table route.

Parameters:
  • connection (dj.Connection) – User’s DataJoint connection object

  • schema_name (str) – Schema name.

Returns:

If successful then sends back a list of table names otherwise returns error.

Return type:

dict

GET /schema/{schema_name}/table

Route to get tables within a schema.

Example request:

GET /schema/alpha_company/table HTTP/1.1
Host: fakeservices.datajoint.io
Authorization: Bearer <token>

Example successful response:

HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json

{
    "tableTypes": {
        "computed": [],
        "imported": [],
        "lookup": [
            "Employee"
        ],
        "manual": [
            "Computer"
        ],
        "part": []
    }
}

Example unexpected response:

HTTP/1.1 500 Internal Server Error
Vary: Accept
Content-Type: text/plain

400 Bad Request: The browser (or proxy) sent a request that this server could not
    understand.
Query Parameters:
  • schema_name – Schema name.

Request Headers:
Response Headers:
Status Codes:

pharus.version module

Package metadata.