oTree安装学习记录

oTree简介

oTree是一个基于python的框架,能够让你构建:

  • 多人策略游戏,如囚徒困境,公共品博弈,拍卖
  • 经济学,心理学等相关领域的受控行为实验
  • 调查问卷与测验

英文官网https://otree.readthedocs.io/en/latest/index.html

中文官网https://otree.readthedocs.io/zh_CN/latest/index.html

如何利用Python + oTree框架编写在线的心理学测验https://zhuanlan.zhihu.com/p/81214979

经济学家的编程课之pythonhttps://www.bilibili.com/video/BV1JE411W7bR

链接转换成二维码

https://cli.im/

oTree的安装与运行

安装oTree

本地(Mac os)上安装oTree

在mac os 本地电脑上安装oTree很容易,在之前已经配置好python3.8环境后,先用conda激活影响的环境conda activate MyPython3.8,然后在terminal中输入pip install -U otree即可安装成功。

在Centos服务器上安装oTree

更新python3

oTree要求运行在python3.7或者python3.8上 ,而Centos上自带的python版本是3.6.8,因此,我采用源码安装的方式安装了Python-3.8.7,下面是安装python3.8.7的过程。

主要参考了以下两个链接,第一次安装时,虽然安装过程没问题,但是后面安装oTree时可能由于一些依赖库没有安装,出现了一些问题,又重新进行了安装python3.8.7。

https://tecadmin.net/install-python-3-8-centos/

https://linuxize.com/post/how-to-install-python-3-8-on-centos-8/

dnf groupinstall 'development tools'

dnf install bzip2-devel expat-devel gdbm-devel \
    ncurses-devel openssl-devel readline-devel \
    sqlite-devel tk-devel xz-devel zlib-devel libffi-devel

scp /Users/yuanbo/Downloads/Python-3.8.7.tgz root@1.13.2.85:/opt/ #电脑上下载的Python-3.8.7.tgz上传到服务器的/opt/用于随后解压安装

tar -xf Python-3.8.7.tgz #解压并进入文件夹
cd Python-3.8.7

./configure --enable-optimizations
make -j 4
sudo make altinstall

rm -rf Python-3.8.7.tgz #删除Python-3.8.7.tgz文件

python3.8 --version
与/usr/bin/python3建立软连接

https://www.jianshu.com/p/aca71ba154b6


rm -rf /usr/bin/python3
rm -rf /usr/bin/pip3

ln -s /usr/local/bin/python3.8 /usr/bin/python3
ln -s /usr/local/bin/pip3.8 /usr/bin/pip3

python3 --version
pip3 --version

创建python3.8的虚拟环境

python3.8 -m venv venv_otree
source ~/venv_otree/bin/activate #放在.bashrc文件中
source ~/.bashrc

# rm -rf /root/venv_otree 删除虚拟环境
# rmvirtualenv venv_otree
在服务器上安装oTree遇到问题

在Centos上安装碰到了一些问题。这里由于在Centos上安装python3.8 有点问题,所以安装psycopg2一直失败。重新配置环境后再次安装psycopg2成功,也成功安装了otree。

pip install --upgrade pip
#Install wheel pip install wheel
pip install wheel
## pip install psycopg2
pip install psycopg2

## python - can't install psycopg2 on centos 7 如何解决
#yum install postgresql-libs
#yum install postgresql-devel

pip install -U otree
##otree 5.3.1

服务器上安装和配置PostgreSQL

oTree官网上介绍在服务器上安装的过程非常简略,有很多坑没有明确说明。我主要参考了下面两个链接,折腾到大半夜才配置好。主要是其中PostgreSQL的配置过程遇到了 Ident authentication failed for user on Ubuntu (Postgres)错误,而在修改pg_hba.conf文件时又没有正确修改好,忽略了是在最后一部分配置语句中修改。解决方案就是修改为host all all 127.0.0.1/32 trusthttps://www.jianshu.com/p/a969e8cfb37e

oTree’s default database is SQLite, which is fine for local development, but insufficient for production. We recommend PostgreSQL, although you can also use MySQL, MariaDB, or any other database supported by Django.

### Postgres基本操作
#新建用户
CREATE USER test WITH PASSWORD 'test';
#赋予指定账户指定数据库所有权限
GRANT ALL PRIVILEGES ON DATABASE mydb TO test;
#移除指定账户指定数据库所有权限
REVOKE ALL PRIVILEGES ON DATABASE mydb TO test;
#权限代码:SELECT、INSERT、UPDATE、DELETE、TRUNCATE、REFERENCES、TRIGGER、CREATE、CONNECT、TEMPORARY、EXECUTE、USAGE

