Skip to content

Commit

Permalink
Allow to pass flags as kwargs too in embed mode (#172)
Browse files Browse the repository at this point in the history
* Dynamically load devtools instead of on page load

* Add support for passing flags as kwargs to main / start methods.

* Fix tests for refactored code

* Allow proxy.main, proxy.start, proxy.TestCase.

Also update README.md to reflect the same.

* Use Any for **opts

* Move main as __init__ to avoid name conflicts

* Fix tests

* Update setup.py entry_point

* Explicitly install requirements before setup.py

* Explicitly mention packages of interest

* ipv6 fails on ubuntu, use ipv4

* Make typing-extensions optional

* Instead of putting it all under __init__.py, move main.py to proxy.py

* Simply make setup.py module free

* autopep8
  • Loading branch information
abhinavsingh committed Nov 14, 2019
1 parent 1b0c2f8 commit c943dd7
Show file tree
Hide file tree
Showing 20 changed files with 677 additions and 595 deletions.
65 changes: 43 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Table of Contents
* [Blocking Mode](#blocking-mode)
* [Non-blocking Mode](#non-blocking-mode)
* [Unit testing with proxy.py](#unit-testing-with-proxypy)
* [proxy.main.TestCase](#proxymaintestcase)
* [proxy.TestCase](#proxytestcase)
* [Override Startup Flags](#override-startup-flags)
* [With unittest.TestCase](#with-unittesttestcase)
* [Plugin Developer and Contributor Guide](#plugin-developer-and-contributor-guide)
Expand Down Expand Up @@ -723,75 +723,97 @@ Embed proxy.py

## Blocking Mode

Start `proxy.py` in embedded mode by using `main` method:
Start `proxy.py` in embedded mode with default configuration
by using the `main` method. Example:

```
from proxy.main import main
import proxy
if __name__ == '__main__':
main([])
proxy.main()
```

or, to start with arguments:
Customize startup flags by passing list of input arguments:

```
from proxy.main import main
import proxy
if __name__ == '__main__':
main([
proxy.main([
'--hostname', '::1',
'--port', '8899'
])
```

or, customize startup flags by passing them as kwargs:

```
import ipaddress
import proxy
if __name__ == '__main__':
proxy.main(
hostname=ipaddress.IPv6Address('::1'),
port=8899
)
```

Note that:

1. Calling `main` is simply equivalent to starting `proxy.py` from command line.
2. `main` will block until `proxy.py` shuts down.

## Non-blocking Mode

Start `proxy.py` in embedded mode by using `start` method:
Start `proxy.py` in non-blocking embedded mode with default configuration
by using `start` method: Example:

```
from proxy.main import start
import proxy
if __name__ == '__main__':
with start([]):
with proxy.start([]):
# ... your logic here ...
```

Note that:

1. `start` is simply a context manager.
2. Is similar to calling `main` except `start` won't block.
3. It automatically shut down `proxy.py`.
1. `start` is similar to `main`, except `start` won't block.
1. `start` is a context manager.
It will start `proxy.py` when called and will shut it down
once scope ends.
3. Just like `main`, startup flags with `start` method too
can be customized by either passing flags as list of
input arguments `start(['--port', '8899'])` or by using passing
flags as kwargs `start(port=8899)`.

Unit testing with proxy.py
==========================

## proxy.main.TestCase
## proxy.TestCase

To setup and teardown `proxy.py` for your Python unittest classes,
simply use `proxy.main.TestCase` instead of `unittest.TestCase`.
simply use `proxy.TestCase` instead of `unittest.TestCase`.
Example:

```
from proxy.main import TestCase
import proxy
class TestProxyPyEmbedded(TestCase):
class TestProxyPyEmbedded(proxy.TestCase):
def test_my_application_with_proxy(self) -> None:
self.assertTrue(True)
```

Note that:

1. `proxy.main.TestCase` overrides `unittest.TestCase.run()` method to setup and teardown `proxy.py`.
1. `proxy.TestCase` overrides `unittest.TestCase.run()` method to setup and teardown `proxy.py`.
2. `proxy.py` server will listen on a random available port on the system.
This random port is available as `self.proxy_port` within your test cases.
3. Only a single worker is started by default (`--num-workers 1`) for faster setup and teardown.
4. Most importantly, `proxy.TestCase` also ensures `proxy.py` server
is up and running before proceeding with execution of tests.

## Override startup flags

Expand All @@ -815,14 +837,13 @@ for full working example.

## With unittest.TestCase

If for some reasons you are unable to directly use `proxy.main.TestCase`,
If for some reasons you are unable to directly use `proxy.TestCase`,
then simply override `unittest.TestCase.run` yourself to setup and teardown `proxy.py`.
Example:

```
import unittest
from proxy.main import start
import proxy
class TestProxyPyEmbedded(unittest.TestCase):
Expand All @@ -831,7 +852,7 @@ class TestProxyPyEmbedded(unittest.TestCase):
self.assertTrue(True)
def run(self, result: Optional[unittest.TestResult] = None) -> Any:
with start([
with proxy.start([
'--num-workers', '1',
'--port', '... random port ...']):
super().run(result)
Expand Down
4 changes: 3 additions & 1 deletion benchmark/benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
import time
from typing import List, Tuple

from proxy.common.constants import __homepage__, DEFAULT_BUFFER_SIZE
from proxy.common.constants import DEFAULT_BUFFER_SIZE
from proxy.common.utils import build_http_request
from proxy.http.methods import httpMethods
from proxy.http.parser import httpParserStates, httpParserTypes, HttpParser

__homepage__ = 'https://github.com/abhinavsingh/proxy.py'

DEFAULT_N = 1


Expand Down
1 change: 0 additions & 1 deletion dashboard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
from .dashboard import __version__
3 changes: 0 additions & 3 deletions dashboard/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
from proxy.common.types import DictQueueType
from proxy.core.connection import TcpClientConnection

VERSION = (0, 1, 0)
__version__ = '.'.join(map(str, VERSION[0:3]))

logger = logging.getLogger(__name__)


Expand Down
12 changes: 8 additions & 4 deletions dashboard/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
"""
from setuptools import setup, find_packages

from proxy.common.constants import __author__, __author_email__
from proxy.common.constants import __homepage__, __description__, __download_url__, __license__

from dashboard import __version__
VERSION = (0, 1, 0)
__version__ = '.'.join(map(str, VERSION[0:3]))
__description__ = '⚡⚡⚡ Fast, Lightweight, Programmable Proxy Server in a single Python file.'
__author__ = 'Abhinav Singh'
__author_email__ = 'mailsforabhinav@gmail.com'
__homepage__ = 'https://github.com/abhinavsingh/proxy.py'
__download_url__ = '%s/archive/master.zip' % __homepage__
__license__ = 'BSD'

setup(
name='proxy.py-dashboard',
Expand Down
18 changes: 18 additions & 0 deletions dashboard/src/core/plugins/inspect_traffic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class InspectTrafficPlugin extends DashboardPlugin {

public activated (): void {
this.websocketApi.enableInspection(this.handleEvents.bind(this))
this.ensureIFrame()
}

public deactivated (): void {
Expand All @@ -39,10 +40,27 @@ export class InspectTrafficPlugin extends DashboardPlugin {
console.log(message)
}

private ensureIFrame (): void {
if ($('#' + this.getDevtoolsIFrameID()).length === 0) {
$('#' + this.name)
.children('.app-body')
.append(
this.getDevtoolsIFrame()
)
}
}

private getDevtoolsIFrameID (): string {
return this.name.concat('_inspector')
}

private getDevtoolsIFrame (): JQuery<HTMLElement> {
return $('<iframe></iframe>')
.attr('id', this.getDevtoolsIFrameID())
.attr('height', '80%')
.attr('width', '100%')
.attr('padding', '0')
.attr('margin', '0')
.attr('frameBorder', '0')
.attr('scrolling', 'no')
.attr('src', 'devtools/inspect_traffic.html')
Expand Down
9 changes: 6 additions & 3 deletions plugin_examples/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
"""
from setuptools import setup, find_packages

from proxy.common.constants import __author__, __author_email__
from proxy.common.constants import __homepage__, __description__, __download_url__, __license__

VERSION = (0, 1, 0)
__version__ = '.'.join(map(str, VERSION[0:3]))
__description__ = '⚡⚡⚡ Fast, Lightweight, Programmable Proxy Server in a single Python file.'
__author__ = 'Abhinav Singh'
__author_email__ = 'mailsforabhinav@gmail.com'
__homepage__ = 'https://github.com/abhinavsingh/proxy.py'
__download_url__ = '%s/archive/master.zip' % __homepage__
__license__ = 'BSD'

setup(
name='proxy.py-plugins',
Expand Down
14 changes: 14 additions & 0 deletions proxy/__init__.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,17 @@
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
from .proxy import entry_point
from .proxy import main, start
from .proxy import TestCase

__all__ = [
# PyPi package entry_point. See
# https://github.com/abhinavsingh/proxy.py#from-command-line-when-installed-using-pip
'entry_point',
# Embed mode. See https://github.com/abhinavsingh/proxy.py#embed-proxypy
'main', 'start',
# Unit testing with proxy.py. See
# https://github.com/abhinavsingh/proxy.py#unit-testing-with-proxypy
'TestCase'
]
2 changes: 1 addition & 1 deletion proxy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
from .main import entry_point
from .proxy import entry_point

if __name__ == '__main__':
entry_point()
7 changes: 0 additions & 7 deletions proxy/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@

from .version import __version__

__description__ = '⚡⚡⚡ Fast, Lightweight, Programmable Proxy Server in a single Python file.'
__author__ = 'Abhinav Singh'
__author_email__ = 'mailsforabhinav@gmail.com'
__homepage__ = 'https://github.com/abhinavsingh/proxy.py'
__download_url__ = '%s/archive/master.zip' % __homepage__
__license__ = 'BSD'

PROXY_PY_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
PROXY_PY_START_TIME = time.time()

Expand Down
Loading

0 comments on commit c943dd7

Please sign in to comment.