PYTHON
                      SIDE PROJECTS
                           by @ahmontero
                             Enero 2013




lunes, 28 de enero de 13
HOLA
lunes, 28 de enero de 13
MI DEFINICIÓN

                  ★ TIEMPO LIBRE

                  ★ ¿ ZONA DE CONFORT ?

                  ★ PERSONA / S

lunes, 28 de enero de 13
MOTIVACIONES
                             ✓ CONSTRUIR

                             ✓ APRENDER

                             ✓ EXPONERSE

lunes, 28 de enero de 13
MOTIVACIONES
                             ✓ CONSTRUIR

                             ✓ APRENDER

                             ✓ EXPONERSE

lunes, 28 de enero de 13
                           ✓DIVERTIRSE
INTRANSCENDENTE




lunes, 28 de enero de 13
INTRANSCENDENTE
                  ‣        # USUARIOS




lunes, 28 de enero de 13
INTRANSCENDENTE
                  ‣        # USUARIOS
                  ‣        # DESCARGAS



lunes, 28 de enero de 13
INTRANSCENDENTE
                  ‣        # USUARIOS
                  ‣        # DESCARGAS
                  ‣        ¿RECHAZADA APP STORE?

lunes, 28 de enero de 13
INTRANSCENDENTE
                  ‣        # USUARIOS
                  ‣        # DESCARGAS
                  ‣        ¿RECHAZADA APP STORE?
                  ‣        MODELO DE NEGOCIO
lunes, 28 de enero de 13
AMOR
lunes, 28 de enero de 13
MUST LIST




lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO




lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO ➡ 100 %




lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO ➡ 100 %

                  ✓ HONESTIDAD



lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO ➡ 100 %

                  ✓ HONESTIDAD

                  ✓ ENLACES

lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO ➡ 100 %

                  ✓ HONESTIDAD

                  ✓ ENLACES ➡ GITHUB, WEB…

lunes, 28 de enero de 13
MUST LIST
                  ✓ TERMINADO ➡ 100 %

                  ✓ HONESTIDAD

                  ✓ ENLACES ➡ GITHUB, WEB…

                  ✓ NO MIEDOS
lunes, 28 de enero de 13
VENTAJAS
                  ‣        VALORACIÓN
                  ‣        DIFERENCIACIÓN
                  ‣        APTITUDES

lunes, 28 de enero de 13
VENTAJAS
                  ‣        VALORACIÓN
                  ‣        DIFERENCIACIÓN
                  ‣        APTITUDES

lunes, 28 de enero de 13
VENTAJAS
                  ‣        VALORACIÓN
                  ‣        DIFERENCIACIÓN
                  ‣        APTITUDES
                ‣          DEMOSTRACIÓN DE...
lunes, 28 de enero de 13
AMOR
lunes, 28 de enero de 13
EJEMPLOS




lunes, 28 de enero de 13
EJEMPLOS




lunes, 28 de enero de 13
EJEMPLOS




lunes, 28 de enero de 13
EJEMPLOS




lunes, 28 de enero de 13
IDEA

                   ✓ SIMPLE

                   ✓ CON UN FIN ESPECÍFICO

                   ✓ SENTIDO

lunes, 28 de enero de 13
EJECUCIÓN
                  ✓ SENCILLA

                  ✓ MEJORAS EN ITERACIONES

                  ✓ NO PRE - OPTIMIZAR

lunes, 28 de enero de 13
Minimun
    Viable
    Product
lunes, 28 de enero de 13
No
    Complicarse
    La
    Vida
lunes, 28 de enero de 13
PROYECTO 1

                  ✓ JUGAR CON BOTTLEPY

                  ✓ DEPLOY EN VPS



lunes, 28 de enero de 13
REQUISITOS I
                            ✓   BOTTLEPY
                            ✓   NGINX
                            ✓   GUNICORN
                            ✓   SUPERVISOR

lunes, 28 de enero de 13
REQUISITOS II
                  ✓        VPS
                  ✓        DIGITAL OCEAN
                  ✓        PROMO CODE: SSDBEAR20
                  ✓        20 $ ~ 3 MESES