# 后面出现数据库Ident authentication failed for user on Ubuntu (Postgres)问题
#chmod 777 /var/lib/pgsql/data/pg_hba.conf
vi /var/lib/pgsql/data/pg_hba.conf
host all all 127.0.0.1/32 md5
#host all all 127.0.0.1/32  trust
#service postgresql restart
systemctl restart postgresql

服务器宕机后重新启动postgresql

https://codeantenna.com/a/VULmU2K2PY

## 查看命令
ps aux | grep postgres

#service postgresql restart
systemctl start postgresql #启动服务
systemctl restart postgresql #重启服务
systemctl stop postgresql #停止服务


如何设置自动重启
systemctl enable postgresql.service #开机启动服务

systemctl is-enable postgresql.service #查看是否开机启动服务

oTree Ubuntu Server Setup(主要内容摘录)

https://ibsen-otree-docs.ibsen-h2020.eu/server/ubuntu.html#sharing-a-server-with-other-otree-users

https://otreecb.netlify.app/reference/ubuntu_server_setup.html

  • Database (Postgresql) and related packages (libpq-dev, postgresql-contrib, redis-server). We will install them with a single command below but before that a note about python version.
  • Set up postgresql
#PostgreSQL查看版本信息
psql --version
postgres --version
#我安装的psql (PostgreSQL)版本是 10.17
#select version();

#切换到postgres超级管理员
sudo su - postgres
#Start the Postgres shell
psql

CREATE DATABASE django_db;
alter user postgres password 'dbpasswordhere';
#然后输入`\q`退出命令行;输入`exit`退出psql

However, instead of modifying the above line directly, it’s better to set the DATABASE_URL environment variable on your server. Setting the database through an environment variable allows you to continue to use SQLite on your development machine, while using Postgres on your production server.但是,与其直接修改上述行,不如在服务器上设置DATABASE_URL环境变量。通过环境变量设置数据库允许您继续在开发机器上使用 SQLite,同时在生产服务器上使用 Postgres。

Add DATABASE_URL and REDIS_URL enviroment variables on your ~/.bashrc. You can use nano or your favourite text editor. To use nano write

#postgres超级用户的密码为yuanbobq0501!

nano ~/.bashrc

export DATABASE_URL=postgres://postgres:yuanbobq0501!@localhost/django_db
#export DATABASE_URL=postgres://postgres:dbpasswordhere@localhost/django_db
export REDIS_URL=redis://localhost:6379
export OTREE_ADMIN_PASSWORD="adminpasswordhere"
export OTREE_PRODUCTION="1" # can set to 1                $
export OTREE_AUTH_LEVEL="STUDY" # can set to STUDY or DEMO$

source ~/.bashrc
echo $DATABASE_URL

另外一个类似的设置方法

CREATE DATABASE django_db;
#CREATE USER otree_user WITH PASSWORD 'mypassword';
CREATE USER otree_user WITH PASSWORD 'yuanbobq0501';
#alter user postgres password 'dbpasswordhere';
GRANT ALL PRIVILEGES ON DATABASE django_db TO otree_user;
#将数据库得权限,全部赋给某个用户grant all on database sonar to foo;

nano ~/.bashrc
#export DATABASE_URL=postgres://otree_user:mypassword@localhost/django_db
export DATABASE_URL=postgres://otree_user:yuanbobq0501@localhost/django_db
#export DATABASE_URL=postgres://otree_user:yuanbobq0501@127.0.0.1/django_db
source ~/.bashrc
echo $DATABASE_URL


Database backups

If you are using Postgres, you can export your database to a file called otree.sql with a command like this:

pg_dump -U postgres -h localhost django_db > otree-$(date +"%Y-%m-%d-%H-%M").sql

#pg_dump -U otree_user -h localhost django_db > otree-$(date +"%Y-%m-%d-%H-%M").sql

