Articles with the tag python

PySeaweed update


Posted on 2016-06-12


I've updated my package PySeaweed (and changed it name from PyWeed).

Changes:

  • Overall code cleanup
  • Added option yo use reqests.Session() for better performance while dealing with huge ammount of files
  • Fixed some tests
  • Merge in one fork

PySeaweed on PyPi and Sources

Leave a comment

Getting package version from code without importing


Posted on 2015-04-07


I use this code for getting version info from package code without importing it, as it has to be installed to be imported and it can't be installed without version number. Classic 'Chicken or the egg' dilema.

I'm using ast module from Python stdlib to parse file from package code. In example I'm using __init__.py but one can use any other file.

It's works with module level variables (only string or number) and it's alternative to using eval() or exec().

setup.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# coding=utf-8
import os
import ast
from setuptools import setup, find_packages


def get_info(filename):
    info = {}
    with open(filename) as _file:
        data = ast.parse(_file.read())
        for node in data.body:
            if type(node) != ast.Assign:
                continue
            if type(node.value) not in [ast.Str, ast.Num]:
                continue
            name = None
            for target in node.targets:
                name = target.id
            if type(node.value) == ast.Str:
                info[name] = node.value.s
            elif type(node.value) == ast.Num:
                info[name] = node.value.n
    return info

file_with_packageinfo = "packagename/__init__.py"
info = get_info(file_with_packageinfo)

here = os.path.abspath(os.path.dirname(__file__))
# README = open(os.path.join(here, 'README.txt')).read()
# CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()


requires = [
]

setup(name='packagename',
      version=info.get('__version__', '0.0.0'),
      description='Package description',
      # long_description=README + '\n\n' + CHANGES,
      classifiers=[
          "Programming Language :: Python ",
      ],
      author=info.get('__author__', 'Łukasz Bołdys'),
      author_email='[email protected]',
      url='http://dev.utek.pl',
      keywords='',
      packages=find_packages(),
      include_package_data=True,
      zip_safe=False,
      test_suite='packagename',
      install_requires=requires,
      entry_points="""\
      [console_scripts]
          ddd = packagename.scripts.analyze:main
      """,
      )

packagename/__init__.py

1
2
3
4
# coding=utf-8

__version__ = "0.5.1"
__author__ = "Łukasz Bołdys"

Leave a comment

Extending setup.py install commands


Posted on 2015-03-11


Lately one of my associates asked if there is a way to use different install_requires lists in setup.py depending on way of installing.

If you are doing python setup.py install you would get one set of requires and doing python setup.pl develop would give you another set of requires (either extended or totally different).

Here's my solution:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python
# coding=utf-8

from setuptools import setup, find_packages
from setuptools.command.develop import develop

requires = [
    'fabric',
    'pelican'
]


class ExtendedDevel(develop):
    ''' Adding ipython to requirements '''
    def run(self):
        requires.append('ipython')
        develop.run(self)


setup(name='lalala',
      version='0.0.1',
      description='That\'s stupid',
      long_description='DESCRIPTION',
      classifiers=[
      ],
      author='Łukasz Bołdys',
      author_email='[email protected]',
      url='',
      keywords='',
      license='LICENSE',
      packages=find_packages(),
      include_package_data=True,
      zip_safe=False,
      test_suite='test',
      install_requires=requires,
      cmdclass={'develop': ExtendedDevel}
      )

Using this code in setup.py will install fabric, pelican and ipython when doing python setup.py develop but will only install fabric and pelican if installing via python setup.py install.

If you don't want to change default behavior of develop you can add new command with changing cmdclass={'develop': ExtendedDevel} to cmdclass={'newcommand': ExtendedDevel}.

Edit 2015-04-22 10:47:20:

As I first needed method explained above to add some lib to development enviroment that was not needed in production enviroment. But there is better method to do it.

You can pass 'extras_require' argument to setup(). 'extras_require' is and dictionary of 'targets' as key and list of additional requirements as value. See documentation for more info.

Leave a comment

Ignoring tables in Alembic


Posted on 2013-08-12


While working on spatial enabled application I came up to a problem with spatial table in my postgres database (spatial_ref_sys). Alembic insisted on deleting this table as it wasn't declared in my models.py.

I didn't wanted to define it just to keep Alembic from removing it so I've added following changes to .ini and env.py files:

development.ini

1
2
[alembic:exclude]
tables = spatial_ref_sys

env.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def exclude_tables_from_config(config_):
    tables_ = config_.get("tables", None)
    if tables_ is not None:
        tables = tables_.split(",")
    return tables

exclude_tables = exclude_tables_from_config(config.get_section('alembic:exclude'))

def include_object(object, name, type_, reflected, compare_to):
    if type_ == "table" and name in exclude_tables:
        return False
    else:
        return True

def run_migrations_online():
    if isinstance(engine, Engine):
        connection = engine.connect()
    else:
        raise Exception('Expected engine instance got %s instead' % type(engine))

    context.configure(
        connection=connection,
        target_metadata=target_metadata,
        include_object=include_object
    )

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()

Leave a comment

WebPy middleware authorization


Posted on 2012-11-12


middleware.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class AuthApp(SimpleHTTPRequestHandler):
    def __init__(self, environ, start_response):
        self.headers = []
        self.environ = environ
        self.start_response = start_response

    def send_response(self, status, msg=""):
        self.status = str(status) + " " + msg

    def send_header(self, name, value):
        self.headers.append((name, value))

    def end_headers(self):
        pass

    def log_message(*a): pass

    def __iter__(self):
        environ = self.environ
        self.send_header('WWW-Authenticate','Basic realm="App authorization"')
        self.send_response(401, "Unauthorized")
        self.start_response(self.status, self.headers)
        yield "Unauthorized"

    AUTH = settings.AUTH

    class AuthMiddleware:
        """WSGI Middleware for authentication."""
        def __init__(self, app):
            self.app = app
        def __call__(self, environ, start_response):
            #allowed = [("test", "test")]
            allowed = AUTH
            auth = environ.get('HTTP_AUTHORIZATION')
            authreq = False
            if auth is None:
                authreq = True
            else:
                auth = re.sub('^Basic ','',auth)
                username,password = base64.decodestring(auth).split(':')
                if (username,password) in allowed:
                    return self.app(environ, start_response)
                else:
                    authreq = True
            if authreq:
                return AuthApp(environ, start_response)

In your main webpy project code

1
2
3
4
5
6
7
8
app = web.application(urls, locals())
app.add_processor(load_sqla)

application = app.wsgifunc(AuthMiddleware) # for WSGI

if __name__ == "__main__":
    pass
    app.run(AuthMiddleware) # for direct execution

Leave a comment

Categories

Tags

Links