lunes, 28 de enero de 13
BOTTLEPY
                  ✓ UN ARCHIVO
                  ✓ LIBRERÍA ESTÁNDAR PYTHON
                  ✓ ROUTING, TEMPLATES,
                    FORMULARIOS, COOKIES…
                  ✓ COMPATIBLE HTTP WSGI
lunes, 28 de enero de 13
BOTTLEPY
                 CUIDADO CON:
                  ➡        PROYECTOS GRANDES
                  ➡        ORM
                  ➡        LAYOUT PROYECTO
lunes, 28 de enero de 13
EJEMPLO
                import bottle

          app = bottle.default_app()

          @app.route('/', method='GET')
          @app.route('/greet/<name:re:[a-z]+>', method='GET')
          def greet(name='world'):
              res = {}
              res['status'] = 'OK'
              res['result'] = 'Hello %s' % name

                    return res

          if __name__ == '__main__':
              bottle.run(app, host='localhost', port=5000, debug=True,
          reloader=True)



lunes, 28 de enero de 13
EJEMPLO
              ➡            PETICIÓN
                           http://127.0.0.1:5000/greet/antonio

              ➡            RESULTADO
                           {
                               "status": "OK",
                               "result": "Hello antonio"
                           }

lunes, 28 de enero de 13
FIBONACCI I
          class Fibonacci(object):
              def __init__(self, steps):
                  self.a = 0
                  self.b = 1
                  self.index = 0
                  self.steps = steps

                  def calculate(self):
                      if self.steps > 0:
                          if self.steps == 1:
                              yield self.a
                          else:
                              yield self.a
                              yield self.b
                              self.index = self.index + 2
                              while self.index < self.steps:
                                  self.a, self.b = self.b, self.a + self.b
                                  self.index = self.index + 1
                                  yield self.b
                      else:
                          raise Exception(''steps' must be an integer >= 0')



lunes, 28 de enero de 13
FIBONACCI II
          @app.route('/fibonacci', method='POST')
          def fibonacci():
              res = {}
              steps = bottle.request.forms.steps

                    try:
                           steps = int(steps)
                           fib = Fibonacci(steps)
                           seq = fib.calculate()
                           res['status'] = 'OK'
                           res['result']={}
                           res['result']['sequence'] = [n for n in seq]

                    except Exception as e:
                        res['status'] = 'Error'
                        res['message'] = '%s' % e

                    return res


lunes, 28 de enero de 13
EJEMPLO
              ➡            PETICIÓN
                               POST http://127.0.0.1:5000/fibonacci
                                     steps = 5

              ➡            RESULTADO
                           {
                               "status": "OK",
                               "result": {
                                   "sequence": [0, 1, 1, 2, 3]
                                }
                           }
lunes, 28 de enero de 13
NGINX
                 sudo nano /etc/nginx/sites-available/project1
                       upstream app_server {
                           server 127.0.0.1:8001 fail_timeout=0;
                 }

                 server {
                            server_name 127.0.0.1;
                            listen 127.0.0.1:80;

                            root /home/username/projects/project1;

                            location / {
                                    try_files $uri @proxy_to_app;
                            }
                            location @proxy_to_app{
                                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                                    proxy_set_header Host $http_host;
                                    proxy_redirect off;

                                    proxy_pass   http://app_server;
                            }
                 }




lunes, 28 de enero de 13
SUPERVISOR
                 sudo nano /etc/supervisor/conf.d/project1.conf
                    [program:project1]
                 command= /home/username/projects/project1/venv/bin/gunicorn -c /
                 home/username/projects/project1/gunicorn.prod.conf project1:app
                 directory=/home/username/projects/project1
                 autostart=true
                 autorestart=true
                 redirect_stderr=true




