Project

General

Profile

Wiki » History » Version 1

Redmine Admin, 01/04/2017 04:48 PM

1 1 Redmine Admin
{{toc}}
2
3
h1. Services on LINDAT
4
5
# Proxies setup
6
7
I took a liberty to reorganize the way we define the proxies. Each proxy setup has a separate file. All definitions related to that proxy should be in that file and not anywhere else. The proxies definitions are in the directory `proxies-available` and enabled proxies are symlinked in `proxies-enabled`.
8
9
You don't have to do symlinks by hand, but you can use `config_proxies.sh` [script](https://gist.github.com/m1ch4ls/0f5444a8f2d1e06693a4).
10
11
12
```
13
.
14
├── config_proxies.sh
15
├── proxies-available
16
│   ├── cesilko
17
│   ├── ....
18
│   ├── pmltq
19
│   └── treex-web
20
├── proxies-enabled
21
...
22
```
23
24
# Add new proxy
25
26
The file skeleton:
27
28
```nginx
29
# who is responsible
30
# email
31
32
location /services/name {
33
  rewrite /services/name(.*) /proxied/path$1 brea
34
35
  include service_prox
36
  proxy_pass http://ques
37
}
38
```
39
40
## `location`
41
42
The crucial directive here is `location` see [Nginx documentation for details](http://nginx.org/en/docs/http/ngx_http_core_module.html#location).
43
44
The most important part is the way how are the locations matched to urls and which location gets used.
45
46
1. Exact match (note `=`)
47
    ```nginx
48
    location = /services/exact { ... }
49
    ```
50
    If the exact match is found the matching process is terminated and the matched location is used.
51
52
2. The longest matching prefix
53
    ```nginx
54
    location /services/name { config A }
55
    location /services/name/images { config B }
56
    ```
57
    The longest matching prefix is selected and than the matching continues ...
58
59
3. Regular expressions are checked after looking for the longest prefix
60
    ```nginx
61
    # case-sensitive match
62
    location ~ \.(gif)$ { }
63
    # case-insensitive match
64
    location ~* \.(php)$ { }
65
    ```
66
    Regular expressions are checked in the order they appear in the config file. If the regular expression match the first one is used. If not the longest matching substring is used instead.
67
68
4. To get things even more complicated you can use `^~` operator to match the longest prefix and don't do regular expression search. This works in similar way the `=` works.
69
70
## `rewrite`
71
72
Use `rewrite` to change base url if required. [See documentation for details](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite).
73
74
## `proxy_pass`
75
76
Every location defined for service should end with `proxy_pass`. It's recommended to use `include service_prox` to inject useful headers to service endpoint.
77
78
The endpoint definition can be full url or so called `upstream`. The upstreams defined:
79
80
- quest
81
- apache
82
- tomcats
83
84
You can't define `upstream` in service file because it's not included in the context where `upstream` definition is allowed.
85
86
[See documentation](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) for more details.
87
88
# Shibboleth authentication
89
90
Shibboleth authentication only works for `https`. To make things as simple as possible I have made a file you can include to make Shibboleth work out of the box. Otherwise those directives would have to be repeated everytime.
91
92
```nginx
93
more_clear_input_headers 'Variable-*' 'Shib-*' 'Remote-User' 'REMOTE_USER' 'Auth-Type' 'AUTH_TYPE\r
94
95
# Add your attributes here. They get introduced as headers
96
# by the FastCGI authorizer so we must prevent spoofing.
97
more_clear_input_headers 'displayName' 'mail' 'persistent-id\r
98
99
# Require https and will redirect
100
if ($https != "on") {
101
  return 301 https://$http_host$request_ur
102
}
103
104
shib_request /shibauthorize
105
```
106
107
Instead use `include shibboleth_aut`.
108
109
Example:
110
111
```nginx
112
location = /services/name/shibboleth-login-url {
113
  include shibboleth_aut
114
115
  rewrite /services/name(.*) /proxied/path$1 brea
116
117
  include service_prox
118
  proxy_pass http://ques
119
}
120
```
121
122
Note the `=` in `location` directive. This will ensure that Shibboleth authentication will trigger only for this location.
123
124
h1. Python REST 
125
126
Python REST is an implementation of REST (Representational State Transfer) like server written in Python. The python REST server is being implemented by UFAL. The main objectives of this implementation are,
127
128
* to provide a consistent web based interaction to the already available and future NLP tools developed at UFAL.
129
* to aid the web developers by providing them GET/POST like API methods that can be used to access the NLP tools.
130
* to aid the NLP tools developers at UFAL to easily port their stand alone applications to web.
131
132
h1. How to use Python REST
133
134
h2. Clone the REST repository
135
136
The REST server can be run from any machine that supports Python. The REST can made available to the local machine by cloning the source code repository. To clone the repository, you need the @Git@ software. Use the following @Git@ command to populate the repository locally,
137
138
<pre>
139
git clone gitolite@redmine.ms.mff.cuni.cz:lindat/lindat-services.git REST
140
</pre>
141
142
Once the repository is cloned to the REST directory, you will be able to see the following files under the cloned repository,
143
144
<pre>
145
$ cd REST
146
$ ls -F
147
applications/  nohup.out                    pyrest@    settings/
148
cherrypy/      project_settings.py          README     utils.py
149
logs/          project_settings.pyc         _scripts/  utils.pyc
150
main.py*       project_settings.py.example  server/
151
</pre>
152
153
h2. Run the REST server
154
155
To start the REST service, you need to do two major things,
156
157
* *Server Settings*
158
* *Expose Plugins*
159
160
161
h3. *Server settings*
162
163
** at least set the server name and port number in which the REST server should run.
164
165
The server settings should be added to the file @project_settings.py@ at the top-level directory.
166
The minimum settings for the REST service is given below, copy the following contents into @project_settings.py@
167
168
<pre>
169
# coding=utf-8
170
# See main file for licence
171
172
"""
173
  Project specific settings overriding the default ones in `settings` directory.
174
"""
175
176
settings = {
177
178
    "server": {
179
        "host": "127.0.0.1",
180
        "port": 8280,
181
    }
182
}
183
</pre>
184
185
186
h3. *Expose an application/service to web via REST plugins*
187
188
A plugin is a piece of code written in Python (in our case) that interacts with the actual application. The plugin acts as a middle layer that accepts requests from the web and passes the requests to the actual application for processing. Also, the plugin is responsible for obtaining the results returned by the application to the web clients. A plugin essentially processes external HTTP requests for a particular exposed application/service (for example: the NLP application Cesilko) and communicates the results of the application back to the HTTP clients. The plugin offers list of APIs which the HTTP clients can request through HTTP methods (such as GET, POST, DELETE and PUT). 
189
190
** Each plugin defines list of APIs the REST should expose to the outside world for a particular application/service.
191
** Each plugin defines methods for processing the API requests and return the output in JSON format.
192
193
194
There's simple plugin in the @applications/expose_myservice.py@. The @applications/expose_myservice.py@ defines the following things,
195
196
* The name of the service : *myservice*
197
* Provides List of APIs:  
198
199
|_.# |_. API name |_. API parameters |
200
| 1  |   *myapi*    | "list" (required)  | 
201
| 2  |   *version*  |   | 
202
203
204
h3. Start the REST server
205
206
<pre>
207
python pyrest 
208
or
209
python main.py
210
</pre>
211
212
213
h3. Accessing the REST service APIs
214
215
Once the REST server is started, the applications (via plugins in the directory @applications/@) will be exposed via the port as defined in the @project_settings.py@. Then, the applications/services can be accessed via HTTP requests. The examples below show how to access the API methods as defined in @applications/expose_myservice.py@ via HTTP requests.
216
217
218
h4. *"myapi"*
219
220
<pre>
221
http://127.0.0.1:8280/myservice/myapi?list=hello
222
</pre>
223
224
The expected output for the above API request should be,
225
226
<pre>
227
{
228
  "input": "hello", 
229
  "result": "this is an example"
230
}
231
</pre>
232
233
234
h4. *"version"*
235
236
<pre>
237
 http://127.0.0.1:8280/myservice/version
238
</pre>
239
240
The expected output for the above API request should be,
241
242
<pre>
243
{
244
  "version": "myservice version 1"
245
}
246
</pre>
247
248
249
h3. API output format
250
251
At present, the Python REST supports only "JSON":http://en.wikipedia.org/wiki/JSON format. All HTTP GET/POST requests to REST services will be returned via JSON objects. JSON is supported by all web tools, so that the outputs can be used by API developers or others who want to get access to the REST services through web programming tools.
252
253
h1. Detailed Documentation on Python REST
254
255
Here you can read more about the Python REST and how to define/expose your own applications via plugins: [[Python REST detailed documentation]]
256
257
h1. Step-by-Step guide to adding LINDAT/CLARIN service
258
259
h2. [[Cesilko]]