(This assumes your database is set up as described above (with username otree_user and database name django_db, and that you are on Unix.)

Install Redis

目前还不确定Redis用来干什么。

If you installed redis-server through apt-get as instructed earlier, Redis should be running on port 6379. You can test with redis-cli ping, which should output PONG.

If there was an installation problem, you can try installing Redis from an alternate source, e.g. here.

https://www.linode.com/docs/guides/install-and-configure-redis-on-centos-7/

本地运行和测试oTree

otree startproject oTree #Create oTree project folder
cd oTree
pip install -r requirements.txt #Go to the folder and install requirements
otree resetdb
#Start the server

otree devserver

在服务器上运行和测试oTree

https://otreecb.netlify.app/reference/ubuntu_server_setup.html

otree startproject oTree #Create oTree project folder
cd oTree

otree devserver
## 然后打开你的浏览器,输入网站 http://localhost:8000 即可测试。

## 创建项目
cd /root/Online_experiment/
otree startproject oTree
cd /oTree

otree prodserver 8000

## 以后直接运行
cd /root/Online_experiment/oTree
otree prodserver 8000
#sudo -E env "PATH=$PATH" otree prodserver 8000

# otree runprodserver --port=8000

上传实验程序文件到服务器

#scp 覆盖文件使用命令
## 上传修改后的otree程序
scp -r /Users/yuanbo/Downloads/Online_experiments/oTree/oTree_Projects/socialcontrol_exp root@1.13.2.85:/root/Online_experiment/oTree/

scp -r /Users/yuanbo/Downloads/Online_experiments/oTree/oTree_Projects/social_control root@1.13.2.85:/root/Online_experiment/oTree/

scp -r /Users/yuanbo/Downloads/Online_experiments/oTree/oTree_Projects/social_Nocontrol root@1.13.2.85:/root/Online_experiment/oTree/

服务器上配置nginx

应该和之前在Jatos上配置类似,后面有时间测试下。经测试,nginx配置与之前在Jatos上配置类似,只是在location中的proxy_set_header稍有修改,参考 这里


server {
        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

	server_name YOURHOSTNAMESHOULDBEHERE;

	location ^~/_static/{
	root /home/cloud/oTree/;
	include /etc/nginx/mime.types;
	}

	location / {
	   proxy_buffering off;
	   proxy_pass http://localhost:8000;
	   proxy_http_version 1.1;
	   proxy_set_header Upgrade $http_upgrade;
	   proxy_set_header Connection $connection_upgrade; 
	   proxy_set_header HOST $host;
	   proxy_set_header X-Real-Ip $remote_addr;
	   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	   proxy_set_header X-Forwarded-Host $server_name;
	   proxy_set_header X-Forwarded-Proto $scheme;
	   proxy_set_header X-Forwarded-Port $server_port;
	   }

}

nginx -t ##检查配置文件是否正确
sudo service nginx reload # 重新加载配置,一般是在修改过 nginx 配置文件时使用。
sudo service nginx stop # 停止 nginx 服务

sudo service nginx restart # 重启 nginx 服务
### 检查 Nginx 的运行状态:
sudo systemctl status nginx


最终的 nginx配置文件


sudo vi /etc/nginx/nginx.conf


        # redirect http to https
        server {
                listen      80;
                server_name www.scmdlab.cn exp.scmdlab.cn;
                # server_name localhost;
                # rewrite ^/(.*) https://www.scmdlab.cn/$1 permanent; #rewrite all http requests to be https requests
                rewrite     ^ https://www.scmdlab.cn$request_uri? permanent; ## redirect http to https

        }

        ## jatos --> www.scmdlab.cn
        server {
                listen        443 ssl;
                server_name   www.scmdlab.cn;
                # server_name localhost;

                keepalive_timeout    70;

                ssl_certificate      /etc/ssl/certs/1_www.scmdlab.cn_bundle.crt;
                ssl_certificate_key  /etc/ssl/private/2_www.scmdlab.cn.key;

                ssl_protocols             TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
                ssl_prefer_server_ciphers on;

                # websocket location (JATOS' group and batch channel and the test page)
                location ~ "/(jatos/testWebSocket|publix/[\d]+/(group/join|batch/open))" {
                        proxy_pass              http://jatos-backend;
                        proxy_http_version      1.1;
                        proxy_set_header        Upgrade $http_upgrade;
                        proxy_set_header        Connection $connection_upgrade;
                        proxy_connect_timeout   7d; # keep open for 7 days even without any transmission
                        proxy_send_timeout      7d;
                        proxy_read_timeout      7d;
                }       

                # all other traffic
                location / {
                        # proxy_pass            http://1.13.2.85:9000;
                        proxy_pass              http://jatos-backend;
                        proxy_connect_timeout   300;
                        proxy_send_timeout      300;
                        proxy_read_timeout      300;
                        send_timeout            300;
                }
                
        }

         ## oTree --> exp.scmdlab.cn
         server {
                listen        443 ssl;
                server_name   exp.scmdlab.cn;
                # server_name localhost;

                keepalive_timeout    70;

                ssl_certificate      /etc/ssl/certs/1_exp.scmdlab.cn_bundle.crt;
                ssl_certificate_key  /etc/ssl/private/2_exp.scmdlab.cn.key;

                ssl_protocols             TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
                ssl_prefer_server_ciphers on;
      


                # nodegame
                # location /nodegame  {
                #         proxy_pass http://localhost:8080;
                #         proxy_http_version 1.1;
                #         proxy_set_header Upgrade $http_upgrade;
                #         proxy_set_header Connection 'upgrade';
                #         proxy_cache_bypass $http_upgrade;

                # } 
                location / {
                        proxy_pass http://127.0.0.1:8000/;
                        proxy_http_version 1.1;
                        proxy_set_header Upgrade $http_upgrade;
                        proxy_set_header Connection $connection_upgrade; 
                        proxy_set_header HOST $host;
                        proxy_set_header X-Real-Ip $remote_addr;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Host $server_name;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header X-Forwarded-Port $server_port;

                }            
                
        }       

服务器上进程控制系统

Once the server is working as described above, it’s a good practice to use a process control system like Supervisord or Circus. This will restart your processes in case they crash, keep it running if you log out, etc

automatize the otree process using supervisor

暂时使用nohup命令

使用nohup命令

描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示”and”的符号)到命令的尾部。

