.. TopChef documentation master file, created by sphinx-quickstart on Fri May 6 00:06:02 2016. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to TopChef's documentation! =================================== TopChef solves the problem of getting a computer "here" to do something on a computer over "there". It provides an abstraction layer over the networking, so that the computer "here" doesn't need to known how to connect to the computer "there", as long as it can connect to the TopChef server. It also wraps all the logic behind an interface that runs through HTTP, so that `any `_ `of `_ `the `_ `multitude `_ `of `_ `HTTP `_ `clients `_ out there can work together to solve a problem. TopChef wants to make HTTP networking as easy as making an HTTP request. TopChef was originally developed at the Institute for Quantum Computing, in order to enable online experiment design, connecting machine learning algorithms to the control computers running experiments. To run TopChef, you will need a server capable of connecting to both "here" and "there". The recommended approach is to use the `docker container `_. For more information about installation and running the application, consult the project's `README `_. The project source code is hosted on `GitHub `_. Report bugs, feature requests, support requests, and other issues to the project's `issue tracker `_. Features -------- * :ref:`json-schema` checks to make sure all messages are valid * Job result storage on - `MySQL `_ - `PostgreSQL `_ * HTTP REST API for sending and receiving messages * HTTP method override HTTP API Guide -------------- This section contains a detailed description of the HTTP endpoints exposed by this application. For more details about about how HTTP works, see the section :ref:`http-requests`. .. qrefflask:: topchef:APP_FACTORY.app :undoc-static: .. toctree:: :maxdepth: 3 http_api The User Guide -------------- This section contains tutorials on using the server, and on server maintenance. It also provides introductory guides to some of the technologies that TopChef needs to make it tick. If you want to know how to do something in this server, or why some code was implemented in a particular way, this is the section for you! .. toctree:: :maxdepth: 3 user_documentation/index API Reference ------------- This section contains the nuts-and-bolts, nitty-gritty description of TopChef. This section is composed primarily of auto-generated documentation built from the source code that runs the server. .. toctree:: :maxdepth: 3 api_reference/index Overview -------- The aim of this project is to have one TopChef server running per group, providing a broker between multiple experiments and clients. To do this, we need to consider the idea of a ``Service``, and a ``Job``. A ``Service`` represents some entity that can listen for jobs, and that does "one thing". Each ``Service`` has one :ref:`json-schema` for posting new jobs, and one :ref:`json-schema` for posting results. These two schemas specify the contract for the service. A Practical Example: ~~~~~~~~~~~~~~~~~~~~ Suppose we want a service that adds one to a given integer. The JSON that will create our service is given below. Let's assign this to a Python variable for use later. All our HTTP requests will be done using Python's :mod:`requests` library. .. sourcecode:: python job_data = { "name": "Add One", "description": "Adds one to a given number", "job_registration_schema": { "title": "The schema for the service", "description": "Adds one to a given number", "$schema": "http://json-schema.org/schema#", "type": "object", "properties": { "value": { "title": "value", "description": "The number to add", "type": "integer" } }, "required": ["value"] }, "job_result_schema": { "title": "Results", "description": "The schema for valid job results", "$schema": "http://json-schema.org/schema#", "type": "object", "properties": { "result": { "title": "result", "description": "The result", "type": "integer" } }, "required": ["value"] } } This may look like a mouthful, but it is in fact quite simple. The ``name`` and ``description`` keys at the top level of the ``job_data`` variable provide human-readable information to describe what our service will do. The ``job_registration_schema`` describes what the job parameters must look like. In our case, the service will take an object that will have a key ``value``, and the value of this key must be an integer. For instance, the object .. sourcecode:: json {"value": 1} is a valid parameter, but the object .. sourcecode:: json {"value": "1"} is not. Let's say a ``TopChef`` server was already started, and is running on address ``http://localhost:5000``. Using :mod:`requests`, the code to do this will look something like .. sourcecode:: python import requests import json url_to_post_to = 'http://localhost:5000/services' request_headers = {'Content-Type': 'application/json'} response = requests.post( url_to_post_to, headers=request_headers, json=job_data ) assert response.status_code == 201 The ``assert`` statement at the bottom checks that the response returns the status code ``201``, indicating that our service was successfully created. As part of the process, TopChef will assign a universally-unique identifier (UUID) to our service. Let's say that ID is ``66ca5284-ba62-4307-8739-4a09466a924f``. In order to send jobs to this service, we can run code that looks something like this .. sourcecode:: python import requests import json data = {'parameters': {'value': '1'}} request_headers = {'Content-Type': 'application/json'} url_to_post_to = 'http://localhost:5000/services/66ca5284-ba62-4307-8739-4a09466a924f/jobs` response = requests.post( url_to_post_to, headers=request_headers, data=data ) assert response.status_code == 201 In a similar way to services, each ``Job`` also gets a job UUID. Let's say that the job ID is ``d476cf16-356e-4828-bcb4-81c39f0c1aeb``. If we were to send a ``GET`` request to ``/jobs/d476cf16-356e-4828-bcb4-81c39f0c1aeb``, we would find that the request body looks like .. sourcecode:: json { "id": "d476cf16-356e-4828-bcb4-81c39f0c1aeb", "status": "REGISTERED", "parameters": { "value": 1 }, "results": null } We wait for the service to finish this job, and after some time, we get the result .. sourcecode:: json { "id": "d476cf16-356e-4828-bcb4-81c39f0c1aeb", "status": "COMPLETED", "parameters": { "value": 1 }, "results": { "result": 2 } } Our job is now complete. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search`