2013-02-14 74 views
0

我是奥斯汀一家小型创业公司的数据人员。我所做的所有分析(迄今为止)都存储为一组从我的笔记本电脑运行的特别脚本。这是一个坏主意。将Python分析脚本部署到服务器

我要在这里画出我的计划来部署我的分析,我想知道是否有任何我曾经错过的明显漏洞,或者我应该考虑的其他事情。我认为概要我保持足够的原子,以便能够在需要的时间和地点插入事物,而且还允许我轻松地运行一个脚本。次要(长期)目标是将简单的Web前端向上放置,以允许用户(即我公司的员工)一次调用一个脚本,请参阅:Very simple web service: take inputs, email results

我想将脚本部署到服务器,我正在考虑将我的脚本组织到一组python模块中。然后,我希望我的批处理脚本如下所示:

import analysis 

batch_dict = analysis.build_batch_dict() 
assert sorted(batch_dict.keys()) = ['Hourly', 'Monthly', 'Nightly', 'Weekly'] 

scripts_to_run = analysis.what_batch() # get from command line? 
results_directory = analysis.make_results_directory() 
failures = {} 
for script in scripts_to_run: 
    try: 
     script.analyze() 
     script.export_results(results_directory) 
    except Exception as e: 
     failures.update(script.failed(e)) 

analysis.completed(failures) 

我将重写我的分析以便它们由类处理。

class AnalysisHandler(object): 
    ... 
    def analyze(): 
     pass 
    def export_results(some_directory): 
     pass 
    def failed(exception): 
     pass 
    def run_with_non_default_args(*args, **kwargs): 
     pass 
    def something_else_im_missing_now(): 
     pass 

所有的脚本都会被继承自AnalysisHandler的东西处理。

服务器上的目录结构如下所示:

datalytics/ 
    results/ 
     02-14-2013/ 
      script1/ 
       /log 
       /error 
       /data 
      script2/ 
       /log 
       /error 
       /data 
      . 
      . 
      . 
      <etc> 
    scripts/ 
     script1/ 
      bin/ 
      data/ 
      doc/ 
      script_1/ 
      tests/ 
      setup.py 
     . 
     . 
     . 
    analysis/ 
     __init__.py 
     analysis.py 
    batch.py (see above) 
    new_script.py 
    run_all_tests.py 
    run_some_tests.py 
    run_this_script.py 
    run_everything.py 
+0

某处有在这里一个问题...... – 2013-02-14 17:10:39

+0

“我要在这里写生我的计划部署我的分析,我想知道,如果有,我已经错过任何明显的缺陷或者我应该考虑的其他事情。“我需要问号吗? – BenDundee 2013-02-14 17:12:16

+1

时髦的权限问题可能会在创建目录时引发异常。从测试背景来看,我认为你最好将你的for循环封装在'with open(output)'等文件中,然后写出结果,并存储它们。在服务器崩溃的情况下,你至少想知道运行的是什么,以及是否有可能你的脚本卡在无限的东西中,并啃掉所有内存等。 – pyInTheSky 2013-02-14 17:23:42

回答

1

作为一个正式的答案:

  • 当心,并尝试捕获异常创建文件时(你可能会得到权限问题),特别是当你添加一个前端,并希望写在一个员工不能修改的目录

  • 随着你目前的设置,我建议将这个循环包装在'with'语句中,保留一个打开的文件句柄,并在结果进入时刷新结果。这可以让你在一定程度上跟踪进度,还可以让你知道你的服务器是否崩溃,测试是否运行,并可能如果其中之一导致崩溃

  • 你似乎正在开发相当多的框架。虽然unittest模块是为了测试Python代码,但它当然可以用来代替很多框架(即排序测试,指定要运行哪些测试,日志记录等)。它还将为您提供简单的方法来附加界面,然后为预期的故障等标记测试。

  • 与输出一样重要的是,让它变得有用也很重要。你可能希望它以干净的文本打印,但是如果它开头是一个python字典,并且你压扁了它,请在你的日志文件中添加一个逗号,然后将该字典转储为一个字符串,这样你就可以将该东西舀回到python中并根据需要操作数据。

  • 最后一点,看看json.dumps和json.loads,尤其是对于工作瓦特/日志和Web UI。 javascript是友好的W /格式,你可以通过保持一切'蟒蛇快乐'格式保存自己的一大堆工作

  • 如果你需要它的话,测试的线程化并不难。如果你知道你有一项任务需要很长时间才能运行,或者是IO密集型的,那么可以让它独立运行。如果你确实认为你要走这条路线,从一开始就计划它,并且知道你可能需要保护的变量,或者将所有结果推送到队列中而不是字典上来解决竞争条件问题

  • 注意时间戳的分辨率,特别是如果你加载一个使用时间戳作为一个关键的字典O_O --->干脆不要做它

  • 我注意到config功能,它接受参数和kwargs。如果你打算允许配置测试,无论是通过UI或文件,特别是如果它是一个文件,使用json友好的格式,你可以做kwargs = json.loads(open(configfile,'r')。read())和非常高兴你不必编写解析器或正则表达式,或者在添加参数时修改代码。

+0

分[-1]:好的。我也喜欢将脚本输入为json的想法。关于框架的数量---我认为这是相对较小的开销。尽管使用unittest是个不错的主意。 – BenDundee 2013-02-14 18:27:39

+0

事实上,这并不多,但是我发现,测试发现它总是从小而来,然后迅速增长。如果您正在编写新的测试代码,则可以将其保留在同一个目录中,并将其标记为忽略。我已经完成了两个。我对自制软件框架非常满意,特别是在unittest在python 2.7版本中增加了很多功能之前做了它,但是现在查看模块,我发现使用“已知”框架的好处,特别是如果有人除了以后你将不得不使用它。 – pyInTheSky 2013-02-14 18:51:30