손님이 특정 모듈을 볼 수 없지만 여전히 작동하도록 파이썬 코드베이스를 어떻게 보호합니까?

StackOverflow https://stackoverflow.com/questions/1443146

문제

우리는 Python에서 몇 가지 독점 알고리즘과 민감한 논리 비트를 사용하여 새로운 프로젝트를 시작하고 있습니다. 또한 코드에서 작업하는 몇몇 외부인 (대중 선택)이 있습니다. 우리는 외부인에게 소형 개인 비트에 대한 액세스 권한을 부여 할 수는 없지만 공개 버전이 충분히 잘 작동하기를 원합니다.

우리 프로젝트 인 Foo에는 모듈이 있다고 말합니다. bar, 하나의 기능으로 get_sauce(). 실제로 무슨 일이 일어나는지 get_sauce() 비밀이지만 우리는 공개 버전을 원합니다. get_sauce() 허용 가능한 것을 반환하려면 부정확하지만 결과.

우리는 또한 우리 자신의 Subversion Server를 실행하므로 누가 액세스 할 수 있는지에 대한 완전히 제어 할 수 있습니다.

Symlinks

나의 첫 번째 생각은 대신에 동성 링크였습니다 bar.py, 제공하다 bar_public.py 모든 사람과 bar_private.py 내부 개발자에게만. 불행히도, Symlinks를 만드는 것은 지루하고 수동 작업입니다. 특히이 개인 모듈 중 약 24 개가 실제로있을 때.

더 중요한 것은, 각 모듈에 대해 예외를 보호하려는 것이 서버에 추가되어야하기 때문에 Subversion Authz 파일을 관리하기가 어렵다는 것입니다. 누군가 가이 일을 잊고 실수로 비밀을 확인하는 것을 잊을 수 있습니다 ... 그러면 모듈은 리포지토리에 있으며 저장소를 재건해야하며 외부인이 그 동안 다운로드하지 않기를 바랍니다.

여러 저장소

다음 생각에는 두 개의 리포지토리가있는 것이 었습니다.

private
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        └── bar.py
public
└── trunk/
    ├── __init__.py
    └── foo/
        ├── __init__.py
        ├── bar.py
        ├── baz.py
        └── quux.py

아이디어는 내부 개발자만이 둘 다 체크 아웃 할 수 있다는 것입니다. private/ 그리고 public/. 내부 개발자는 자신을 설정합니다 PYTHONPATH=private/trunk:public/trunk, 그러나 다른 모든 사람들은 방금 설정할 것입니다 PYTHONPATH=public/trunk. 그런 다음 내부자와 외부인 모두가 할 수 있습니다 from foo import bar 그리고 올바른 모듈을 얻으십시오.

이것을 시도해 봅시다 :

% PYTHONPATH=private/trunk:public/trunk python
Python 2.5.1
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo.bar
>>> foo.bar.sauce()
'a private bar'
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

나는 파이썬 전문가가 아니지만 Python은 이미 모듈에 대한 마음을 구성한 것 같습니다. foo 그리고 그것에 대한 검색 :

>>> foo
<module 'foo' from '/path/to/private/trunk/foo/__init__.py'>

삭제조차하지 않습니다 foo 도움 :

>>> import sys
>>> del foo
>>> del sys.modules['foo']
>>> import foo.quux
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named quux

더 나은 솔루션이나 제안을 제공 할 수 있습니까?

도움이 되었습니까?

해결책

에서 __init__ 방법의 방법 foo 패키지를 변경할 수 있습니다 __path__ 다른 디렉토리에서 모듈을 찾기 위해.

따라서 호출되는 디렉토리를 만듭니다 secret 그리고 당신의 개인 전복 저장소에 넣으십시오. ~ 안에 secret 당신의 독점을 넣으십시오 bar.py. 에서 __init__.py 대중의 foo 패키지는 다음과 같은 것과 같은 것을 넣습니다.

__path__.insert(0,'secret')

이것은 개인 저장소가있는 사용자에게 의미합니다. secret 디렉토리 그들은 독점을 얻을 것입니다 bar.py ~처럼 foo.bar ~처럼 secret 검색 경로의 첫 번째 디렉토리입니다. 다른 사용자의 경우 Python은 찾을 수 없습니다 secret 다음 디렉토리로 보일 것입니다 __path__ 그리고 정상을로드 할 것입니다 bar.py ~에서 foo.

그래서 그것은 다음과 같이 보일 것입니다.

   private
    └── trunk/
        └── secret/
            └── bar.py
    public
    └── trunk/
        ├── __init__.py
        └── foo/
            ├── __init__.py
            ├── bar.py
            ├── baz.py
            └── quux.py

다른 팁

일종의 플러그인 시스템을 사용하고 플러그인을 자체적으로 보관할뿐만 아니라 오픈 코드와 함께 제공되는 공개적으로 사용 가능한 플러그인도 가지고 있습니다.

플러그인 시스템이 많이 있습니다. 당신은 쉽게 죽은 단순한 것을 직접 만들 수 있습니다. 더 진보 된 것을 원한다면 Zope 구성 요소 아키텍처를 선호하지만 setuptools entry_points 등과 같은 옵션도 있습니다.

귀하의 경우에 사용해야 할 것은 좋은 두 번째 질문입니다.

다음은 문서를 읽을 때 알아 차린 대체 솔루션입니다. 플라스크:

flaskext/__init__.py

이 파일의 유일한 목적은 패키지를 네임 스페이스 패키지로 표시하는 것입니다. 다른 PYPI 패키지의 여러 모듈이 동일한 Python 패키지에 상주 할 수 있도록 필요합니다.

__import__('pkg_resources').declare_namespace(__name__)

그곳에서 무슨 일이 일어나고 있는지 정확히 알고 싶다면 배포 또는 SetUptools 문서를 확인하여 이것이 어떻게 작동하는지 설명하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top