lunes, 28 de enero de 13
LOCALHOST
      1. GIT CLONE HTTPS://GITHUB.COM/AHMONTERO/SIDE-PROJECTS-SPEECH.GIT
      2. CD SIDE-PROJECTS-SPEECH
      3. CHMOD +X SETUP_ENV.SH
      4. ./SETUP_ENV.SH
      5. SOURCE __VEN__/BIN/ACTIVATE
      6. PIP INSTALL -R REQUIREMENTS.TXT
      7. PYTHON PROJECT1.PY
      8. HTTP://127.0.0.1:5000/GREET/ANTONIO


lunes, 28 de enero de 13
PROYECTO 1I
                  ✓ WEB SCRAPING
                  ✓ API HTTP REST
                  ✓ DJANGO + TWITTER
                  ✓ BOOTSTRAP
lunes, 28 de enero de 13
BRAINSTORMING
                  ✓ OFERTAS DE TRABAJO
                  ✓ EMPRESAS JÓVENES E
                    INNOVADORAS
                  ✓ RISAS
lunes, 28 de enero de 13
ESPECIFICACIONES
                  ✓ PARSEAR OFERTAS
                  ✓ CLASIFICARLAS
                  ✓ LOGIN CON TWITTER
                  ✓ COMENTARIOS
lunes, 28 de enero de 13
REQUISITOS
                           ✓   BEAUTIFUL SOUP
                           ✓   DJANGO
                           ✓   NGINX
                           ✓   GUNICORN
                           ✓   SUPERVISOR
lunes, 28 de enero de 13
DATA SCRAPING

                  ✓ BEAUTIFUL SOUP
                  ✓ SCRIPT INDEPENDIENTE
                  ✓ USA API HTTP

lunes, 28 de enero de 13
API HTTP REST I
                  ✓ DJANGO-TASTYPIE
                  ✓ DOCUMENTACIÓN
                  ✓ AUTENTICACIÓN
                  ✓ EXTENSIBLE (NOSQL…)
lunes, 28 de enero de 13
API HTTP REST II
                  ✓ AUTENTICACIÓN
                           ✓ API_USER
                           ✓ API_KEY
                  ✓ SIN COMPLICACIONES
lunes, 28 de enero de 13
DISEÑO




lunes, 28 de enero de 13
DISEÑO
                  ✓ NO SOY DISEÑADOR




lunes, 28 de enero de 13
DISEÑO
                  ✓ NO SOY DISEÑADOR
                  ✓ FÁCIL…



lunes, 28 de enero de 13
DISEÑO
                  ✓ NO SOY DISEÑADOR
                  ✓ FÁCIL…
                  ✓ COPIO DISEÑO WEB DE
                    BOOTSTRAP
lunes, 28 de enero de 13
lunes, 28 de enero de 13
LAYOUT PROYECTO




lunes, 28 de enero de 13
LAYOUT PROYECTO




lunes, 28 de enero de 13
LAYOUT PROYECTO


                           Requirements separados




lunes, 28 de enero de 13
LAYOUT PROYECTO


                           Archivos deploy
                           Requirements separados




lunes, 28 de enero de 13
LAYOUT PROYECTO
                           Aplicaciones

                           Archivos deploy
                           Requirements separados




lunes, 28 de enero de 13
LAYOUT PROYECTO
                           Aplicaciones
                           Algunos PaaS lo necesitan
                           Archivos deploy
                           Requirements separados




lunes, 28 de enero de 13
LAYOUT PROYECTO
                           Aplicaciones
                           Algunos PaaS lo necesitan
                           Archivos deploy
                           Requirements separados
                           Parser ofertas



lunes, 28 de enero de 13
REQUIREMENTS
                 /requirements/_base.txt

                 beautifulsoup4
                 django
                 django-tastypie
                 django-twitter
                 gunicorn
                 honcho
                 lxml
                 psycopg2
                 recaptcha-client

lunes, 28 de enero de 13
REQUIREMENTS
                 /requirements/local.txt

                 -r _base.txt
                 django-debug-toolbar==0.9.4


                 /requirements/production.txt

                 -r _base.txt




