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
链接转换成二维码
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 trust
https://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