Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
224d0cd
Merge pull request #1 from LittleByLittleLabs/donigian.initialBranch4…
donigian Mar 28, 2015
21fdce5
Update README.md
donigian Mar 28, 2015
22af3f5
updated notes
donigian Mar 29, 2015
d3d1d4f
Update README.md
donigian Mar 29, 2015
a5e88b3
Update README.md
donigian Mar 29, 2015
5421a58
Update README.md
donigian Mar 30, 2015
8a14e53
Update README.md
donigian Mar 30, 2015
7081a6d
Update README.md
donigian Apr 4, 2015
5d20296
Update README.md
donigian Apr 4, 2015
ced3f60
Update README.md
donigian Apr 5, 2015
9fdb2af
Updated Readme.md with instructions for Git workflow.
Apr 12, 2015
f72f233
Merge pull request #9 from LittleByLittleLabs/donigian.instructionsFo…
donigian Apr 12, 2015
92500c7
Update README.md
donigian Apr 12, 2015
59e96d3
Update README.md
donigian Apr 14, 2015
de83eb6
Update README.md
donigian Apr 14, 2015
302cb6e
Added jinja templates.
Apr 18, 2015
a36b94c
Merge pull request #23 from LittleByLittleLabs/donigian.addJinjaTempl…
donigian Apr 18, 2015
8ecf29e
Added Bootstrap.
Apr 18, 2015
b3cdba4
Merge pull request #24 from LittleByLittleLabs/donigian.bootstrap
donigian Apr 18, 2015
608028c
Added Supervisor, Nginx, and Vagrant installation/configuation files.
Apr 18, 2015
2abd182
Merge pull request #25 from LittleByLittleLabs/donigian.virtualization
donigian Apr 18, 2015
a33d6fe
Update README.md
donigian Apr 20, 2015
42ea35a
Changes needed for vagrant.
Apr 25, 2015
b0c3909
Merge pull request #27 from LittleByLittleLabs/donigian.fixVagrant
donigian Apr 25, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ venv
.idea

students/data.sqlite

# vagrant
.vagrant
123 changes: 122 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,127 @@
Custom APIs using Flask
========================================================
=====================

This repo contains a seed project to help you start building a microservice with custom API endpoints.

If this is your first time, do the following after you clone:

```
# create a virtualenv environment
virtualenv venv

# start virtualenv environment
source venv/bin/activate

# install dependencies needed for your app
pip install -r requirements.txt

# start the server
python requests/app/api.py

# stop virtualenv environment
deactivate
```

For subsequent runs, simply do the following:
```
# start virtualenv environment
source venv/bin/activate

# start the server, ctrl-c if you want to stop server
python requests/app/api.py

# Test 1: in separate console window, retrieve all students
http GET http://localhost:5000/students/

# Test 2: in separate console window, create a new student
http POST http://localhost:5000/students/ name=Armen

# Test 3: in separate console window, retrieve a specific user
http GET http://localhost:5000/students/1

# Test 4: in separate console window, update an existing user
http PUT http://localhost:5000/students/1 name="Changed Name"

# stop virtualenv environment when you're finished
deactivate
```

Challenge (due April 5th):
```
1. Complete the `For subsequent runs` section above
2. Write a script which will test the 4 endpoints above (GET, POST, GET, PUT) using curl.
3. Write a script which will populate 30 records into your database.
```


Challenge (due April 12th)

1. Find a data set

2. Create a SQL schema

3. Write a script to extract and transform the data into an input file

3. Implement REST POST endpoint to populate data into sqlite

4. Write a script to load data into DB using curl from previous step



Some interesting product feature ideas may be:

Best Posts

Worst Posts

Most Controversial

Most Commented

Most/Least posts by author

Top Site References

**Don't forget to push your github branch on Mondays.


Instructions for Git Workflow

```
1. Git pull or Git clone repo which you plan to make changes to

2. Create a branch using (`git checkout -b branchname`)

3. Make the changes

4. Commit the changes locally

5. Push changes to remote repo (`git push -u origin branchname`)

6. Create Pull Request and send to reviewers

7. Address reviewer comments and merge Pull Request to master
```

Challenge (due April 17th)

