diff --git a/README.md b/README.md
index ae9f04f..59bc89e 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,120 @@
-# Ziti SDK for Python
+
+
+
-## Installation
+# Python SDK for OpenZiti
+
+
+
+
+
+
+
+
+
+
+
+
+
-Ziti SDK for Python is distributed via Python Package Index(PyPI)
+
+ Getting Started •
+ Examples •
+ Support •
+ Contributing •
+ License
+
-```shell
-pip install openziti
-```
+
+
+The Python SDK for [OpenZiti](https://github.com/openziti/ziti) is a library that enables you to integrate zero trust network connectivity into your Python
+applications, and establish secure connections with remote network resources over an OpenZiti network. The SDK also
+simplifies the process of adding secure, zero-trust network connectivity built into your Python application. It's so
+simple that it can be done in just two lines of code!
+
+OpenZiti is an open-source project that provides secure, zero-trust networking for applications running on any platform.
-## Usage
+More specifically, the SDK allows you to integrate zero trust at the application level. This means your data is never
+exposed outside the application environment providing you with end-to-end encryption for ultimate security. See other
+zero trust models [here](https://docs.openziti.io/docs/learn/core-concepts/zero-trust-models/overview).
+
+
+
-### Identity Enrollment
+## Getting Started
+If you don't already have an OpenZiti network running, you can follow our [express install guides](https://docs.openziti.io/docs/learn/quickstarts/network/)
+to set up the network that fits your needs. Or, you can try [CloudZiti](https://netfoundry.io/pricing/) for free, check out more [here](https://docs.openziti.io/).
-Acquire [Ziti Enrollment Token](https://openziti.github.io/ziti/identities/overview.html)
+### Installing the SDK
+
+The Python SDK for OpenZiti is distributed via the Python Package Index (PyPI) and can be installed using
+[`pip`](https://pypi.org/project/openziti/) package manager.
```shell
-python -m openziti enroll -j -i
+pip install openziti
```
-### Environment Variables
+### Using Ziti Python SDK
+With just two lines of code, you can turn your plain old web server into a secure, zero-trust embedded application.
+Below is an example of just how simple it is to get started.
-- `ZITI_IDENTITIES` is a semi-colon-separated list of file paths to Ziti identity configuration JSON files.
-- You may increase the log level of the underlying C SDK by setting environment variable `ZITI_LOG=4` (`DEBUG`).
+Provide a hostname, and port for your application, a simple monkey patch, and you're ready to go. You don't even need to
+know what a monkey patch is! However, if you're interested in what a monkey patch is, expand the block below.
+
+ What is Monkey Patching?
-### Samples
+ > Monkey patching allows developers to modify functionality for code even when they may not have access to the
+ > original source code. Because Python has a dynamic object model allowing developers to modify objects at runtime.
+ > Monkey patching allows developers to point a function call to any function they want. We can even implement our
+ > own function that doesn't exist in the source code.
+ >
+ > The way this Python SDK uses monkey patching is to override existing functionality in socket handling by the
+ > [socket module](https://docs.python.org/3/library/socket.html).
+ >
+ > Taking a look at the code below, the key lines are the last two. You can see how, for each monkey patched function,
+ > we're telling that function call on the `sock` object to be directed to the function held in `_patch_methods`.
+ > Therefore, this SDK can be used on any application that doesn't manage its own sockets.
+ > ```python
+ > def __init__(self, **kwargs):
+ > self.orig_socket = sock.socket
+ > sock.socket = _patchedSocket(kwargs)
+ > self.orig_methods = {m: sock.__dict__[m] for m, _ in
+ > _patch_methods.items()}
+ > for m_name, _ in _patch_methods.items():
+ > sock.__dict__[m_name] = _patch_methods[m_name]
+ > ```
-We several Python SDK sample programs for clients and servers in [sample/README.md](sample/README.md).
+
-## Getting Help
+```python
+cfg = dict(ztx=openziti.load('/path/to/identity.json'), service="name-of-ziti-service")
+openziti.monkeypatch(bindings={('127.0.0.1', 8000): cfg})
+```
+Or try our decorator pattern with a function annotation
+```python
+@openziti.zitify(bindings={('127.0.0.1', 18080): {'ztx': '/path/to/identity.json', 'service': 'name-of-ziti-service'}})
+def yourFunction():
+```
+## Examples
+Try it out yourself with one of our [examples](sample%2FREADME.md)
+* [Flazk](sample/flask-of-ziti)
+* [Echo Server](sample/ziti-echo-server)
+* [HTTP Server](sample/ziti-http-server)
+* [Ziti Requests](sample/ziti-requests)
+* [Ziti Socket](sample/ziti-socket)
+* [Ziti urllib3](sample/ziti-urllib3)
+## Support
+### Looking for Help?
Please use these community resources for getting help. We use GitHub [issues](https://github.com/openziti/ziti-sdk-py/issues)
for tracking bugs and feature requests and have limited bandwidth to address them.
-- Read the [docs](https://openziti.github.io/ziti/overview.html)
+- Read the [offical docs](https://docs.openziti.io/docs/learn/introduction/)
- Join our [Developer Community](https://openziti.org)
- Participate in discussion on [Discourse](https://openziti.discourse.group/)
-
-Copyright© 2018-2022. NetFoundry, Inc.
+## Contributing
+Do you want to get your hands dirty and help make OpenZiti better? Contribute to the OpenZiti open-source project
+through bug reports, bug fixes, documentation, etc. Check out our guide on contributing to our projects [here](https://docs.openziti.io/policies/CONTRIBUTING.html).
+## License
+[Apache 2.0](./LICENSE)
diff --git a/images/Ziggy-Loves-Python.svg b/images/Ziggy-Loves-Python.svg
new file mode 100644
index 0000000..ecfed0b
--- /dev/null
+++ b/images/Ziggy-Loves-Python.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/python-flask-text.png b/images/python-flask-text.png
new file mode 100644
index 0000000..a13d72e
Binary files /dev/null and b/images/python-flask-text.png differ
diff --git a/images/python-flask.jpg b/images/python-flask.jpg
new file mode 100644
index 0000000..397ea12
Binary files /dev/null and b/images/python-flask.jpg differ
diff --git a/images/ziti-logo-dark.svg b/images/ziti-logo-dark.svg
new file mode 100644
index 0000000..d308722
--- /dev/null
+++ b/images/ziti-logo-dark.svg
@@ -0,0 +1 @@
+OPEN ZITI
\ No newline at end of file
diff --git a/images/ztaa-model-flazk.png b/images/ztaa-model-flazk.png
new file mode 100644
index 0000000..7cd6ea3
Binary files /dev/null and b/images/ztaa-model-flazk.png differ
diff --git a/images/ztaa-model-overview.png b/images/ztaa-model-overview.png
new file mode 100644
index 0000000..7a95482
Binary files /dev/null and b/images/ztaa-model-overview.png differ
diff --git a/sample/README.md b/sample/README.md
index 4372a36..99f4576 100644
--- a/sample/README.md
+++ b/sample/README.md
@@ -1,58 +1,77 @@
-# OpenZiti Python SDK in Action
+# Python SDK for OpenZiti Examples
-## Sample Setup
+## Setup
-See [the main README](../README.md) for general setup and environment details.
+In order to begin using the examples, you'll need an OpenZiti network. If you don't already have one running, you can follow our [express install guides](https://docs.openziti.io/docs/learn/quickstarts/network/)
+to set up the network that fits your needs. You could also use [ZEDS](https://zeds.openziti.org) (Ziti Edge Developer Sandbox) or, you can try cloud Ziti for free, check out more [here](https://docs.openziti.io/).
-- install Python requirements
+### Installing the SDK
+The Python SDK for OpenZiti is distributed via the Python Package Index (PyPI) and can be installed using
+[`pip`](https://pypi.org/project/openziti/) package manager.
+
+```shell
+pip install openziti
+```
+
+### Install Python Requirements
+First, you'll need the dependent libraries used in the examples.
```bash
cd ./sample
pip install -r requirements
```
-- get yourself a Ziti identity from [ZEDS](https://zeds.openziti.org)
-
- follow enrollment instructions from the site, or better yet enroll with openziti Python module
+### Get and Enroll an Identity
+You need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview) to be used by the example
+application. If using [ZEDS](https://zeds.openziti.org) you can grab one from there, otherwise you can find all the
+information you need for creating and enrolling an identity in the [doc here](https://docs.openziti.io/docs/learn/core-concepts/identities/overview#creating-an-identity).
+Alternatively, if you have an identity enrollment token (JWT file), you can perform the enrollment with the Python SDK.
```bash
- python -m openziti enroll --jwt= --identity=
+ python -m openziti enroll --jwt= --identity=
```
- the following instructions assume that Ziti identity is stored in `id.json` file
-
-- set `ZITI_IDENTITIES` environment variable to location of `id.json` file
-
+### Environment
+The `ZITI_IDENTITIES` environment variable can be used to store the paths to any identity files you have. If you have
+more than one identity file, you can use the `;` operator as a delimiter to provide additional identities.
```bash
- export ZITI_IDENTITIES=
+ export ZITI_IDENTITIES=
```
-## Run Samples
-
-All sample scripts use predefined services in [ZEDS](https://zeds.openziti.org)
-
-### `flask-of-ziti/helloFlazk.py`
-
-Shows the use of a decorator function to monkeypatch a Flask server.
-
-### `h-ziti-p.py`
-
-Shows the use of Ziti monkeypatching standard socket to intercept network connections
-and using Ziti overlay.
+There is an optional environment variable `ZITI_LOG` which, by default is set to `1`. This value can be adjusted to
+output more or less log information. A `ZITI_LOG` level of `6` will output `TRACE` level logs.
-### `http-get.py`
+### Network
+Your network overlay needs to have a [Service](https://docs.openziti.io/docs/learn/core-concepts/services/overview),
+and the proper [Service Configurations](https://docs.openziti.io/docs/learn/core-concepts/config-store/overview), the
+documentation for which is linked.
-Monkeypatch `requests.get(url)` to fetch a Ziti service with HTTP.
+If you happen to be using [ZEDS](https://zeds.openziti.org) you are in luck, these examples will use default services
+that are already implemented in the developer sandbox.
-### `ziti-echo-server.py`
+## Examples
+> **Note**
+> All but the Flazk example scripts use predefined services in [ZEDS](https://zeds.openziti.org) by default.
-Open a socket to listen on the overlay for a particular Ziti service and send all bytes received back to the sender.
+### [Flazk](flask-of-ziti)
+An example showing the simplicity in integrating zero trust into a web server or API using Flask. This example also
+shows how to use the decorator to apply the monkeypatch.
+`flask-of-ziti/helloFlazk.py`
-### `ziti-http-server.py`
+### [Ziti Echo Server](ziti-echo-server)
+An example showing how to open a socket to listen on the network overlay for a particular service and send all bytes
+received back to the sender.
-Monkeypatch `http.server` to listen for requests on the overlay. Respond to clients with a simple JSON document.
+### [Ziti HTTP Server](ziti-http-server)
+An example showing how to monkeypatch `http.server` to listen for HTTP requests on the network overlay. When a request
+is captured, a response with a simple JSON document is sent to clients.
-### `ziti-socket-sample.py`
+### [Ziti Requests](ziti-requests)
+An example showing the use of Ziti monkey patching a standard socket, via the requests module, to intercept network
+connections using Ziti overlay.
-Shows the use of _raw_ Ziti socket.
+### [Ziti Socket](ziti-socket)
+An example showing the use of a _raw_ Ziti socket.
+### [Ziti urllib3](ziti-urllib3)
+An example showing how to monkeypatch `urllib3` to fetch a Ziti service using HTTP.
diff --git a/sample/flask-of-ziti/README.md b/sample/flask-of-ziti/README.md
new file mode 100644
index 0000000..a88fecb
--- /dev/null
+++ b/sample/flask-of-ziti/README.md
@@ -0,0 +1,36 @@
+# Hello Flazk
+This example shows the simplicity in integrating zero trust into a web server or API using Flask. This example also
+shows how to use the decorator to apply the monkeypatch.
+
+This is a perfect example of application to application embedded zero trust. When used in conjunction with the
+[Ziti urllib3](../ziti-urllib3) example, both ends of the network are fully app-embedded zero trust applications and therefore
+offer complete encryption from app to app, no unencrypted data ever leaves the application environment.
+![ztaa-model-flazk.png](..%2F..%2Fimages%2Fztaa-model-flazk.png)
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+This example accepts two input arguments.
+1. The identity file to be used by the SDK tunneler
+2. The service to bind to
+```shell
+python helloFlazk.py
+```
+
+## Testing the Example :clipboard:
+By default, the base url is mapped to our `hello_world()` function. So, if we hit that endpoint we will see the
+response from the function which is simply `Have some ziti`. This could be tested with
+1. The [Ziti urllib3](../ziti-urllib3) example
+2. The [Ziti Requests](../ziti-requests) example
+3. A curl command
+
+ curl :
+4. Or simply visiting the intercept address in a browser.
\ No newline at end of file
diff --git a/sample/flask-of-ziti/helloFlazk.py b/sample/flask-of-ziti/helloFlazk.py
index 6efd4a2..23d3187 100644
--- a/sample/flask-of-ziti/helloFlazk.py
+++ b/sample/flask-of-ziti/helloFlazk.py
@@ -1,4 +1,4 @@
-# Copyright (c) NetFoundry Inc.
+# Copyright NetFoundry Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,17 +21,21 @@
@openziti.zitify(bindings={
- ('1.2.3.4', '18080'): bind_opts
+ ('127.0.0.1', 18080): bind_opts
})
def runApp():
from waitress import serve
- serve(app,host='1.2.3.4',port=18080)
+ serve(app,host='127.0.0.1',port=18080)
@app.route('/')
def hello_world(): # put application's code here
return 'Have some Ziti!'
+@app.route('/json')
+def get_json():
+ return '{ "name":"Ziti", "message":"Have some JSON Ziti"}'
+
if __name__ == '__main__':
bind_opts['ztx'] = sys.argv[1]
diff --git a/sample/flask-of-ziti/requirements.txt b/sample/flask-of-ziti/requirements.txt
deleted file mode 100644
index 65d268e..0000000
--- a/sample/flask-of-ziti/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-flask
-waitress
-openziti
\ No newline at end of file
diff --git a/sample/http-get.py b/sample/http-get.py
deleted file mode 100644
index 0b6a891..0000000
--- a/sample/http-get.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import sys
-
-import urllib3
-import openziti
-
-# to run this sample
-# set ZITI_IDENTITIES environment variable to location of your Ziti identity file
-#
-# python http-get.py
-# url should be the intercept address of a ziti service
-if __name__ == '__main__':
- openziti.monkeypatch()
- http = urllib3.PoolManager()
- r = http.request('GET', sys.argv[1])
- print("{0} {1}".format(r.status, r.reason))
- print(r.data.decode('utf-8'))
-
diff --git a/sample/requirements.txt b/sample/requirements.txt
index e263c09..e2e016a 100644
--- a/sample/requirements.txt
+++ b/sample/requirements.txt
@@ -1,2 +1,6 @@
openziti
requests
+flask
+waitress
+urllib3
+setuptools
\ No newline at end of file
diff --git a/sample/ziti-echo-server/README.md b/sample/ziti-echo-server/README.md
new file mode 100644
index 0000000..6f1fd8a
--- /dev/null
+++ b/sample/ziti-echo-server/README.md
@@ -0,0 +1,44 @@
+# Ziti Echo Server
+This example shows how to open a socket to listen on the network overlay for a particular service and send all bytes
+received back to the sender.
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+This example accepts two input arguments.
+1. The identity file to be used by the SDK tunneler to bind to the service
+2. The service to bind to
+```shell
+python ziti-echo-server.py
+```
+
+## Testing the Example :clipboard:
+Netcat can be used to test this however, in order to connect to the service over netcat you'll need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview)
+and a tunneler for the device running the netcat commands. An easy way to set this up is to create an identity that has
+dial access on the intended service. Then run a [tunneler](https://docs.openziti.io/docs/reference/tunnelers/) on your
+platform, and enroll the identity.
+
+If we use netcat to connect to the intercept address and send some data, we will see a response of the exact same data
+we sent (hence the name, echo server).
+
+### Example:
+```shell
+nc
+Hello!
+```
+
+### Example Output:
+Using a service called `python.echo.ziti` on port `80` here is what this would look like.
+```shell
+nc python.echo.ziti 80
+Hello
+Hello
+```
\ No newline at end of file
diff --git a/sample/ziti-echo-server.py b/sample/ziti-echo-server/ziti-echo-server.py
similarity index 97%
rename from sample/ziti-echo-server.py
rename to sample/ziti-echo-server/ziti-echo-server.py
index e9d0f67..137032f 100644
--- a/sample/ziti-echo-server.py
+++ b/sample/ziti-echo-server/ziti-echo-server.py
@@ -1,4 +1,4 @@
-# Copyright (c) NetFoundry Inc.
+# Copyright NetFoundry Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
diff --git a/sample/ziti-http-server/README.md b/sample/ziti-http-server/README.md
new file mode 100644
index 0000000..e1bf2b5
--- /dev/null
+++ b/sample/ziti-http-server/README.md
@@ -0,0 +1,36 @@
+# Ziti HTTP Server
+This example shows how to listen for HTTP requests on a service
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+We can test this example with `curl` however, in order to connect to the service over netcat you'll need an [identity](https://docs.openziti.io/docs/learn/core-concepts/identities/overview)
+and a tunneler for the device running the curl command. An easy way to set this up is to create an identity that has
+dial access on the intended service. Then run a [tunneler](https://docs.openziti.io/docs/reference/tunnelers/) on your
+platform, and enroll the identity.
+
+### Example:
+```shell
+curl
+Hello!
+```
+
+### Example Output:
+Using a service called `python.http.ziti` on port `80` here is what this would look like.
+```shell
+$ curl http://python.http.ziti:80
+{"msg": "Help! I was zitified!"}
+```
+And on the `ziti-http-server` side, we can see the following output showing the identity (`desktop.user`) and some
+request metadata.
+```
+desktop.user - - [12/Apr/2023 15:03:33] "GET / HTTP/1.1" 200 -
+```
\ No newline at end of file
diff --git a/sample/ziti-http-server.py b/sample/ziti-http-server/ziti-http-server.py
similarity index 94%
rename from sample/ziti-http-server.py
rename to sample/ziti-http-server/ziti-http-server.py
index 357615c..38686a3 100644
--- a/sample/ziti-http-server.py
+++ b/sample/ziti-http-server/ziti-http-server.py
@@ -1,4 +1,4 @@
-# Copyright (c) NetFoundry Inc.
+# Copyright NetFoundry Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
import openziti
-hostName = "localhost"
-serverPort = 8080
+hostName = "127.0.0.1"
+serverPort = 18080
cfg = dict(
ztx=sys.argv[1],
diff --git a/sample/ziti-requests/README.md b/sample/ziti-requests/README.md
new file mode 100644
index 0000000..f742cf4
--- /dev/null
+++ b/sample/ziti-requests/README.md
@@ -0,0 +1,44 @@
+# Ziti Requests
+This example shows the use of Ziti monkey patching a standard socket, via the requests module, to intercept network
+connections using a Ziti overlay.
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+This example accepts one _optional_ input argument.
+1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed)
+```shell
+python ziti-requests.py
+```
+This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES`
+environment variable.
+```shell
+export ZITI_IDENTITIES="/path/to/id.json"
+```
+
+## Testing the Example :clipboard:
+One easy way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun up and ready
+to handle requests, we can run this example, sending a request to the flask server.
+
+### Example:
+After starting up the Flazk example with a service called `python.flask.ziti`...
+```shell
+export ZITI_IDENTITIES=
+python ziti-requests.py python.flask.ziti
+```
+
+### Example Output:
+Using a service called `python.flask.ziti` on port `80` here is what this would look like.
+```shell
+$ python ziti-requests.py python.flask.ziti
+{'Content-Length': '49', 'Content-Type': 'text/html; charset=utf-8', 'Date': 'Wed, 12 Apr 2023 18:56:12 GMT', 'Server': 'waitress'}
+{'name': 'Ziti', 'message': 'Have some JSON Ziti'}
+```
\ No newline at end of file
diff --git a/sample/h-ziti-p.py b/sample/ziti-requests/ziti-requests.py
similarity index 72%
rename from sample/h-ziti-p.py
rename to sample/ziti-requests/ziti-requests.py
index 2bfcf9e..62fb022 100644
--- a/sample/h-ziti-p.py
+++ b/sample/ziti-requests/ziti-requests.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2022. NetFoundry, Inc.
+# Copyright NetFoundry Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,12 +11,18 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-
+import sys
import openziti
import requests
if __name__ == '__main__':
+ # Use the provided service name or a default service from ZEDS
+ if len(sys.argv) > 1:
+ service = sys.argv[1]
+ else:
+ service = 'httpbin.ziti'
+
with openziti.monkeypatch():
- r = requests.get('http://httpbin.ziti/json')
+ r = requests.get('http://' + service + '/json')
print(r.headers)
print(r.json())
\ No newline at end of file
diff --git a/sample/ziti-socket/README.md b/sample/ziti-socket/README.md
new file mode 100644
index 0000000..162e123
--- /dev/null
+++ b/sample/ziti-socket/README.md
@@ -0,0 +1,52 @@
+# Ziti Socket
+This example shows the use of a _raw_ ziti socket. Using a raw socket will enable you to add zero trust to an
+application that manages its own sockets. In an application where sockets are managed the decorator can't be used to
+easily "zitify" the application.
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+This example accepts two _optional_ input arguments.
+1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed)
+2. The intercept port to bind to (if none is provided, port `80` will be assumed)
+```shell
+python ziti-socket.py
+```
+This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES`
+environment variable.
+```shell
+export ZITI_IDENTITIES="/path/to/id.json"
+```
+
+## Testing the Example :clipboard:
+Probably the easiest way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun
+up and ready to handle requests, we can run this example, sending a request to the flask server.
+
+### Example:
+After starting up the Flazk example...
+```shell
+python ziti-socket.py python.flask.ziti 80
+```
+
+### Example Output:
+Using a service called `python.flask.ziti` on port `80` here is what this would look like.
+```shell
+$ python ziti-socket.py python.flask.ziti 80
+Ziti SDK version = (b'0.31.5', b'ccbc692')
+HTTP/1.1 200 OK
+Content-Length: 49
+Content-Type: text/html; charset=utf-8
+Date: Mon, 10 Apr 2023 20:43:44 GMT
+Server: waitress
+
+{ "name":"Ziti", "message":"Have some JSON Ziti"}
+
+```
\ No newline at end of file
diff --git a/sample/ziti-socket-sample.py b/sample/ziti-socket/ziti-socket.py
similarity index 74%
rename from sample/ziti-socket-sample.py
rename to sample/ziti-socket/ziti-socket.py
index a568d78..5c8d09d 100644
--- a/sample/ziti-socket-sample.py
+++ b/sample/ziti-socket/ziti-socket.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2022. NetFoundry, Inc.
+# Copyright NetFoundry Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,15 +11,25 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+import sys
import openziti
from socket import SOCK_STREAM,SHUT_WR
if __name__ == '__main__':
+ # Use the provided intercept address or a default address from ZEDS
+ intercept_address = 'httpbin.ziti'
+ if len(sys.argv) > 1:
+ intercept_address = sys.argv[1]
+ # Use the provided port
+ intercept_port = 80
+ if len(sys.argv) > 2:
+ intercept_port = sys.argv[2]
print("Ziti SDK version = {0}".format(openziti.version()))
sock = openziti.socket(type = SOCK_STREAM)
- sock.connect(('httpbin.ziti', 80))
+ sock.connect((intercept_address,
+ 80))
msg = """GET /json HTTP/1.1\r
Accept: */*\r
Accept-Encoding: gzip, deflate\r
diff --git a/sample/ziti-urllib3/README.md b/sample/ziti-urllib3/README.md
new file mode 100644
index 0000000..de53a4b
--- /dev/null
+++ b/sample/ziti-urllib3/README.md
@@ -0,0 +1,43 @@
+# Ziti Urllib3
+This example shows using a "zitified" urllib3 module to send a request to a server.
+
+## Setup :wrench:
+Refer to the [examples README](../README.md) for details on setting up your network, service, and obtaining an identity
+file.
+
+### Install Python Requirements
+If you haven't already installed them, you'll need the dependent libraries used in the examples.
+ ```bash
+ pip install -r ../requirements
+ ```
+
+## Running the Example :arrow_forward:
+This example accepts one _optional_ input argument.
+1. The intercept address to bind to (if none is provided, the `httpbin.ziti` service from ZEDs will be assumed)
+```shell
+python ziti-urllib3.py
+```
+This example also requires the identity file for binding to the service to be provided in the `ZITI_IDENTITIES`
+environment variable.
+```shell
+export ZITI_IDENTITIES="/path/to/id.json"
+```
+
+## Testing the Example :clipboard:
+One easy way to test this example is with the [Flazk example](../flask-of-ziti). Once that server is spun up and ready
+to handle requests, we can run this example, sending a request to the flask server.
+
+### Example:
+After starting up the Flazk example with a service called `python.flask.ziti`...
+```shell
+export ZITI_IDENTITIES=
+python ziti-urllib3.py python.flask.ziti
+```
+
+### Example Output:
+Using a service called `python.flask.ziti` on port `80` here is what this would look like.
+```shell
+$ python ziti-urllib3.py python.flask.ziti
+200 OK
+Have some Ziti!
+```
\ No newline at end of file
diff --git a/sample/ziti-urllib3/ziti-urllib3.py b/sample/ziti-urllib3/ziti-urllib3.py
new file mode 100644
index 0000000..8caff2b
--- /dev/null
+++ b/sample/ziti-urllib3/ziti-urllib3.py
@@ -0,0 +1,25 @@
+# Copyright NetFoundry Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import urllib3
+import openziti
+
+if __name__ == '__main__':
+ openziti.monkeypatch()
+ http = urllib3.PoolManager()
+ r = http.request('GET', sys.argv[1])
+ print("{0} {1}".format(r.status, r.reason))
+ print(r.data.decode('utf-8'))
+