Серверная разработка
Сергей Лихобабин
Техносфера 2014
Что мы научимся делатьОбработка GET и POST запросов
Генерация HTML при помощи шаблонов
Знакомство с Django
Типичные задачисерверной разработкиОтображение и изменение(CRUD) объектов насервере
Предоставление API и взаимодействие c APIдругих сервисов
Языки сервернойразработки
Компилируемые
C/C++ модули к Web серверам
Java
C#
Языки сервернойразработки
Интерпретируемые
Perl
PHP
Ruby
Python
Javascript (NodeJS)
Lua (скриптование веб-серверов)
Языки сервернойразработки
Новая волна
Go
Erlang
Scala
Groovy
ТенденцииФункциональный подход
Асинхронность
Распределенность
Real-Time
Взаимодействие веб-сервера с приложением
CGI
FastCGI
WSGI
Веб-сервер встроенный в приложение
CGI #!/usr/bin/python
import osimport sys
print "Content-type: text/html"print "Status: 200"print ""print "<h1>Hello, world!</h1>"
for k, v in os.environ.items(): print "%s = %s<br>" % (k, v)
print >> sys.stderr, "Nice to meet you"
Заголовки ответаBooking.com HTTP/1.1 200 OK Server: nginx Date: Sun, 27 Oct 2013 10:08:40 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 42510 Connection: keep-alive Cache-Control: private Vary: User-Agent, Accept-Encoding Content-Encoding: gzip X-Recruiting: Like HTTP headers? Come write ours: booking.com/jobs
Заголовки ответаReddit.com HTTP/1.1 200 OKContent-Type: text/html; charset=UTF-8Vary: accept-encodingContent-Encoding: gzipContent-Length: 19879Server: '; DROP TABLE servertypes; --Date: Sun, 27 Oct 2013 10:10:10 GMTConnection: keep-alive
GET параметрыГиперссылка <a href="‘/hello.cgi?name=me&greeting=hello’">Hello!</a>
Переменная окружения QUERY_STRING=name=me&greeting=hello
CGI-скрипт import urlparseparams = urlparse.parse_qs('name=me&greeting=hello')
POST параметрыФорма <form method="”post”" action="”/hello.cgi”"> <input name="”name”" value="”me”/"> <input name="”greeting”" value="”hi”/"> <input type="”submit”/"></form>
CGI скрипт qs = sys.stdin.read()
или cgi.FieldStorage()
Фаилы в POST и Non-ASCII символыMultipart/form-data <form method="”post”" action="”/hello.cgi”" enctype= <input name="”name”" value="”me”/"> <input name="”pic”" type="”file”/"> <input type="”submit”/"></form>
URI encoding <a href="”/hello.cgi?name=%D0%B8%D0%BC%D1%8F”">привет</a>
Обработка параметров import cgiform = cgi.FieldStorage()
# Наличие параметровif not 'name' in form: raise ValidationError('panic')# Валидацияif not re.match('[a-z]+', form['name']): raise ValidationError('panic')# Очисткаstory = re.sub('<[̂>]+>', ' ', form['story'])# Экранированиеstory = form['story']story = story.replace('<', '<')story = story.replace('>', '>')
Переменные окружения HTTP_COOKIEHTTP_USER_AGENTPATH_INFOQUERY_STRINGREMOTE_ADDRREQUEST_METHODSCRIPT_FILENAMESCRIPT_NAME…
WSGI def application(environ, start_response): status = '200 OK' output = 'Hello World!'
response_headers = [ ('Content-type', 'text/plain'), ('Content-Length', str(len(output))) ] start_response(status, response_headers)
return [output]
Gunicorn
Как запустить gunicorn myproject.wsgi:application
АльтернативыuWSGI
Tornado
Werkzeug
Решаемыезадачи
Обработка форм request = Request(environ)error = Noneurl = ''if request.method == 'POST': url = request.form.get('url') if not is_valid_url(url): error = 'Please enter a valid URL' else: short_id = insert_url(url) return redirect('/%s' % short_id)return render_template('new_url.html', error=error, url=url)
Обработка формОтображение формы и изменение через одинобработчик
Сообщение об ошибке и успехе
Проверка данных на сервере и клиенте
Ajax Frontend var request = $.ajax({ url: ”/like/", type: "POST", data: {id : itemId}, dataType: "json"}); request.done(function(result) { if (result.status) { $("#log").html( result.msg ); }}); request.fail(function(jqXHR, textStatus) { alert("Request failed: " + textStatus);})
Ajax Backend import json
request = Request(environ)
json_data = json.dumps({ 'status': True, 'msg': u'Лайк!'})
response = Response(json_data, mimetype='text/plain')return response(environ, start_response)
Хранение данных наклиенте
Что нужно хранить о пользователе
Авторизацию
Временную информацию
Cookie и сессии
Cookie передаются вместе запросом
Сессии хранятся на сервере (в файлах, в базе),идентификатор сессии передаются в куках
Cookie ЗаголовкиSet-Cookie: name=val; path=/; domain=domain.ru; expires=Tue, 20 Mar 2012 11:52:54 GMTCookie: name=val;name2=val2;is_visited=2011-13-15
Установкаimport Cookiecookie = Cookie.SimpleCookie()cookie['name'] = 'val'cookie['name']['path'] = '/path'
Получениеcookie.load('a=b;c=d')for name in cookie: print '%s => %s' % (name, cookie[name])
Шаблонизаторы '''<html><body> <h1>%s</h1></body></html>’’ % name
VS context = { 'user' : get_user(form['name']), 'friends' : get_friends(form['name']) }
render('tpl/home.html', context)
Шаблонизаторы
ШаблонизаторыDjango, Jinja2 {% extends "layout.html" %}{% block body %} <ul> {% for user in users %} <li> {% include helper %}</li> {% endfor %} </ul>{% endblock %}
SSI <!--# echo var=”Email" default="" -->
<!--# include virtual="/remote/body.php?argument=value" -->
<!--# if expr="$name = /(.+)@(?P<domain>.+)/" --> <!--# echo var="1" --> <!--# echo var="domain" --> <!--# endif -->
ФреймворкиГотовая архитектура проекта
Решения для часто-встречающихся задач
Все их используют
Flask app = Flask(__name__)
@app.route('/')def index_page(): db = get_db() cur = db.execute('select title, text from entries order by id desc' entries = cur.fetchall() return render_template('show_entries.html', entries=entries)
@app.route('/contact/')def contact_page(): return render_template('contact_page.html')
MVC
ПримерыPHP - CodeIgniter, Yii
ASP.Net MVC Framework
Perl - Catalyst
Python - Django, Pyramid
Ruby - Ruby on Rails
Почему Django?
Почему Django?
Почему Django?Instagram
40+ миллионов пользователей
100+ виртуальных серверов
1 миллион регистраций за 12 часов послезапуска Android версии
5 разработчиков
Почему Django?Pinterest
3 миллиона посетителей в день
4 по популярности в США после Facebook,Twitter, LinkedIn
410 ТБ пользовательских данных
Почему Django?Disqus
500 миллионов уникальных посетителей вмесяц
750 тысяч сайтов используют Disqus
165 тысяч сообщений в секунду
8 инженеров-разработчиков
Django
Возможности фреймворкаГибкая ORM
Интерфейс администрирования
Диспетчер URL на основе регулярныхвыражений
Шаблонизатор
Кэширующий фреймворк
Интернационализация
Обширное комьюнити
Структура проектаПроект состоит из приложений
Приложения могут находиться где угодно вPython path
Pluggable-приложения
Полезные ссылкиhttp://docs.djangoproject.com/
http://www.djangosites.org/with-source/
https://github.com/django/django