We discussed in class what and how to use Apache Bench (https://www.digitalocean.com/community/tutorials/how-to-use-apachebench-to-do-load-testing-on-an-arch-linux-vps).

Your challenge for this week is to create a report in markdown format callled `load_test.md`. This report should contain a few benchmarks/scenarios which you can perform on your app. If you haven't gotten previous weeks challenge to work, then you can simply clone and run the seed github project for students as you did 3 weeks ago.

Please provide an explanation for each load test scenario and your justification for why or how you came up with the different values for `-n` & `-c` flags. You can also try using `ngrok` after you document your tests for `localhost` and explain differences.


Challenge Due (April 25th)

1. Implement a 404.html error page
```
# todo: implement this template
@app.errorhandler(404)
def not_found(e):
return render_template('404.html')
```

2. Implement a `index.html` for your project and make it look pretty. Use `app/index.html` as an example.

3. Get `vagrant up` working for your project
34 changes: 34 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box_url = "https://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-i386-vagrant-disk1.box"
config.vm.box = "precise64"
config.ssh.forward_agent = true

# Create a private network, which allows host-only access to the machine
# using a specific IP.
#config.vm.network "private_network", ip: "localhost"
config.vm.network :forwarded_port, host: 5000, guest: 5000

config.vm.provider :virtualbox do |vb, override|

# The Virtualbox image
override.vm.box = "precise64"
override.vm.box_url = "http://files.vagrantup.com/precise64.box"

# Port forwarding details

# Flask
override.vm.network :forwarded_port, host: 5000, guest: 5000

# You can increase the default amount of memory used by your VM by
# adjusting this value below (in MB) and reprovisioning.
vb.customize ["modifyvm", :id, "--memory", "384"]
end

# Setup web server
config.vm.provision "shell", path: 'install_script.sh', args: '/vagrant', privileged: false
end
29 changes: 29 additions & 0 deletions install_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# install web server dependencies
sudo apt-get update
sudo apt-get -y install python python-virtualenv nginx supervisor

# install application (source location in $1)
mkdir /home/vagrant/students
cp $1/requirements.txt /home/vagrant
cp -R $1/students/* /home/vagrant/students/

# create a virtualenv and install dependencies
virtualenv /home/vagrant/students/venv
source /home/vagrant/students/venv/bin/activate
sudo /home/vagrant/students/venv/bin/pip install -r /home/vagrant/requirements.txt

# configure supervisor
sudo cp /vagrant/student.conf /etc/supervisor/conf.d/
sudo mkdir /var/log/student
sudo supervisorctl reread
sudo supervisorctl update

# configure nginx
sudo cp /vagrant/student.nginx /etc/nginx/sites-available/student
sudo rm -f /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/student /etc/nginx/sites-enabled/
sudo service nginx restart

echo Application deployed to http://localhost:5000/
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ itsdangerous==0.24
python-dateutil==2.2
requests==2.3.0
six==1.7.3
flask-bootstrap
gunicorn==19.1.1
9 changes: 9 additions & 0 deletions student.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; supervisor configuration

[program:students]
command=/home/vagrant/students/venv/bin/gunicorn -b 127.0.0.1:5000 -w 4 --chdir /home/vagrant/students --log-file - students:app
user=vagrant
autostart=true
autorestart=true
stderr_logfile=/var/log/student/stderr.log
stdout_logfile=/var/log/student/stdout.log
21 changes: 21 additions & 0 deletions student.nginx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# nginx reverse proxy configuration

server {
listen 80;
server_name _;
access_log /var/log/nginx/student.access.log;
error_log /var/log/nginx/student.error.log;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /home/vagrant/students/static;
}
location /favicon.ico {
alias /home/vagrant/students/static/favicon.ico;
}
}
14 changes: 13 additions & 1 deletion students/app/api.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os
from flask import Flask, url_for, jsonify, request
from flask import Flask, url_for, jsonify, request, render_template
from flask.ext.bootstrap import Bootstrap
from flask.ext.sqlalchemy import SQLAlchemy

basedir = os.path.abspath(os.path.dirname(__file__))
db_path = os.path.join(basedir, '../data.sqlite')

app = Flask(__name__)
bootstrap = Bootstrap(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + db_path

db = SQLAlchemy(app)
Expand Down Expand Up @@ -62,6 +64,16 @@ def edit_student(id):
db.session.commit()
return jsonify({})

# todo: implement this template
@app.errorhandler(404)
def not_found(e):
return render_template('404.html')

@app.route('/')
def index():
highlight = {'min': 1, 'max': 2}
students = Student.query.all()
return render_template('index.html', students=students, highlight=highlight)

if __name__ == '__main__':
db.create_all()
Expand Down
37 changes: 37 additions & 0 deletions students/app/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% extends 'bootstrap/base.html' %}
{% block title %}List of Students{% endblock %}

{% block navbar %}
<nav class="navbar navbar-inverse" role="navigation">
<div class="container">
<a class="navbar-brand" href="#">List of Students</a>
</div>
</nav>
{% endblock %}

{% block content %}
<div class="container">
<h1>Student Info</h1>
<table class="table table-hover">
<tr>
<th>Id</th>
<th></th>
<th>Name</th>
</tr>
{% for student in students %}
<tr>
<td>
{% set hl = student.id <= highlight['min'] %}
{% if hl %}<b>{% endif %}
{{ student.id }}
{% if hl %}</b>{% endif %}
</td>
<td></td>
<td>{{ student.name }}</td>
<td></td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}