Show More
@@ -1,100 +1,104 b'' | |||||
1 | # Makefile for Sphinx documentation |
|
1 | # Makefile for Sphinx documentation | |
2 | # |
|
2 | # | |
3 |
|
3 | |||
4 | # You can set these variables from the command line. |
|
4 | # You can set these variables from the command line. | |
5 | SPHINXOPTS = |
|
5 | SPHINXOPTS = | |
6 | SPHINXBUILD = sphinx-build |
|
6 | SPHINXBUILD = sphinx-build | |
7 | PAPER = |
|
7 | PAPER = | |
8 | SRCDIR = source |
|
8 | SRCDIR = source | |
9 |
|
9 | |||
10 | # Internal variables. |
|
10 | # Internal variables. | |
11 | PAPEROPT_a4 = -D latex_paper_size=a4 |
|
11 | PAPEROPT_a4 = -D latex_paper_size=a4 | |
12 | PAPEROPT_letter = -D latex_paper_size=letter |
|
12 | PAPEROPT_letter = -D latex_paper_size=letter | |
13 | ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) |
|
13 | ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SRCDIR) | |
14 |
|
14 | |||
15 | .PHONY: help clean html web pickle htmlhelp latex changes linkcheck api |
|
15 | .PHONY: help clean html web pickle htmlhelp latex changes linkcheck api | |
16 |
|
16 | |||
17 | default: html |
|
17 | default: html | |
18 |
|
18 | |||
19 | help: |
|
19 | help: | |
20 | @echo "Please use \`make <target>' where <target> is one of" |
|
20 | @echo "Please use \`make <target>' where <target> is one of" | |
21 | @echo " html to make standalone HTML files" |
|
21 | @echo " html to make standalone HTML files" | |
22 | @echo " pickle to make pickle files (usable by e.g. sphinx-web)" |
|
22 | @echo " pickle to make pickle files (usable by e.g. sphinx-web)" | |
23 | @echo " htmlhelp to make HTML files and a HTML help project" |
|
23 | @echo " htmlhelp to make HTML files and a HTML help project" | |
24 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" |
|
24 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | |
25 | @echo " changes to make an overview over all changed/added/deprecated items" |
|
25 | @echo " changes to make an overview over all changed/added/deprecated items" | |
26 | @echo " linkcheck to check all external links for integrity" |
|
26 | @echo " linkcheck to check all external links for integrity" | |
27 | @echo |
|
27 | @echo | |
28 | @echo "Compound utility targets:" |
|
28 | @echo "Compound utility targets:" | |
29 | @echo "pdf latex and then runs the PDF generation" |
|
29 | @echo "pdf latex and then runs the PDF generation" | |
30 | @echo "all html and pdf" |
|
30 | @echo "all html and pdf" | |
31 | @echo "dist all, and then puts the results in dist/" |
|
31 | @echo "dist all, and then puts the results in dist/" | |
32 | @echo "gitwash-update update git workflow from source repo" |
|
32 | @echo "gitwash-update update git workflow from source repo" | |
33 |
|
33 | |||
34 | clean: |
|
34 | clean: | |
35 | -rm -rf build/* dist/* $(SRCDIR)/api/generated |
|
35 | -rm -rf build/* dist/* $(SRCDIR)/api/generated | |
36 |
|
36 | |||
37 | pdf: latex |
|
37 | pdf: latex | |
38 | cd build/latex && make all-pdf |
|
38 | cd build/latex && make all-pdf | |
39 |
|
39 | |||
40 | all: html pdf |
|
40 | all: html pdf | |
41 |
|
41 | |||
42 |
dist: |
|
42 | dist: all | |
43 | mkdir -p dist |
|
43 | mkdir -p dist | |
|
44 | rm -rf dist/* | |||
44 | ln build/latex/ipython.pdf dist/ |
|
45 | ln build/latex/ipython.pdf dist/ | |
45 | cp -al build/html dist/ |
|
46 | cp -al build/html dist/ | |
46 | @echo "Build finished. Final docs are in dist/" |
|
47 | @echo "Build finished. Final docs are in dist/" | |
47 |
|
48 | |||
48 | html: api |
|
49 | html: api | |
49 | mkdir -p build/html build/doctrees |
|
50 | mkdir -p build/html build/doctrees | |
50 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html |
|
51 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html | |
51 | @echo |
|
52 | @echo | |
52 | @echo "Build finished. The HTML pages are in build/html." |
|
53 | @echo "Build finished. The HTML pages are in build/html." | |
53 |
|
54 | |||
54 | api: source/api/generated/gen.txt |
|
55 | api: source/api/generated/gen.txt | |
55 |
|
56 | |||
56 | source/api/generated/gen.txt: |
|
57 | source/api/generated/gen.txt: | |
57 | python autogen_api.py |
|
58 | python autogen_api.py | |
58 | @echo "Build API docs finished." |
|
59 | @echo "Build API docs finished." | |
59 |
|
60 | |||
60 | pickle: |
|
61 | pickle: | |
61 | mkdir -p build/pickle build/doctrees |
|
62 | mkdir -p build/pickle build/doctrees | |
62 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle |
|
63 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle | |
63 | @echo |
|
64 | @echo | |
64 | @echo "Build finished; now you can process the pickle files or run" |
|
65 | @echo "Build finished; now you can process the pickle files or run" | |
65 | @echo " sphinx-web build/pickle" |
|
66 | @echo " sphinx-web build/pickle" | |
66 | @echo "to start the sphinx-web server." |
|
67 | @echo "to start the sphinx-web server." | |
67 |
|
68 | |||
68 | web: pickle |
|
69 | web: pickle | |
69 |
|
70 | |||
70 | htmlhelp: |
|
71 | htmlhelp: | |
71 | mkdir -p build/htmlhelp build/doctrees |
|
72 | mkdir -p build/htmlhelp build/doctrees | |
72 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp |
|
73 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp | |
73 | @echo |
|
74 | @echo | |
74 | @echo "Build finished; now you can run HTML Help Workshop with the" \ |
|
75 | @echo "Build finished; now you can run HTML Help Workshop with the" \ | |
75 | ".hhp project file in build/htmlhelp." |
|
76 | ".hhp project file in build/htmlhelp." | |
76 |
|
77 | |||
77 | latex: api |
|
78 | latex: api | |
78 | mkdir -p build/latex build/doctrees |
|
79 | mkdir -p build/latex build/doctrees | |
79 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex |
|
80 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex | |
80 | @echo |
|
81 | @echo | |
81 | @echo "Build finished; the LaTeX files are in build/latex." |
|
82 | @echo "Build finished; the LaTeX files are in build/latex." | |
82 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ |
|
83 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ | |
83 | "run these through (pdf)latex." |
|
84 | "run these through (pdf)latex." | |
84 |
|
85 | |||
85 | changes: |
|
86 | changes: | |
86 | mkdir -p build/changes build/doctrees |
|
87 | mkdir -p build/changes build/doctrees | |
87 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes |
|
88 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes | |
88 | @echo |
|
89 | @echo | |
89 | @echo "The overview file is in build/changes." |
|
90 | @echo "The overview file is in build/changes." | |
90 |
|
91 | |||
91 | linkcheck: |
|
92 | linkcheck: | |
92 | mkdir -p build/linkcheck build/doctrees |
|
93 | mkdir -p build/linkcheck build/doctrees | |
93 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck |
|
94 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck | |
94 | @echo |
|
95 | @echo | |
95 | @echo "Link check complete; look for any errors in the above output " \ |
|
96 | @echo "Link check complete; look for any errors in the above output " \ | |
96 | "or in build/linkcheck/output.txt." |
|
97 | "or in build/linkcheck/output.txt." | |
97 |
|
98 | |||
98 | gitwash-update: |
|
99 | gitwash-update: | |
99 | python ../tools/gitwash_dumper.py source/development ipython |
|
100 | python ../tools/gitwash_dumper.py source/development ipython | |
100 | cd source/development/gitwash && rename 's/.rst/.txt/' *.rst |
|
101 | cd source/development/gitwash && rename 's/.rst/.txt/' *.rst | |
|
102 | ||||
|
103 | nightly: dist | |||
|
104 | rsync -avH --delete dist/ ipython:www/doc/nightly No newline at end of file |
@@ -1,74 +1,79 b'' | |||||
1 | #!/usr/bin/env python |
|
1 | #!/usr/bin/env python | |
2 | """Script to auto-generate our API docs. |
|
2 | """Script to auto-generate our API docs. | |
3 | """ |
|
3 | """ | |
4 | # stdlib imports |
|
4 | # stdlib imports | |
5 | import os |
|
5 | import os | |
6 | import sys |
|
6 | import sys | |
7 |
|
7 | |||
8 | # local imports |
|
8 | # local imports | |
9 | sys.path.append(os.path.abspath('sphinxext')) |
|
9 | sys.path.append(os.path.abspath('sphinxext')) | |
10 | from apigen import ApiDocWriter |
|
10 | from apigen import ApiDocWriter | |
11 |
|
11 | |||
12 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
13 | if __name__ == '__main__': |
|
13 | if __name__ == '__main__': | |
14 | pjoin = os.path.join |
|
14 | pjoin = os.path.join | |
15 | package = 'IPython' |
|
15 | package = 'IPython' | |
16 | outdir = pjoin('source','api','generated') |
|
16 | outdir = pjoin('source','api','generated') | |
17 | docwriter = ApiDocWriter(package,rst_extension='.txt') |
|
17 | docwriter = ApiDocWriter(package,rst_extension='.txt') | |
18 | # You have to escape the . here because . is a special char for regexps. |
|
18 | # You have to escape the . here because . is a special char for regexps. | |
19 | # You must do make clean if you change this! |
|
19 | # You must do make clean if you change this! | |
20 | docwriter.package_skip_patterns += [r'\.fixes$', |
|
20 | docwriter.package_skip_patterns += [r'\.fixes$', | |
21 | r'\.external$', |
|
21 | r'\.external$', | |
22 | r'\.extensions', |
|
22 | r'\.extensions', | |
23 | r'\.kernel\.config', |
|
23 | r'\.kernel\.config', | |
24 | r'\.attic', |
|
24 | r'\.attic', | |
25 | r'\.quarantine', |
|
25 | r'\.quarantine', | |
26 | r'\.deathrow', |
|
26 | r'\.deathrow', | |
27 | r'\.config\.default', |
|
27 | r'\.config\.default', | |
28 | r'\.config\.profile', |
|
28 | r'\.config\.profile', | |
29 | r'\.frontend', |
|
29 | r'\.frontend', | |
30 | r'\.gui' |
|
30 | r'\.gui', | |
|
31 | # For now, the zmq code has | |||
|
32 | # unconditional top-level code so it's | |||
|
33 | # not import safe. This needs fixing | |||
|
34 | # soon. | |||
|
35 | r'\.zmq', | |||
31 | ] |
|
36 | ] | |
32 |
|
37 | |||
33 | docwriter.module_skip_patterns += [ r'\.core\.fakemodule', |
|
38 | docwriter.module_skip_patterns += [ r'\.core\.fakemodule', | |
34 |
|
39 | |||
35 | # XXX These need fixing, disabling for |
|
40 | # XXX These need fixing, disabling for | |
36 | # now but we need to figure out why |
|
41 | # now but we need to figure out why | |
37 | # they are breaking. Error from sphinx |
|
42 | # they are breaking. Error from sphinx | |
38 | # for each group copied below |
|
43 | # for each group copied below | |
39 |
|
44 | |||
40 | # AttributeError: __abstractmethods__ |
|
45 | # AttributeError: __abstractmethods__ | |
41 | r'\.core\.component', |
|
46 | r'\.core\.component', | |
42 | r'\.utils\.traitlets', |
|
47 | r'\.utils\.traitlets', | |
43 |
|
48 | |||
44 | # AttributeError: __provides__ |
|
49 | # AttributeError: __provides__ | |
45 | r'\.kernel\.clusterdir', |
|
50 | r'\.kernel\.clusterdir', | |
46 | r'\.kernel\.configobjfactory', |
|
51 | r'\.kernel\.configobjfactory', | |
47 | r'\.kernel\.fcutil', |
|
52 | r'\.kernel\.fcutil', | |
48 | r'\.kernel\.ipcontrollerapp', |
|
53 | r'\.kernel\.ipcontrollerapp', | |
49 | r'\.kernel\.launcher', |
|
54 | r'\.kernel\.launcher', | |
50 | r'\.kernel\.task', |
|
55 | r'\.kernel\.task', | |
51 | r'\.kernel\.winhpcjob', |
|
56 | r'\.kernel\.winhpcjob', | |
52 | r'\.testing\.util', |
|
57 | r'\.testing\.util', | |
53 |
|
58 | |||
54 | # Keeping these disabled is OK |
|
59 | # Keeping these disabled is OK | |
55 | r'\.cocoa', |
|
60 | r'\.cocoa', | |
56 | r'\.ipdoctest', |
|
61 | r'\.ipdoctest', | |
57 | r'\.Gnuplot', |
|
62 | r'\.Gnuplot', | |
58 | r'\.frontend\.process\.winprocess', |
|
63 | r'\.frontend\.process\.winprocess', | |
59 | r'\.Shell', |
|
64 | r'\.Shell', | |
60 | ] |
|
65 | ] | |
61 |
|
66 | |||
62 | # If we don't have pexpect, we can't load irunner, so skip any code that |
|
67 | # If we don't have pexpect, we can't load irunner, so skip any code that | |
63 | # depends on it |
|
68 | # depends on it | |
64 | try: |
|
69 | try: | |
65 | import pexpect |
|
70 | import pexpect | |
66 | except ImportError: |
|
71 | except ImportError: | |
67 | docwriter.module_skip_patterns += [r'\.lib\.irunner', |
|
72 | docwriter.module_skip_patterns += [r'\.lib\.irunner', | |
68 | r'\.testing\.mkdoctests'] |
|
73 | r'\.testing\.mkdoctests'] | |
69 | # Now, generate the outputs |
|
74 | # Now, generate the outputs | |
70 | docwriter.write_api_docs(outdir) |
|
75 | docwriter.write_api_docs(outdir) | |
71 | docwriter.write_index(outdir, 'gen', |
|
76 | docwriter.write_index(outdir, 'gen', | |
72 | relative_to = pjoin('source','api') |
|
77 | relative_to = pjoin('source','api') | |
73 | ) |
|
78 | ) | |
74 | print '%d files written' % len(docwriter.written_modules) |
|
79 | print '%d files written' % len(docwriter.written_modules) |
This diff has been collapsed as it changes many lines, (576 lines changed) Show them Hide them | |||||
@@ -1,284 +1,560 b'' | |||||
1 | ===================== |
|
1 | ====================== | |
2 | Message Specification |
|
2 | Messaging in IPython | |
3 | ===================== |
|
3 | ====================== | |
4 |
|
||||
5 | Note: not all of these have yet been fully fleshed out, but the key ones are, |
|
|||
6 | see kernel and frontend files for actual implementation details. |
|
|||
7 |
|
||||
8 | Messages are dicts of dicts with string keys and values that are reasonably |
|
|||
9 | representable in JSON. Our current implementation uses JSON explicitly as its |
|
|||
10 | message format, but this shouldn't be considered a permanent feature. As we've |
|
|||
11 | discovered that JSON has non-trivial performance issues due to excessive |
|
|||
12 | copying, we may in the future move to a pure pickle-based raw message format. |
|
|||
13 | However, it should be possible to easily convert from the raw objects to JSON, |
|
|||
14 | since we may have non-python clients (e.g. a web frontend). As long as it's |
|
|||
15 | easy to make a JSON version of the objects that is a faithful representation of |
|
|||
16 | all the data, we can communicate with such clients. |
|
|||
17 |
|
4 | |||
18 |
|
5 | |||
|
6 | Introduction | |||
|
7 | ============ | |||
|
8 | ||||
|
9 | This document explains the basic communications design and messaging | |||
|
10 | specification for how the various IPython objects interact over a network | |||
|
11 | transport. The current implementation uses the ZeroMQ_ library for messaging | |||
|
12 | within and between hosts. | |||
|
13 | ||||
|
14 | .. Note:: | |||
|
15 | ||||
|
16 | This document should be considered the authoritative description of the | |||
|
17 | IPython messaging protocol, and all developers are strongly encouraged to | |||
|
18 | keep it updated as the implementation evolves, so that we have a single | |||
|
19 | common reference for all protocol details. | |||
|
20 | ||||
|
21 | The basic design is explained in the following diagram: | |||
|
22 | ||||
|
23 | .. image:: frontend-kernel.png | |||
|
24 | :width: 450px | |||
|
25 | :alt: IPython kernel/frontend messaging architecture. | |||
|
26 | :align: center | |||
|
27 | :target: ../_images/frontend-kernel.png | |||
|
28 | ||||
|
29 | A single kernel can be simultaneously connected to one or more frontends. The | |||
|
30 | kernel has three sockets that serve the following functions: | |||
|
31 | ||||
|
32 | 1. REQ: this socket is connected to a *single* frontend at a time, and it allows | |||
|
33 | the kernel to request input from a frontend when :func:`raw_input` is called. | |||
|
34 | The frontend holding the matching REP socket acts as a 'virtual keyboard' | |||
|
35 | for the kernel while this communication is happening (illustrated in the | |||
|
36 | figure by the black outline around the central keyboard). In practice, | |||
|
37 | frontends may display such kernel requests using a special input widget or | |||
|
38 | otherwise indicating that the user is to type input for the kernel instead | |||
|
39 | of normal commands in the frontend. | |||
|
40 | ||||
|
41 | 2. XREP: this single sockets allows multiple incoming connections from | |||
|
42 | frontends, and this is the socket where requests for code execution, object | |||
|
43 | information, prompts, etc. are made to the kernel by any frontend. The | |||
|
44 | communication on this socket is a sequence of request/reply actions from | |||
|
45 | each frontend and the kernel. | |||
|
46 | ||||
|
47 | 3. PUB: this socket is the 'broadcast channel' where the kernel publishes all | |||
|
48 | side effects (stdout, stderr, etc.) as well as the requests coming from any | |||
|
49 | client over the XREP socket and its own requests on the REP socket. There | |||
|
50 | are a number of actions in Python which generate side effects: :func:`print` | |||
|
51 | writes to ``sys.stdout``, errors generate tracebacks, etc. Additionally, in | |||
|
52 | a multi-client scenario, we want all frontends to be able to know what each | |||
|
53 | other has sent to the kernel (this can be useful in collaborative scenarios, | |||
|
54 | for example). This socket allows both side effects and the information | |||
|
55 | about communications taking place with one client over the XREQ/XREP channel | |||
|
56 | to be made available to all clients in a uniform manner. | |||
|
57 | ||||
|
58 | All messages are tagged with enough information (details below) for clients | |||
|
59 | to know which messages come from their own interaction with the kernel and | |||
|
60 | which ones are from other clients, so they can display each type | |||
|
61 | appropriately. | |||
|
62 | ||||
|
63 | The actual format of the messages allowed on each of these channels is | |||
|
64 | specified below. Messages are dicts of dicts with string keys and values that | |||
|
65 | are reasonably representable in JSON. Our current implementation uses JSON | |||
|
66 | explicitly as its message format, but this shouldn't be considered a permanent | |||
|
67 | feature. As we've discovered that JSON has non-trivial performance issues due | |||
|
68 | to excessive copying, we may in the future move to a pure pickle-based raw | |||
|
69 | message format. However, it should be possible to easily convert from the raw | |||
|
70 | objects to JSON, since we may have non-python clients (e.g. a web frontend). | |||
|
71 | As long as it's easy to make a JSON version of the objects that is a faithful | |||
|
72 | representation of all the data, we can communicate with such clients. | |||
|
73 | ||||
|
74 | .. Note:: | |||
|
75 | ||||
|
76 | Not all of these have yet been fully fleshed out, but the key ones are, see | |||
|
77 | kernel and frontend files for actual implementation details. | |||
|
78 | ||||
|
79 | ||||
19 | Python functional API |
|
80 | Python functional API | |
20 | ===================== |
|
81 | ===================== | |
21 |
|
82 | |||
22 | As messages are dicts, they map naturally to a ``func(**kw)`` call form. We |
|
83 | As messages are dicts, they map naturally to a ``func(**kw)`` call form. We | |
23 | should develop, at a few key points, functional forms of all the requests that |
|
84 | should develop, at a few key points, functional forms of all the requests that | |
24 | take arguments in this manner and automatically construct the necessary dict |
|
85 | take arguments in this manner and automatically construct the necessary dict | |
25 | for sending. |
|
86 | for sending. | |
26 |
|
87 | |||
27 |
|
88 | |||
28 | General Message Format |
|
89 | General Message Format | |
29 | ===================== |
|
|||
30 |
|
||||
31 | General message format:: |
|
|||
32 |
|
||||
33 | { |
|
|||
34 | header : { 'msg_id' : 10, # start with 0 |
|
|||
35 | 'username' : 'name', |
|
|||
36 | 'session' : uuid |
|
|||
37 | }, |
|
|||
38 | parent_header : dict, |
|
|||
39 | msg_type : 'string_message_type', |
|
|||
40 | content : blackbox_dict , # Must be a dict |
|
|||
41 | } |
|
|||
42 |
|
||||
43 |
|
||||
44 | Request/Reply going from kernel for stdin |
|
|||
45 | ========================================= |
|
|||
46 |
|
||||
47 | This is a socket that goes in the opposite direction: from the kernel to a |
|
|||
48 | *single* frontend, and its purpose is to allow ``raw_input`` and similar |
|
|||
49 | operations that read from ``sys.stdin`` on the kernel to be fulfilled by the |
|
|||
50 | client. For now we will keep these messages as simple as possible, since they |
|
|||
51 | basically only mean to convey the ``raw_input(prompt)`` call. |
|
|||
52 |
|
||||
53 | Message type: 'input_request':: |
|
|||
54 |
|
||||
55 | content = { prompt : string } |
|
|||
56 |
|
||||
57 | Message type: 'input_reply':: |
|
|||
58 |
|
||||
59 | content = { value : string } |
|
|||
60 |
|
||||
61 |
|
||||
62 | Side effect: (PUB/SUB) |
|
|||
63 | ====================== |
|
90 | ====================== | |
64 |
|
91 | |||
65 | Message type: 'stream':: |
|
92 | All messages send or received by any IPython process should have the following | |
66 |
|
93 | generic structure:: | ||
67 | content = { |
|
|||
68 | name : 'stdout', |
|
|||
69 | data : 'blob', |
|
|||
70 | } |
|
|||
71 |
|
||||
72 | When a kernel receives a raw_input call, it should also broadcast it on the pub |
|
|||
73 | socket with the names 'stdin' and 'stdin_reply'. This will allow other clients |
|
|||
74 | to monitor/display kernel interactions and possibly replay them to their user |
|
|||
75 | or otherwise expose them. |
|
|||
76 |
|
94 | |||
77 | Message type: 'pyin':: |
|
95 | { | |
78 |
|
96 | # The message header contains a pair of unique identifiers for the | ||
79 | content = { |
|
97 | # originating session and the actual message id, in addition to the | |
80 | code = 'x=1', |
|
98 | # username for the process that generated the message. This is useful in | |
81 | } |
|
99 | # collaborative settings where multiple users may be interacting with the | |
82 |
|
100 | # same kernel simultaneously, so that frontends can label the various | ||
83 | Message type: 'pyout':: |
|
101 | # messages in a meaningful way. | |
|
102 | 'header' : { 'msg_id' : uuid, | |||
|
103 | 'username' : str, | |||
|
104 | 'session' : uuid | |||
|
105 | }, | |||
84 |
|
106 | |||
85 | content = { |
|
107 | # In a chain of messages, the header from the parent is copied so that | |
86 | data = 'repr(obj)', |
|
108 | # clients can track where messages come from. | |
87 | prompt_number = 10 |
|
109 | 'parent_header' : dict, | |
88 | } |
|
|||
89 |
|
110 | |||
90 | Message type: 'pyerr':: |
|
111 | # All recognized message type strings are listed below. | |
|
112 | 'msg_type' : str, | |||
91 |
|
113 | |||
92 | content = { |
|
114 | # The actual content of the message must be a dict, whose structure | |
93 | # Same as the data payload of a code execute_reply, minus the 'status' |
|
115 | # depends on the message type.x | |
94 | # field. See below. |
|
116 | 'content' : dict, | |
95 | } |
|
117 | } | |
96 |
|
118 | |||
97 | When the kernel has an unexpected exception, caught by the last-resort |
|
119 | For each message type, the actual content will differ and all existing message | |
98 | sys.excepthook, we should broadcast the crash handler's output before exiting. |
|
120 | types are specified in what follows of this document. | |
99 | This will allow clients to notice that a kernel died, inform the user and |
|
|||
100 | propose further actions. |
|
|||
101 |
|
121 | |||
102 | Message type: 'crash':: |
|
|||
103 |
|
122 | |||
104 | content = { |
|
123 | Messages on the XREP/XREQ socket | |
105 | traceback : 'full traceback', |
|
124 | ================================ | |
106 | exc_type : 'TypeError', |
|
|||
107 | exc_value : 'msg' |
|
|||
108 | } |
|
|||
109 |
|
125 | |||
110 |
|
126 | .. _execute: | ||
111 | Other potential message types, currently unimplemented, listed below as ideas. |
|
|||
112 |
|
||||
113 | Message type: 'file':: |
|
|||
114 | content = { |
|
|||
115 | path : 'cool.jpg', |
|
|||
116 | mimetype : string |
|
|||
117 | data : 'blob' |
|
|||
118 | } |
|
|||
119 |
|
||||
120 |
|
||||
121 | Request/Reply |
|
|||
122 | ============= |
|
|||
123 |
|
127 | |||
124 | Execute |
|
128 | Execute | |
125 | ------- |
|
129 | ------- | |
126 |
|
130 | |||
127 | The execution request contains a single string, but this may be a multiline |
|
131 | The execution request contains a single string, but this may be a multiline | |
128 | string. The kernel is responsible for splitting this into possibly more than |
|
132 | string. The kernel is responsible for splitting this into possibly more than | |
129 | one block and deciding whether to compile these in 'single' or 'exec' mode. |
|
133 | one block and deciding whether to compile these in 'single' or 'exec' mode. | |
130 | We're still sorting out this policy. The current inputsplitter is capable of |
|
134 | We're still sorting out this policy. The current inputsplitter is capable of | |
131 | splitting the input for blocks that can all be run as 'single', but in the long |
|
135 | splitting the input for blocks that can all be run as 'single', but in the long | |
132 | run it may prove cleaner to only use 'single' mode for truly single-line |
|
136 | run it may prove cleaner to only use 'single' mode for truly single-line | |
133 | inputs, and run all multiline input in 'exec' mode. This would preserve the |
|
137 | inputs, and run all multiline input in 'exec' mode. This would preserve the | |
134 | natural behavior of single-line inputs while allowing long cells to behave more |
|
138 | natural behavior of single-line inputs while allowing long cells to behave more | |
135 | likea a script. Some thought is still required here... |
|
139 | likea a script. This design will be refined as we complete the implementation. | |
136 |
|
140 | |||
137 |
Message type: |
|
141 | Message type: ``execute_request``:: | |
138 |
|
142 | |||
139 | content = { |
|
143 | content = { | |
140 | code : 'a = 10', |
|
144 | # Source code to be executed by the kernel, one or more lines. | |
|
145 | 'code' : str, | |||
|
146 | ||||
|
147 | # A boolean flag which, if True, signals the kernel to execute this | |||
|
148 | # code as quietly as possible. This means that the kernel will compile | |||
|
149 | # the code with 'exec' instead of 'single' (so sys.displayhook will not | |||
|
150 | # fire), and will *not*: | |||
|
151 | # - broadcast exceptions on the PUB socket | |||
|
152 | # - do any logging | |||
|
153 | # - populate any history | |||
|
154 | # The default is False. | |||
|
155 | 'silent' : bool, | |||
141 | } |
|
156 | } | |
142 |
|
157 | |||
143 | Reply: |
|
158 | Upon execution, the kernel *always* sends a reply, with a status code | |
|
159 | indicating what happened and additional data depending on the outcome. | |||
144 |
|
160 | |||
145 |
Message type: |
|
161 | Message type: ``execute_reply``:: | |
146 |
|
162 | |||
147 | content = { |
|
163 | content = { | |
148 |
|
|
164 | # One of: 'ok' OR 'error' OR 'abort' | |
|
165 | 'status' : str, | |||
|
166 | ||||
149 | # Any additional data depends on status value |
|
167 | # Any additional data depends on status value | |
150 | } |
|
168 | } | |
151 |
|
169 | |||
152 | When status is 'ok', the following extra fields are present:: |
|
170 | When status is 'ok', the following extra fields are present:: | |
153 |
|
171 | |||
154 | { |
|
172 | { | |
155 | # This has the same structure as the output of a prompt request, but is |
|
173 | # This has the same structure as the output of a prompt request, but is | |
156 | # for the client to set up the *next* prompt (with identical limitations |
|
174 | # for the client to set up the *next* prompt (with identical limitations | |
157 | # to a prompt request) |
|
175 | # to a prompt request) | |
158 | 'next_prompt' : { |
|
176 | 'next_prompt' : { | |
159 |
prompt_string : str |
|
177 | 'prompt_string' : str, | |
160 | prompt_number : int |
|
178 | 'prompt_number' : int, | |
161 | } |
|
179 | }, | |
162 |
|
180 | |||
163 | # The prompt number of the actual execution for this code, which may be |
|
181 | # The prompt number of the actual execution for this code, which may be | |
164 | # different from the one used when the code was typed, which was the |
|
182 | # different from the one used when the code was typed, which was the | |
165 | # 'next_prompt' field of the *previous* request. They will differ in the |
|
183 | # 'next_prompt' field of the *previous* request. They will differ in the | |
166 | # case where there is more than one client talking simultaneously to a |
|
184 | # case where there is more than one client talking simultaneously to a | |
167 | # kernel, since the numbers can go out of sync. GUI clients can use this |
|
185 | # kernel, since the numbers can go out of sync. GUI clients can use this | |
168 | # to correct the previously written number in-place, terminal ones may |
|
186 | # to correct the previously written number in-place, terminal ones may | |
169 | # re-print a corrected one if desired. |
|
187 | # re-print a corrected one if desired. | |
170 |
'prompt_number' : |
|
188 | 'prompt_number' : int, | |
171 |
|
189 | |||
172 | # The kernel will often transform the input provided to it. This |
|
190 | # The kernel will often transform the input provided to it. This | |
173 | # contains the transformed code, which is what was actually executed. |
|
191 | # contains the transformed code, which is what was actually executed. | |
174 |
'transformed_code' : |
|
192 | 'transformed_code' : str, | |
175 |
|
193 | |||
176 | # This 'payload' needs a bit more thinking. The basic idea is that |
|
194 | # The execution payload is a dict with string keys that may have been | |
177 | # certain actions will want to return additional information, such as |
|
195 | # produced by the code being executed. It is retrieved by the kernel at | |
178 | # magics producing data output for display by the clients. We may need |
|
196 | # the end of the execution and sent back to the front end, which can take | |
179 | # to define a few types of payload, or specify a syntax for the, not sure |
|
197 | # action on it as needed. See main text for further details. | |
180 | # yet... FIXME here. |
|
198 | 'payload' : dict, | |
181 | 'payload' : things from page(), for example. |
|
|||
182 | } |
|
199 | } | |
183 |
|
200 | |||
|
201 | .. admonition:: Execution payloads | |||
|
202 | ||||
|
203 | The notion of an 'execution payload' is different from a return value of a | |||
|
204 | given set of code, which normally is just displayed on the pyout stream | |||
|
205 | through the PUB socket. The idea of a payload is to allow special types of | |||
|
206 | code, typically magics, to populate a data container in the IPython kernel | |||
|
207 | that will be shipped back to the caller via this channel. The kernel will | |||
|
208 | have an API for this, probably something along the lines of:: | |||
|
209 | ||||
|
210 | ip.exec_payload_add(key, value) | |||
|
211 | ||||
|
212 | though this API is still in the design stages. The data returned in this | |||
|
213 | payload will allow frontends to present special views of what just happened. | |||
|
214 | ||||
|
215 | ||||
184 | When status is 'error', the following extra fields are present:: |
|
216 | When status is 'error', the following extra fields are present:: | |
185 |
|
217 | |||
186 | { |
|
218 | { | |
187 |
|
|
219 | 'exc_name' : str, # Exception name, as a string | |
188 |
evalue : str # |
|
220 | 'exc_value' : str, # Exception value, as a string | |
189 |
|
221 | |||
190 | # The traceback will contain a list of frames, represented each as a |
|
222 | # The traceback will contain a list of frames, represented each as a | |
191 | # string. For now we'll stick to the existing design of ultraTB, which |
|
223 | # string. For now we'll stick to the existing design of ultraTB, which | |
192 | # controls exception level of detail statefully. But eventually we'll |
|
224 | # controls exception level of detail statefully. But eventually we'll | |
193 | # want to grow into a model where more information is collected and |
|
225 | # want to grow into a model where more information is collected and | |
194 | # packed into the traceback object, with clients deciding how little or |
|
226 | # packed into the traceback object, with clients deciding how little or | |
195 | # how much of it to unpack. But for now, let's start with a simple list |
|
227 | # how much of it to unpack. But for now, let's start with a simple list | |
196 | # of strings, since that requires only minimal changes to ultratb as |
|
228 | # of strings, since that requires only minimal changes to ultratb as | |
197 | # written. |
|
229 | # written. | |
198 |
traceback : list |
|
230 | 'traceback' : list, | |
199 | } |
|
231 | } | |
200 |
|
232 | |||
201 |
|
233 | |||
202 | When status is 'abort', there are for now no additional data fields. |
|
234 | When status is 'abort', there are for now no additional data fields. This | |
|
235 | happens when the kernel was interrupted by a signal. | |||
203 |
|
236 | |||
204 |
|
237 | |||
205 | Prompt |
|
238 | Prompt | |
206 | ------ |
|
239 | ------ | |
207 |
|
240 | |||
208 | A simple request for a current prompt string. |
|
241 | A simple request for a current prompt string. | |
209 |
|
242 | |||
210 |
Message type: |
|
243 | Message type: ``prompt_request``:: | |
211 |
|
244 | |||
212 | content = {} |
|
245 | content = {} | |
213 |
|
246 | |||
214 | In the reply, the prompt string comes back with the prompt number placeholder |
|
247 | In the reply, the prompt string comes back with the prompt number placeholder | |
215 | *unevaluated*. The message format is: |
|
248 | *unevaluated*. The message format is: | |
216 |
|
249 | |||
217 |
Message type: |
|
250 | Message type: ``prompt_reply``:: | |
218 |
|
251 | |||
219 | content = { |
|
252 | content = { | |
220 |
prompt_string : str |
|
253 | 'prompt_string' : str, | |
221 | prompt_number : int |
|
254 | 'prompt_number' : int, | |
222 | } |
|
255 | } | |
223 |
|
256 | |||
224 | Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but |
|
257 | Clients can produce a prompt with ``prompt_string.format(prompt_number)``, but | |
225 | they should be aware that the actual prompt number for that input could change |
|
258 | they should be aware that the actual prompt number for that input could change | |
226 | later, in the case where multiple clients are interacting with a single |
|
259 | later, in the case where multiple clients are interacting with a single | |
227 | kernel. |
|
260 | kernel. | |
|
261 | ||||
|
262 | ||||
|
263 | Object information | |||
|
264 | ------------------ | |||
|
265 | ||||
|
266 | One of IPython's most used capabilities is the introspection of Python objects | |||
|
267 | in the user's namespace, typically invoked via the ``?`` and ``??`` characters | |||
|
268 | (which in reality are shorthands for the ``%pinfo`` magic). This is used often | |||
|
269 | enough that it warrants an explicit message type, especially because frontends | |||
|
270 | may want to get object information in response to user keystrokes (like Tab or | |||
|
271 | F1) besides from the user explicitly typing code like ``x??``. | |||
|
272 | ||||
|
273 | Message type: ``object_info_request``:: | |||
|
274 | ||||
|
275 | content = { | |||
|
276 | # The (possibly dotted) name of the object to be searched in all | |||
|
277 | # relevant namespaces | |||
|
278 | 'name' : str, | |||
|
279 | ||||
|
280 | # The level of detail desired. The default (0) is equivalent to typing | |||
|
281 | # 'x?' at the prompt, 1 is equivalent to 'x??'. | |||
|
282 | 'detail_level' : int, | |||
|
283 | } | |||
|
284 | ||||
|
285 | The returned information will be a dictionary with keys very similar to the | |||
|
286 | field names that IPython prints at the terminal. | |||
228 |
|
287 | |||
|
288 | Message type: ``object_info_reply``:: | |||
|
289 | ||||
|
290 | content = { | |||
|
291 | # Flags for magics and system aliases | |||
|
292 | 'ismagic' : bool, | |||
|
293 | 'isalias' : bool, | |||
|
294 | ||||
|
295 | # The name of the namespace where the object was found ('builtin', | |||
|
296 | # 'magics', 'alias', 'interactive', etc.) | |||
|
297 | 'namespace' : str, | |||
|
298 | ||||
|
299 | # The type name will be type.__name__ for normal Python objects, but it | |||
|
300 | # can also be a string like 'Magic function' or 'System alias' | |||
|
301 | 'type_name' : str, | |||
|
302 | ||||
|
303 | 'string_form' : str, | |||
|
304 | ||||
|
305 | # For objects with a __class__ attribute this will be set | |||
|
306 | 'base_class' : str, | |||
|
307 | ||||
|
308 | # For objects with a __len__ attribute this will be set | |||
|
309 | 'length' : int, | |||
|
310 | ||||
|
311 | # If the object is a function, class or method whose file we can find, | |||
|
312 | # we give its full path | |||
|
313 | 'file' : str, | |||
|
314 | ||||
|
315 | # For pure Python callable objects, we can reconstruct the object | |||
|
316 | # definition line which provides its call signature | |||
|
317 | 'definition' : str, | |||
|
318 | ||||
|
319 | # For instances, provide the constructor signature (the definition of | |||
|
320 | # the __init__ method): | |||
|
321 | 'init_definition' : str, | |||
|
322 | ||||
|
323 | # Docstrings: for any object (function, method, module, package) with a | |||
|
324 | # docstring, we show it. But in addition, we may provide additional | |||
|
325 | # docstrings. For example, for instances we will show the constructor | |||
|
326 | # and class docstrings as well, if available. | |||
|
327 | 'docstring' : str, | |||
|
328 | ||||
|
329 | # For instances, provide the constructor and class docstrings | |||
|
330 | 'init_docstring' : str, | |||
|
331 | 'class_docstring' : str, | |||
|
332 | ||||
|
333 | # If detail_level was 1, we also try to find the source code that | |||
|
334 | # defines the object, if possible. The string 'None' will indicate | |||
|
335 | # that no source was found. | |||
|
336 | 'source' : str, | |||
|
337 | } | |||
|
338 | ||||
229 |
|
339 | |||
230 | Complete |
|
340 | Complete | |
231 | -------- |
|
341 | -------- | |
232 |
|
342 | |||
233 |
Message type: |
|
343 | Message type: ``complete_request``:: | |
234 |
|
344 | |||
235 | content = { |
|
345 | content = { | |
236 | text : 'a.f', # complete on this |
|
346 | # The text to be completed, such as 'a.is' | |
237 | line : 'print a.f' # full line |
|
347 | 'text' : str, | |
|
348 | ||||
|
349 | # The full line, such as 'print a.is'. This allows completers to | |||
|
350 | # make decisions that may require information about more than just the | |||
|
351 | # current word. | |||
|
352 | 'line' : str, | |||
238 | } |
|
353 | } | |
239 |
|
354 | |||
240 |
Message type: |
|
355 | Message type: ``complete_reply``:: | |
241 |
|
356 | |||
242 | content = { |
|
357 | content = { | |
243 | matches : ['a.foo', 'a.bar'] |
|
358 | # The list of all matches to the completion request, such as | |
|
359 | # ['a.isalnum', 'a.isalpha'] for the above example. | |||
|
360 | 'matches' : list | |||
244 | } |
|
361 | } | |
245 |
|
362 | |||
246 |
|
363 | |||
247 | History |
|
364 | History | |
248 | ------- |
|
365 | ------- | |
249 |
|
366 | |||
250 | For clients to explicitly request history from a kernel |
|
367 | For clients to explicitly request history from a kernel. The kernel has all | |
|
368 | the actual execution history stored in a single location, so clients can | |||
|
369 | request it from the kernel when needed. | |||
251 |
|
370 | |||
252 |
Message type: |
|
371 | Message type: ``history_request``:: | |
253 |
|
372 | |||
254 | content = { |
|
373 | content = { | |
255 | output : boolean. If true, also return output history in the resulting |
|
374 | ||
256 | dict. |
|
375 | # If true, also return output history in the resulting dict. | |
257 |
|
376 | 'output' : bool, | ||
258 | range : optional. A number, a pair of numbers, 'all' |
|
377 | ||
259 | If not given, last 40 are returned. |
|
378 | # This parameter can be one of: A number, a pair of numbers, 'all' | |
260 | - number n: return the last n entries. |
|
379 | # If not given, last 40 are returned. | |
261 | - pair n1, n2: return entries in the range(n1, n2). |
|
380 | # - number n: return the last n entries. | |
262 | - 'all': return all history |
|
381 | # - pair n1, n2: return entries in the range(n1, n2). | |
263 |
|
382 | # - 'all': return all history | ||
264 | filter : optional, string |
|
383 | 'range' : n or (n1, n2) or 'all', | |
265 | If given, treated as a regular expression and only matching entries are |
|
384 | ||
266 | returned. re.search() is used to find matches. |
|
385 | # If a filter is given, it is treated as a regular expression and only | |
|
386 | # matching entries are returned. re.search() is used to find matches. | |||
|
387 | 'filter' : str, | |||
267 | } |
|
388 | } | |
268 |
|
389 | |||
269 |
Message type: |
|
390 | Message type: ``history_reply``:: | |
270 |
|
391 | |||
271 | content = { |
|
392 | content = { | |
272 |
|
|
393 | # A list of (number, input) pairs | |
273 | output : list of pairs (number, output). Empty if not requested. |
|
394 | 'input' : list, | |
|
395 | ||||
|
396 | # A list of (number, output) pairs | |||
|
397 | 'output' : list, | |||
274 | } |
|
398 | } | |
275 |
|
399 | |||
276 |
|
400 | |||
277 | Control |
|
401 | Control | |
278 | ------- |
|
402 | ------- | |
279 |
|
403 | |||
280 |
Message type: |
|
404 | Message type: ``heartbeat``:: | |
|
405 | ||||
|
406 | content = { | |||
|
407 | # FIXME - unfinished | |||
|
408 | } | |||
|
409 | ||||
|
410 | ||||
|
411 | Messages on the PUB/SUB socket | |||
|
412 | ============================== | |||
|
413 | ||||
|
414 | Streams (stdout, stderr, etc) | |||
|
415 | ------------------------------ | |||
|
416 | ||||
|
417 | Message type: ``stream``:: | |||
|
418 | ||||
|
419 | content = { | |||
|
420 | # The name of the stream is one of 'stdin', 'stdout', 'stderr' | |||
|
421 | 'name' : str, | |||
|
422 | ||||
|
423 | # The data is an arbitrary string to be written to that stream | |||
|
424 | 'data' : str, | |||
|
425 | } | |||
|
426 | ||||
|
427 | When a kernel receives a raw_input call, it should also broadcast it on the pub | |||
|
428 | socket with the names 'stdin' and 'stdin_reply'. This will allow other clients | |||
|
429 | to monitor/display kernel interactions and possibly replay them to their user | |||
|
430 | or otherwise expose them. | |||
|
431 | ||||
|
432 | Python inputs | |||
|
433 | ------------- | |||
|
434 | ||||
|
435 | These messages are the re-broadcast of the ``execute_request``. | |||
|
436 | ||||
|
437 | Message type: ``pyin``:: | |||
|
438 | ||||
|
439 | content = { | |||
|
440 | # Source code to be executed, one or more lines | |||
|
441 | 'code' : str | |||
|
442 | } | |||
|
443 | ||||
|
444 | Python outputs | |||
|
445 | -------------- | |||
|
446 | ||||
|
447 | When Python produces output from code that has been compiled in with the | |||
|
448 | 'single' flag to :func:`compile`, any expression that produces a value (such as | |||
|
449 | ``1+1``) is passed to ``sys.displayhook``, which is a callable that can do with | |||
|
450 | this value whatever it wants. The default behavior of ``sys.displayhook`` in | |||
|
451 | the Python interactive prompt is to print to ``sys.stdout`` the :func:`repr` of | |||
|
452 | the value as long as it is not ``None`` (which isn't printed at all). In our | |||
|
453 | case, the kernel instantiates as ``sys.displayhook`` an object which has | |||
|
454 | similar behavior, but which instead of printing to stdout, broadcasts these | |||
|
455 | values as ``pyout`` messages for clients to display appropriately. | |||
|
456 | ||||
|
457 | Message type: ``pyout``:: | |||
|
458 | ||||
|
459 | content = { | |||
|
460 | # The data is typically the repr() of the object. | |||
|
461 | 'data' : str, | |||
|
462 | ||||
|
463 | # The prompt number for this execution is also provided so that clients | |||
|
464 | # can display it, since IPython automatically creates variables called | |||
|
465 | # _N (for prompt N). | |||
|
466 | 'prompt_number' : int, | |||
|
467 | } | |||
|
468 | ||||
|
469 | Python errors | |||
|
470 | ------------- | |||
|
471 | ||||
|
472 | When an error occurs during code execution | |||
|
473 | ||||
|
474 | Message type: ``pyerr``:: | |||
|
475 | ||||
|
476 | content = { | |||
|
477 | # Similar content to the execute_reply messages for the 'error' case, | |||
|
478 | # except the 'status' field is omitted. | |||
|
479 | } | |||
|
480 | ||||
|
481 | Kernel crashes | |||
|
482 | -------------- | |||
|
483 | ||||
|
484 | When the kernel has an unexpected exception, caught by the last-resort | |||
|
485 | sys.excepthook, we should broadcast the crash handler's output before exiting. | |||
|
486 | This will allow clients to notice that a kernel died, inform the user and | |||
|
487 | propose further actions. | |||
|
488 | ||||
|
489 | Message type: ``crash``:: | |||
281 |
|
490 | |||
282 | content = { |
|
491 | content = { | |
283 | # XXX - unfinished |
|
492 | # Similarly to the 'error' case for execute_reply messages, this will | |
|
493 | # contain exc_name, exc_type and traceback fields. | |||
|
494 | ||||
|
495 | # An additional field with supplementary information such as where to | |||
|
496 | # send the crash message | |||
|
497 | 'info' : str, | |||
284 | } |
|
498 | } | |
|
499 | ||||
|
500 | ||||
|
501 | Future ideas | |||
|
502 | ------------ | |||
|
503 | ||||
|
504 | Other potential message types, currently unimplemented, listed below as ideas. | |||
|
505 | ||||
|
506 | Message type: ``file``:: | |||
|
507 | ||||
|
508 | content = { | |||
|
509 | 'path' : 'cool.jpg', | |||
|
510 | 'mimetype' : str, | |||
|
511 | 'data' : str, | |||
|
512 | } | |||
|
513 | ||||
|
514 | ||||
|
515 | Messages on the REQ/REP socket | |||
|
516 | ============================== | |||
|
517 | ||||
|
518 | This is a socket that goes in the opposite direction: from the kernel to a | |||
|
519 | *single* frontend, and its purpose is to allow ``raw_input`` and similar | |||
|
520 | operations that read from ``sys.stdin`` on the kernel to be fulfilled by the | |||
|
521 | client. For now we will keep these messages as simple as possible, since they | |||
|
522 | basically only mean to convey the ``raw_input(prompt)`` call. | |||
|
523 | ||||
|
524 | Message type: ``input_request``:: | |||
|
525 | ||||
|
526 | content = { 'prompt' : str } | |||
|
527 | ||||
|
528 | Message type: ``input_reply``:: | |||
|
529 | ||||
|
530 | content = { 'value' : str } | |||
|
531 | ||||
|
532 | .. Note:: | |||
|
533 | ||||
|
534 | We do not explicitly try to forward the raw ``sys.stdin`` object, because in | |||
|
535 | practice the kernel should behave like an interactive program. When a | |||
|
536 | program is opened on the console, the keyboard effectively takes over the | |||
|
537 | ``stdin`` file descriptor, and it can't be used for raw reading anymore. | |||
|
538 | Since the IPython kernel effectively behaves like a console program (albeit | |||
|
539 | one whose "keyboard" is actually living in a separate process and | |||
|
540 | transported over the zmq connection), raw ``stdin`` isn't expected to be | |||
|
541 | available. | |||
|
542 | ||||
|
543 | ||||
|
544 | ToDo | |||
|
545 | ==== | |||
|
546 | ||||
|
547 | Missing things include: | |||
|
548 | ||||
|
549 | * Important: finish thinking through the payload concept and API. | |||
|
550 | ||||
|
551 | * Important: ensure that we have a good solution for magics like %edit. It's | |||
|
552 | likely that with the payload concept we can build a full solution, but not | |||
|
553 | 100% clear yet. | |||
|
554 | ||||
|
555 | * Finishing the details of the heartbeat protocol. | |||
|
556 | ||||
|
557 | * Signal handling: specify what kind of information kernel should broadcast (or | |||
|
558 | not) when it receives signals. | |||
|
559 | ||||
|
560 | .. include:: ../links.rst |
@@ -1,72 +1,74 b'' | |||||
1 | .. This (-*- rst -*-) format file contains commonly used link targets |
|
1 | .. This (-*- rst -*-) format file contains commonly used link targets | |
2 | and name substitutions. It may be included in many files, |
|
2 | and name substitutions. It may be included in many files, | |
3 | therefore it should only contain link targets and name |
|
3 | therefore it should only contain link targets and name | |
4 | substitutions. Try grepping for "^\.\. _" to find plausible |
|
4 | substitutions. Try grepping for "^\.\. _" to find plausible | |
5 | candidates for this list. |
|
5 | candidates for this list. | |
6 |
|
6 | |||
7 | NOTE: this file must have an extension *opposite* to that of the main reST |
|
7 | NOTE: this file must have an extension *opposite* to that of the main reST | |
8 | files in the manuals, so that we can include it with ".. include::" |
|
8 | files in the manuals, so that we can include it with ".. include::" | |
9 | directives, but without triggering warnings from Sphinx for not being listed |
|
9 | directives, but without triggering warnings from Sphinx for not being listed | |
10 | in any toctree. Since IPython uses .txt for the main files, this wone will |
|
10 | in any toctree. Since IPython uses .txt for the main files, this wone will | |
11 | use .rst. |
|
11 | use .rst. | |
12 |
|
12 | |||
13 | NOTE: reST targets are |
|
13 | NOTE: reST targets are | |
14 | __not_case_sensitive__, so only one target definition is needed for |
|
14 | __not_case_sensitive__, so only one target definition is needed for | |
15 | ipython, IPython, etc. |
|
15 | ipython, IPython, etc. | |
16 |
|
16 | |||
17 | NOTE: Some of these were taken from the nipy links compendium. |
|
17 | NOTE: Some of these were taken from the nipy links compendium. | |
18 |
|
18 | |||
19 | .. Main IPython links |
|
19 | .. Main IPython links | |
20 | .. _ipython: http://ipython.scipy.org |
|
20 | .. _ipython: http://ipython.scipy.org | |
21 | .. _`ipython manual`: http://ipython.scipy.org/doc/manual/html |
|
21 | .. _`ipython manual`: http://ipython.scipy.org/doc/manual/html | |
22 | .. _ipython_github: http://github.com/ipython/ipython/ |
|
22 | .. _ipython_github: http://github.com/ipython/ipython/ | |
23 | .. _ipython_github_repo: http://github.com/ipython/ipython/ |
|
23 | .. _ipython_github_repo: http://github.com/ipython/ipython/ | |
24 | .. _ipython_downloads: http://ipython.scipy.org/dist |
|
24 | .. _ipython_downloads: http://ipython.scipy.org/dist | |
25 | .. _ipython_pypi: http://pypi.python.org/pypi/ipython |
|
25 | .. _ipython_pypi: http://pypi.python.org/pypi/ipython | |
26 |
|
26 | |||
|
27 | .. _ZeroMQ: http://zeromq.org | |||
|
28 | ||||
27 | .. Documentation tools and related links |
|
29 | .. Documentation tools and related links | |
28 | .. _graphviz: http://www.graphviz.org |
|
30 | .. _graphviz: http://www.graphviz.org | |
29 | .. _Sphinx: http://sphinx.pocoo.org |
|
31 | .. _Sphinx: http://sphinx.pocoo.org | |
30 | .. _`Sphinx reST`: http://sphinx.pocoo.org/rest.html |
|
32 | .. _`Sphinx reST`: http://sphinx.pocoo.org/rest.html | |
31 | .. _sampledoc: http://matplotlib.sourceforge.net/sampledoc |
|
33 | .. _sampledoc: http://matplotlib.sourceforge.net/sampledoc | |
32 | .. _reST: http://docutils.sourceforge.net/rst.html |
|
34 | .. _reST: http://docutils.sourceforge.net/rst.html | |
33 | .. _docutils: http://docutils.sourceforge.net |
|
35 | .. _docutils: http://docutils.sourceforge.net | |
34 | .. _lyx: http://www.lyx.org |
|
36 | .. _lyx: http://www.lyx.org | |
35 | .. _pep8: http://www.python.org/dev/peps/pep-0008 |
|
37 | .. _pep8: http://www.python.org/dev/peps/pep-0008 | |
36 | .. _numpy_coding_guide: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines |
|
38 | .. _numpy_coding_guide: http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines | |
37 |
|
39 | |||
38 | .. Licenses |
|
40 | .. Licenses | |
39 | .. _GPL: http://www.gnu.org/licenses/gpl.html |
|
41 | .. _GPL: http://www.gnu.org/licenses/gpl.html | |
40 | .. _BSD: http://www.opensource.org/licenses/bsd-license.php |
|
42 | .. _BSD: http://www.opensource.org/licenses/bsd-license.php | |
41 | .. _LGPL: http://www.gnu.org/copyleft/lesser.html |
|
43 | .. _LGPL: http://www.gnu.org/copyleft/lesser.html | |
42 |
|
44 | |||
43 | .. Other python projects |
|
45 | .. Other python projects | |
44 | .. _numpy: http://numpy.scipy.org |
|
46 | .. _numpy: http://numpy.scipy.org | |
45 | .. _scipy: http://www.scipy.org |
|
47 | .. _scipy: http://www.scipy.org | |
46 | .. _scipy_conference: http://conference.scipy.org |
|
48 | .. _scipy_conference: http://conference.scipy.org | |
47 | .. _matplotlib: http://matplotlib.sourceforge.net |
|
49 | .. _matplotlib: http://matplotlib.sourceforge.net | |
48 | .. _pythonxy: http://www.pythonxy.com |
|
50 | .. _pythonxy: http://www.pythonxy.com | |
49 | .. _ETS: http://code.enthought.com/projects/tool-suite.php |
|
51 | .. _ETS: http://code.enthought.com/projects/tool-suite.php | |
50 | .. _EPD: http://www.enthought.com/products/epd.php |
|
52 | .. _EPD: http://www.enthought.com/products/epd.php | |
51 | .. _python: http://www.python.org |
|
53 | .. _python: http://www.python.org | |
52 | .. _mayavi: http://code.enthought.com/projects/mayavi |
|
54 | .. _mayavi: http://code.enthought.com/projects/mayavi | |
53 | .. _sympy: http://code.google.com/p/sympy |
|
55 | .. _sympy: http://code.google.com/p/sympy | |
54 | .. _sage: http://sagemath.org |
|
56 | .. _sage: http://sagemath.org | |
55 | .. _pydy: http://code.google.com/p/pydy |
|
57 | .. _pydy: http://code.google.com/p/pydy | |
56 | .. _vpython: http://vpython.org |
|
58 | .. _vpython: http://vpython.org | |
57 | .. _cython: http://cython.org |
|
59 | .. _cython: http://cython.org | |
58 | .. _software carpentry: http://software-carpentry.org |
|
60 | .. _software carpentry: http://software-carpentry.org | |
59 |
|
61 | |||
60 | .. Not so python scientific computing tools |
|
62 | .. Not so python scientific computing tools | |
61 | .. _matlab: http://www.mathworks.com |
|
63 | .. _matlab: http://www.mathworks.com | |
62 | .. _VTK: http://vtk.org |
|
64 | .. _VTK: http://vtk.org | |
63 |
|
65 | |||
64 | .. Other organizations |
|
66 | .. Other organizations | |
65 | .. _enthought: http://www.enthought.com |
|
67 | .. _enthought: http://www.enthought.com | |
66 | .. _kitware: http://www.kitware.com |
|
68 | .. _kitware: http://www.kitware.com | |
67 | .. _netlib: http://netlib.org |
|
69 | .. _netlib: http://netlib.org | |
68 |
|
70 | |||
69 | .. Other tools and projects |
|
71 | .. Other tools and projects | |
70 | .. _indefero: http://www.indefero.net |
|
72 | .. _indefero: http://www.indefero.net | |
71 | .. _git: http://git-scm.com |
|
73 | .. _git: http://git-scm.com | |
72 | .. _github: http://github.com |
|
74 | .. _github: http://github.com |
General Comments 0
You need to be logged in to leave comments.
Login now