lunes, 28 de enero de 13
SETTINGS
                 /angryjobs/settings/base.py
                 DJANGO_APPS = (
                     # Default Django apps:
                     'django.contrib.auth',
                     'django.contrib.contenttypes',
                     'django.contrib.sessions',
                     'django.contrib.sites',
                     'django.contrib.messages',
                     'django.contrib.staticfiles',
                     'django.contrib.webdesign',
                 )

                 THIRD_PARTY_APPS = (
                     # Wsgi http server
                     'gunicorn',
                     # Api
                     'tastypie',
                 )

                 # Apps specific for this project go here.
                 LOCAL_APPS = (
                     'web',
                     'api',
                     'twitter',
                 )

                 INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS




lunes, 28 de enero de 13
SETTINGS
                 /angryjobs/settings/base.py
                 DJANGO_APPS = (
                     # Default Django apps:
                     'django.contrib.auth',
                     'django.contrib.contenttypes',
                     'django.contrib.sessions',
                     'django.contrib.sites',
                     'django.contrib.messages',
                     'django.contrib.staticfiles',
                     'django.contrib.webdesign',
                 )

                 THIRD_PARTY_APPS = (
                     # Wsgi http server
                     'gunicorn',
                     # Api
                     'tastypie',
                 )

                 # Apps specific for this project go here.
                 LOCAL_APPS = (
                     'web',
                     'api',
                     'twitter',
                 )

                 INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS




lunes, 28 de enero de 13
SETTINGS
                 /angryjobs/settings/local.py
                 from os.path import join, normpath
                 from os import environ
                 from base import *

                 API_USER = environ.get('TE_API_USER', '')
                 API_KEY = environ.get('TE_API_KEY', '')

                 DATABASES = {
                     'default': {
                         'ENGINE': 'django.db.backends.sqlite3',
                         'NAME': normpath(join(DJANGO_ROOT, 'angryjobs.db')),
                         'USER': '',
                         'PASSWORD': '',
                         'HOST': '',
                         'PORT': '',
                     }
                 }



lunes, 28 de enero de 13
EJECUCIÓN
           ✓ NO USAR MANAGE.PY

           ✓ USAR DJANGO-ADMIN.PY
             django-admin.py syncdb --pythonpath='angryjobs' --settings=angryjobs.settings.local

             django-admin.py runserver --pythonpath='angryjobs' --settings=angryjobs.settings.local




lunes, 28 de enero de 13
VENTAJAS
                  ✓ CONTROL DE VERSIONES
                  ✓ DATOS SENSIBLES A SALVO
                  ✓ ENTORNOS IGUALES


lunes, 28 de enero de 13
LOCALHOST
      1. GIT CLONE HTTPS://GITHUB.COM/AHMONTERO/ANGRYJOBS.GIT
      2. CD ANGRYJOBS
      3. CHMOD +X SETUP_ENV.SH
      4. ./SETUP_ENV.SH
      5. SOURCE __VEN__/BIN/ACTIVATE
      6. PIP INSTALL -R REQUIREMENTS/LOCAL.TXT
      7. DJANGO-ADMIN.PY SYNCDB --PYTHONPATH='ANGRYJOBS' --
         SETTINGS=ANGRYJOBS.SETTINGS.LOCAL

      8. DJANGO-ADMIN.PY RUNSERVER --PYTHONPATH='ANGRYJOBS' --
         SETTINGS=ANGRYJOBS.SETTINGS.LOCAL

      9. PYTHON UPDATER/FETCH_DATA.PY
      10. HTTP://127.0.0.1:8000
lunes, 28 de enero de 13
NÚMEROS
           ✓ ~ 40 HORAS
           ✓ VERANO
           ✓ NINGÚN COMENTARIO
           ✓ POCOS RETWEETS
lunes, 28 de enero de 13
NÚMEROS
           ✓ ~ 40 HORAS
           ✓ VERANO ➡ NO SIESTA
           ✓ NINGÚN COMENTARIO
           ✓ POCOS RETWEETS
lunes, 28 de enero de 13
photo credit: http://www.flickr.com/photos/notemily/5590023825/




lunes, 28 de enero de 13
EXPERIENCIA
           ✓ SETTINGS SEPARADOS
           ✓ BEAUTIFULSOAP
           ✓ ÚTIL EN 1 ENTREVISTA
           ✓ DIVERSIÓN