nohup java ChatServer > ChatServer.file 2>&1 &

## 在我的服务器上启动otree的命令
nohup otree prodserver 8000 & 
#后台运行,可以加上 & 符号

pid 3539765

那要如何找到进程对应的 pid 呢?我们可以使用 ps 命令。

ps aux | grep otree

pgrep -a otree

ps -ef|grep otree|grep -v grep #显示出所有的otree进程,并去处掉当前的grep进程。

kill -9 3539765 #杀掉otree进程
kill -9 3539771 #杀掉otree进程
#Centos查看端口占用情况命令,比如查看80端口占用情况使用如下命令:
lsof -i tcp:8000
#netstat -ntlp
netstat -ntlp

#检查端口被哪个进程占用
netstat -lnp|grep 8000   #88请换为你的apache需要的端口,如:80

pm2是否可以达到类似效果?

(Process Manager 2 )是具有内置负载均衡器的Node.js应用程序的生产运行时和进程管理器。 它允许您永久保持应用程序活跃,无需停机即可重新加载它们,并促进常见的Devops任务。

pm2 start app.js                //启动app.js应用
pm2 start app.js --name demo    //启动应用并设置name
pm2 start app.sh                //脚本启动

pm2 stop all               //停止所有应用
pm2 stop [AppName]        //根据应用名停止指定应用
pm2 stop [ID]             //根据应用id停止指定应用

pm2 delete all               //关闭并删除应用
pm2 delete [AppName]        //根据应用名关闭并删除应用
pm2 delete [ID]            //根据应用ID关闭并删除应用

##创建开机自启动
pm2 startup
##pm2 startup centos 

##更新PM2
pm2 updatePM2
pm2 update

##监听模式
pm2 start app.js --watch    //当文件发生变化,自动重启

##重新启动
//同时杀死并重启所有进程。短时间内服务不可用。生成环境推荐使用reload
pm2 restart app.js

##0秒停机重新加载
pm2 reload app.js        //重新启动所有进程,始终保持至少一个进程在运行
pm2 gracefulReload all   //优雅地以群集模式重新加载所有应用程序

##查看启动列表
pm2 list

##显示应用程序所有信息
pm2 show [Name]      //根据name查看
pm2 show [ID]        //根据id查看

##保存当前应用列表
pm2 save


pm2 start otree prodserver 8000 #目前看不行
pm2 delete otree

可以通过Set up Git。If your code is on your personal computer and you are trying to push it to this web server, you can use Git.

oTree学习记录

otree调试程序教训

调试了好几天的程序,发现是用subsession的问题,应该用player的属性。真是惨重的教训了,花费了那么长时间。

Inspect game 里面现在设置的P1就是雇员,P2就是雇主

p1 = group.get_player_by_id(1) #employee p2 = group.get_player_by_id(2) #employer

Yuan Bo 袁博
Yuan Bo 袁博
Associate Professor of Psychology (Social Psychology)

My research examines the nature and dynamics of social norms, namely how norms may emerge and become stable, why norms may suddenly change, how is it possible that inefficient or unpopular norms survive, and what motivates people to obey norms. I combines laboratory and simulation experiments to test theoretical predictions and build empirically-grounded models of social norms and their dynamics.

comments powered by Disqus