lunes, 28 de enero de 13
photo credit: http://www.flickr.com/photos/pjlewis/65273119




lunes, 28 de enero de 13
PROYECTO 1II
            ✓ DIGITAL OCEAN API
            ✓ NO PYTHON WRAPPER?
            ✓ IDEA!

lunes, 28 de enero de 13
ESPECIFICACIONES

          ✓ WRAPPER API HTTP
          ✓ MÉTODOS DEFINIDOS WEB
          ✓ DOCUMENTACIÓN


lunes, 28 de enero de 13
REQUISITOS I
                             ✓ PYTHON

                             ✓ REQUESTS



lunes, 28 de enero de 13
EXPERIENCIA
           ✓ REQUESTS MOLA
           ✓ ~ 20$ CRÉDITO
           ✓ NOMBRADO EN BLOG
           ✓ PEGATINAS!!
lunes, 28 de enero de 13
lunes, 28 de enero de 13
FIN
lunes, 28 de enero de 13

Python side projects etssi-jan-2013

  • 1.
    PYTHON SIDE PROJECTS by @ahmontero Enero 2013 lunes, 28 de enero de 13
  • 2.
    HOLA lunes, 28 deenero de 13
  • 3.
    MI DEFINICIÓN ★ TIEMPO LIBRE ★ ¿ ZONA DE CONFORT ? ★ PERSONA / S lunes, 28 de enero de 13
  • 4.
    MOTIVACIONES ✓ CONSTRUIR ✓ APRENDER ✓ EXPONERSE lunes, 28 de enero de 13
  • 5.
    MOTIVACIONES ✓ CONSTRUIR ✓ APRENDER ✓ EXPONERSE lunes, 28 de enero de 13 ✓DIVERTIRSE
  • 6.
  • 7.
    INTRANSCENDENTE ‣ # USUARIOS lunes, 28 de enero de 13
  • 8.
    INTRANSCENDENTE ‣ # USUARIOS ‣ # DESCARGAS lunes, 28 de enero de 13
  • 9.
    INTRANSCENDENTE ‣ # USUARIOS ‣ # DESCARGAS ‣ ¿RECHAZADA APP STORE? lunes, 28 de enero de 13
  • 10.
    INTRANSCENDENTE ‣ # USUARIOS ‣ # DESCARGAS ‣ ¿RECHAZADA APP STORE? ‣ MODELO DE NEGOCIO lunes, 28 de enero de 13
  • 11.
    AMOR lunes, 28 deenero de 13
  • 12.
    MUST LIST lunes, 28de enero de 13
  • 13.
    MUST LIST ✓ TERMINADO lunes, 28 de enero de 13
  • 14.
    MUST LIST ✓ TERMINADO ➡ 100 % lunes, 28 de enero de 13
  • 15.
    MUST LIST ✓ TERMINADO ➡ 100 % ✓ HONESTIDAD lunes, 28 de enero de 13
  • 16.
    MUST LIST ✓ TERMINADO ➡ 100 % ✓ HONESTIDAD ✓ ENLACES lunes, 28 de enero de 13
  • 17.
    MUST LIST ✓ TERMINADO ➡ 100 % ✓ HONESTIDAD ✓ ENLACES ➡ GITHUB, WEB… lunes, 28 de enero de 13
  • 18.
    MUST LIST ✓ TERMINADO ➡ 100 % ✓ HONESTIDAD ✓ ENLACES ➡ GITHUB, WEB… ✓ NO MIEDOS lunes, 28 de enero de 13
  • 19.
    VENTAJAS ‣ VALORACIÓN ‣ DIFERENCIACIÓN ‣ APTITUDES lunes, 28 de enero de 13
  • 20.
    VENTAJAS ‣ VALORACIÓN ‣ DIFERENCIACIÓN ‣ APTITUDES lunes, 28 de enero de 13
  • 21.
    VENTAJAS ‣ VALORACIÓN ‣ DIFERENCIACIÓN ‣ APTITUDES ‣ DEMOSTRACIÓN DE... lunes, 28 de enero de 13
  • 22.
    AMOR lunes, 28 deenero de 13
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
    IDEA ✓ SIMPLE ✓ CON UN FIN ESPECÍFICO ✓ SENTIDO lunes, 28 de enero de 13
  • 28.
    EJECUCIÓN ✓ SENCILLA ✓ MEJORAS EN ITERACIONES ✓ NO PRE - OPTIMIZAR lunes, 28 de enero de 13
  • 29.
    Minimun Viable Product lunes, 28 de enero de 13
  • 30.
    No Complicarse La Vida lunes, 28 de enero de 13
  • 31.
    PROYECTO 1 ✓ JUGAR CON BOTTLEPY ✓ DEPLOY EN VPS lunes, 28 de enero de 13
  • 32.
    REQUISITOS I ✓ BOTTLEPY ✓ NGINX ✓ GUNICORN ✓ SUPERVISOR lunes, 28 de enero de 13
  • 33.
    REQUISITOS II ✓ VPS ✓ DIGITAL OCEAN ✓ PROMO CODE: SSDBEAR20 ✓ 20 $ ~ 3 MESES lunes, 28 de enero de 13
  • 34.
    BOTTLEPY ✓ UN ARCHIVO ✓ LIBRERÍA ESTÁNDAR PYTHON ✓ ROUTING, TEMPLATES, FORMULARIOS, COOKIES… ✓ COMPATIBLE HTTP WSGI lunes, 28 de enero de 13
  • 35.
    BOTTLEPY CUIDADO CON: ➡ PROYECTOS GRANDES ➡ ORM ➡ LAYOUT PROYECTO lunes, 28 de enero de 13
  • 36.
    EJEMPLO import bottle app = bottle.default_app() @app.route('/', method='GET') @app.route('/greet/<name:re:[a-z]+>', method='GET') def greet(name='world'): res = {} res['status'] = 'OK' res['result'] = 'Hello %s' % name return res if __name__ == '__main__': bottle.run(app, host='localhost', port=5000, debug=True, reloader=True) lunes, 28 de enero de 13
  • 37.
    EJEMPLO ➡ PETICIÓN http://127.0.0.1:5000/greet/antonio ➡ RESULTADO { "status": "OK", "result": "Hello antonio" } lunes, 28 de enero de 13
  • 38.
    FIBONACCI I class Fibonacci(object): def __init__(self, steps): self.a = 0 self.b = 1 self.index = 0 self.steps = steps def calculate(self): if self.steps > 0: if self.steps == 1: yield self.a else: yield self.a yield self.b self.index = self.index + 2 while self.index < self.steps: self.a, self.b = self.b, self.a + self.b self.index = self.index + 1 yield self.b else: raise Exception(''steps' must be an integer >= 0') lunes, 28 de enero de 13
  • 39.
    FIBONACCI II @app.route('/fibonacci', method='POST') def fibonacci(): res = {} steps = bottle.request.forms.steps try: steps = int(steps) fib = Fibonacci(steps) seq = fib.calculate() res['status'] = 'OK' res['result']={} res['result']['sequence'] = [n for n in seq] except Exception as e: res['status'] = 'Error' res['message'] = '%s' % e return res lunes, 28 de enero de 13
  • 40.
    EJEMPLO ➡ PETICIÓN POST http://127.0.0.1:5000/fibonacci steps = 5 ➡ RESULTADO { "status": "OK", "result": { "sequence": [0, 1, 1, 2, 3] } } lunes, 28 de enero de 13
  • 41.
    NGINX sudo nano /etc/nginx/sites-available/project1 upstream app_server { server 127.0.0.1:8001 fail_timeout=0; } server { server_name 127.0.0.1; listen 127.0.0.1:80; root /home/username/projects/project1; location / { try_files $uri @proxy_to_app; } location @proxy_to_app{ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } } lunes, 28 de enero de 13
  • 42.
    SUPERVISOR sudo nano /etc/supervisor/conf.d/project1.conf [program:project1] command= /home/username/projects/project1/venv/bin/gunicorn -c / home/username/projects/project1/gunicorn.prod.conf project1:app directory=/home/username/projects/project1 autostart=true autorestart=true redirect_stderr=true lunes, 28 de enero de 13
  • 43.
    LOCALHOST 1. GIT CLONE HTTPS://GITHUB.COM/AHMONTERO/SIDE-PROJECTS-SPEECH.GIT 2. CD SIDE-PROJECTS-SPEECH 3. CHMOD +X SETUP_ENV.SH 4. ./SETUP_ENV.SH 5. SOURCE __VEN__/BIN/ACTIVATE 6. PIP INSTALL -R REQUIREMENTS.TXT 7. PYTHON PROJECT1.PY 8. HTTP://127.0.0.1:5000/GREET/ANTONIO lunes, 28 de enero de 13
  • 44.
    PROYECTO 1I ✓ WEB SCRAPING ✓ API HTTP REST ✓ DJANGO + TWITTER ✓ BOOTSTRAP lunes, 28 de enero de 13
  • 45.
    BRAINSTORMING ✓ OFERTAS DE TRABAJO ✓ EMPRESAS JÓVENES E INNOVADORAS ✓ RISAS lunes, 28 de enero de 13
  • 46.
    ESPECIFICACIONES ✓ PARSEAR OFERTAS ✓ CLASIFICARLAS ✓ LOGIN CON TWITTER ✓ COMENTARIOS lunes, 28 de enero de 13
  • 47.
    REQUISITOS ✓ BEAUTIFUL SOUP ✓ DJANGO ✓ NGINX ✓ GUNICORN ✓ SUPERVISOR lunes, 28 de enero de 13
  • 48.
    DATA SCRAPING ✓ BEAUTIFUL SOUP ✓ SCRIPT INDEPENDIENTE ✓ USA API HTTP lunes, 28 de enero de 13
  • 49.
    API HTTP RESTI ✓ DJANGO-TASTYPIE ✓ DOCUMENTACIÓN ✓ AUTENTICACIÓN ✓ EXTENSIBLE (NOSQL…) lunes, 28 de enero de 13
  • 50.
    API HTTP RESTII ✓ AUTENTICACIÓN ✓ API_USER ✓ API_KEY ✓ SIN COMPLICACIONES lunes, 28 de enero de 13
  • 51.
  • 52.
    DISEÑO ✓ NO SOY DISEÑADOR lunes, 28 de enero de 13
  • 53.
    DISEÑO ✓ NO SOY DISEÑADOR ✓ FÁCIL… lunes, 28 de enero de 13
  • 54.
    DISEÑO ✓ NO SOY DISEÑADOR ✓ FÁCIL… ✓ COPIO DISEÑO WEB DE BOOTSTRAP lunes, 28 de enero de 13
  • 55.
    lunes, 28 deenero de 13
  • 56.
  • 57.
  • 58.
    LAYOUT PROYECTO Requirements separados lunes, 28 de enero de 13
  • 59.
    LAYOUT PROYECTO Archivos deploy Requirements separados lunes, 28 de enero de 13
  • 60.
    LAYOUT PROYECTO Aplicaciones Archivos deploy Requirements separados lunes, 28 de enero de 13
  • 61.
    LAYOUT PROYECTO Aplicaciones Algunos PaaS lo necesitan Archivos deploy Requirements separados lunes, 28 de enero de 13
  • 62.
    LAYOUT PROYECTO Aplicaciones Algunos PaaS lo necesitan Archivos deploy Requirements separados Parser ofertas lunes, 28 de enero de 13
  • 63.
    REQUIREMENTS /requirements/_base.txt beautifulsoup4 django django-tastypie django-twitter gunicorn honcho lxml psycopg2 recaptcha-client lunes, 28 de enero de 13
  • 64.
    REQUIREMENTS /requirements/local.txt -r _base.txt django-debug-toolbar==0.9.4 /requirements/production.txt -r _base.txt lunes, 28 de enero de 13
  • 65.
    SETTINGS /angryjobs/settings/base.py DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.webdesign', ) THIRD_PARTY_APPS = ( # Wsgi http server 'gunicorn', # Api 'tastypie', ) # Apps specific for this project go here. LOCAL_APPS = ( 'web', 'api', 'twitter', ) INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS lunes, 28 de enero de 13
  • 66.
    SETTINGS /angryjobs/settings/base.py DJANGO_APPS = ( # Default Django apps: 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.webdesign', ) THIRD_PARTY_APPS = ( # Wsgi http server 'gunicorn', # Api 'tastypie', ) # Apps specific for this project go here. LOCAL_APPS = ( 'web', 'api', 'twitter', ) INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS lunes, 28 de enero de 13
  • 67.
    SETTINGS /angryjobs/settings/local.py from os.path import join, normpath from os import environ from base import * API_USER = environ.get('TE_API_USER', '') API_KEY = environ.get('TE_API_KEY', '') DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': normpath(join(DJANGO_ROOT, 'angryjobs.db')), 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } } lunes, 28 de enero de 13
  • 68.
    EJECUCIÓN ✓ NO USAR MANAGE.PY ✓ USAR DJANGO-ADMIN.PY django-admin.py syncdb --pythonpath='angryjobs' --settings=angryjobs.settings.local django-admin.py runserver --pythonpath='angryjobs' --settings=angryjobs.settings.local lunes, 28 de enero de 13
  • 69.
    VENTAJAS ✓ CONTROL DE VERSIONES ✓ DATOS SENSIBLES A SALVO ✓ ENTORNOS IGUALES lunes, 28 de enero de 13
  • 70.
    LOCALHOST 1. GIT CLONE HTTPS://GITHUB.COM/AHMONTERO/ANGRYJOBS.GIT 2. CD ANGRYJOBS 3. CHMOD +X SETUP_ENV.SH 4. ./SETUP_ENV.SH 5. SOURCE __VEN__/BIN/ACTIVATE 6. PIP INSTALL -R REQUIREMENTS/LOCAL.TXT 7. DJANGO-ADMIN.PY SYNCDB --PYTHONPATH='ANGRYJOBS' -- SETTINGS=ANGRYJOBS.SETTINGS.LOCAL 8. DJANGO-ADMIN.PY RUNSERVER --PYTHONPATH='ANGRYJOBS' -- SETTINGS=ANGRYJOBS.SETTINGS.LOCAL 9. PYTHON UPDATER/FETCH_DATA.PY 10. HTTP://127.0.0.1:8000 lunes, 28 de enero de 13
  • 71.
    NÚMEROS ✓ ~ 40 HORAS ✓ VERANO ✓ NINGÚN COMENTARIO ✓ POCOS RETWEETS lunes, 28 de enero de 13
  • 72.
    NÚMEROS ✓ ~ 40 HORAS ✓ VERANO ➡ NO SIESTA ✓ NINGÚN COMENTARIO ✓ POCOS RETWEETS lunes, 28 de enero de 13
  • 73.
  • 74.
    EXPERIENCIA ✓ SETTINGS SEPARADOS ✓ BEAUTIFULSOAP ✓ ÚTIL EN 1 ENTREVISTA ✓ DIVERSIÓN lunes, 28 de enero de 13
  • 75.
  • 76.
    PROYECTO 1II ✓ DIGITAL OCEAN API ✓ NO PYTHON WRAPPER? ✓ IDEA! lunes, 28 de enero de 13
  • 77.
    ESPECIFICACIONES ✓ WRAPPER API HTTP ✓ MÉTODOS DEFINIDOS WEB ✓ DOCUMENTACIÓN lunes, 28 de enero de 13
  • 78.
    REQUISITOS I ✓ PYTHON ✓ REQUESTS lunes, 28 de enero de 13
  • 79.
    EXPERIENCIA ✓ REQUESTS MOLA ✓ ~ 20$ CRÉDITO ✓ NOMBRADO EN BLOG ✓ PEGATINAS!! lunes, 28 de enero de 13
  • 80.
    lunes, 28 deenero de 13
  • 81.
    FIN lunes, 28 deenero de 13