weight sampling example

Hi, i've tried to follow your weight sampling example, but i'm stuck with this error:
ValueError: Dimension 0 in both shapes must be equal, but are 3 and 324 for 'Assign_49' (op: 'Assign') with input shapes: [3,3,512,12], [324,512,3,3].
At first i thought it was because i was trying to adapt the example to SDD512, but a clean copy/paste of the original example ends up with same error. It looks like the vector is backwards, but i'm not yet fluent enough in Python/Keras/Tensorflow to actually figure where it might be happening ...
I wasn't using the original ipynb, just a local file, but should be pretty much the same as it was a plain copy/paste...
import h5py
import numpy as np
import shutil

from tensor_sampling_utils import sample_tensors

# TODO: Set the path for the source weights file you want to load.

weights_source_path = 'VGG_coco_SSD_300x300_iter_400000.h5'

# TODO: Set the path and name for the destination weights file
#       that you want to create.

# *** New class number ***
num_classes=2

weights_destination_path = 'VGG_coco_SSD_300x300_iter_400000_subsampled_'+str(num_classes)+'_classes.h5'

# Make a copy of the weights file.
shutil.copy(weights_source_path, weights_destination_path)

# Load both the source weights file and the copy we made.
# We will load the original weights file in read-only mode so that we can't mess up anything.
weights_source_file = h5py.File(weights_source_path, 'r')
weights_destination_file = h5py.File(weights_destination_path)

classifier_names = ['conv4_3_norm_mbox_conf',
                    'fc7_mbox_conf',
                    'conv6_2_mbox_conf',
                    'conv7_2_mbox_conf',
                    'conv8_2_mbox_conf',
                    'conv9_2_mbox_conf']

# *** Output the original model shape ***

conv4_3_norm_mbox_conf_kernel = weights_source_file[classifier_names[0]][classifier_names[0]]['kernel:0']
conv4_3_norm_mbox_conf_bias = weights_source_file[classifier_names[0]][classifier_names[0]]['bias:0']

print("Shape of the '{}' weights:".format(classifier_names[0]))
print()
print("kernel:\t", conv4_3_norm_mbox_conf_kernel.shape)
print("bias:\t", conv4_3_norm_mbox_conf_bias.shape)

# *** Preset paramas for the new model ***

# Number of classes that the model was trained for
n_classes_source = 81
# Number of classes we want to re-train for
# n_classes_dest = 2
# We add 1 because 'backgound' is a class too, 0 to be more precise
# classes_of_interest = list(range(n_classes_dest+1))

# The subset of classes we want to extract from our source model
# 0 SHOULD carried over to the new model.

classes_of_interest=[0,3,8]

subsampling_indices = []
for i in range(int(324/n_classes_source)):
    indices = np.array(classes_of_interest) + i * n_classes_source
    subsampling_indices.append(indices)
subsampling_indices = list(np.concatenate(subsampling_indices))

print(subsampling_indices)

for name in classifier_names:
    # Get the trained weights for this layer from the source HDF5 weights file.
    kernel = weights_source_file[name][name]['kernel:0'].value
    bias = weights_source_file[name][name]['bias:0'].value

    # Get the shape of the kernel. We're interested in sub-sampling
    # the last dimension, 'o'.
    height, width, in_channels, out_channels = kernel.shape

    # Compute the indices of the elements we want to sub-sample.
    # Keep in mind that each classification predictor layer predicts multiple
    # bounding boxes for every spatial location, so we want to sub-sample
    # the relevant classes for each of these boxes.
    subsampling_indices = []
    for i in range(int(out_channels/n_classes_source)):
        indices = np.array(classes_of_interest) + i * n_classes_source
        subsampling_indices.append(indices)
    subsampling_indices = list(np.concatenate(subsampling_indices))

    # Sub-sample the kernel and bias.
    # The `sample_tensors()` function used below provides extensive
    # documentation, so don't hesitate to read it if you want to know
    # what exactly is going on here.
    new_kernel, new_bias = sample_tensors(weights_list=[kernel, bias],
                                          sampling_instructions=[height, width, in_channels, subsampling_indices],
                                          axes=[[3]], # The one bias dimension corresponds to the last kernel dimension.
                                          init=['gaussian', 'zeros'],
                                          mean=0.0,
                                          stddev=0.005)

    # Delete the old weights from the destination file.
    del weights_destination_file[name][name]['kernel:0']
    del weights_destination_file[name][name]['bias:0']
    # Create new datasets for the sub-sampled weights.
    weights_destination_file[name][name].create_dataset(name='kernel:0', data=new_kernel)
    weights_destination_file[name][name].create_dataset(name='bias:0', data=new_bias)

# *** Print the new model shape ***

conv4_3_norm_mbox_conf_kernel = weights_destination_file[classifier_names[0]][classifier_names[0]]['kernel:0']
conv4_3_norm_mbox_conf_bias = weights_destination_file[classifier_names[0]][classifier_names[0]]['bias:0']

print("Shape of the '{}' weights:".format(classifier_names[0]))
print()
print("kernel:\t", conv4_3_norm_mbox_conf_kernel.shape)
print("bias:\t", conv4_3_norm_mbox_conf_bias.shape)

Did you set the correct number of classes when you created the model into which you tried to load the sub-sampled weights? You can see in the error that the number of channels of the two tensors already doesn't match. It seems as if you tried to load the sub-sampled weights into a model with 80 classes.

Think so, on the SDD300 one it was actually all that i changed from your ipynb, ie, the number of classses, to match the ones in the new model... At first i thought i might be loading the model and not just the weights, but nope.
`from keras.optimizers import Adam
from keras import backend as K
from keras.models import load_model
from keras_ssd300 import ssd_300
from keras_ssd_loss import SSDLoss
from keras_layer_AnchorBoxes import AnchorBoxes
from keras_layer_L2Normalization import L2Normalization
from ssd_box_encode_decode_utils import decode_y, decode_y2
from ssd_batch_generator import BatchGenerator
img_height = 300 # Height of the input images
img_width = 300 # Width of the input images
img_channels = 3 # Number of color channels of the input images
subtract_mean = [123, 117, 104] # The per-channel mean of the images in the dataset
The color channel order in the original SSD is BGR, so we should set this to True,
but weirdly the results are better without swapping.
swap_channels = True
Number of positive classes in the new model
n_classes = 2
The anchor box scaling factors used in the original SSD300 for the MS COCO datasets.
scales = [0.07, 0.15, 0.33, 0.51, 0.69, 0.87, 1.05]
The anchor box scaling factors used in the original SSD300 for the Pascal VOC datasets.
scales = [0.1, 0.2, 0.37, 0.54, 0.71, 0.88, 1.05]
The anchor box aspect ratios used in the original SSD300; the order matters
aspect_ratios_per_layer=[[1.0, 2.0, 0.5],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5, 3.0, 1.0/3.0],
[1.0, 2.0, 0.5],
[1.0, 2.0, 0.5]]
two_boxes_for_ar1 = True
steps = [8, 16, 32, 64, 100, 300] # The space between two adjacent anchor box center points for each predictor layer.
offsets = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5] # The offsets of the first anchor box center points from the top and left borders of the image as a fraction of the step size for each predictor layer.
limit_boxes = False # Whether or not you want to limit the anchor boxes to lie entirely within the image boundaries
variances = [0.1, 0.1, 0.2, 0.2] # The variances by which the encoded target coordinates are scaled as in the original implementation
coords = 'centroids' # Whether the box coordinates to be used as targets for the model should be in the 'centroids', 'corners', or 'minmax' format, see documentation
normalize_coords = True
*** Build the Keras  model ***
K.clear_session() # Clear previous models from memory.
model = ssd_300(image_size=(img_height, img_width, img_channels),
n_classes=n_classes,
l2_regularization=0.0005,
scales=scales,
aspect_ratios_per_layer=aspect_ratios_per_layer,
two_boxes_for_ar1=two_boxes_for_ar1,
steps=steps,
offsets=offsets,
limit_boxes=limit_boxes,
variances=variances,
coords=coords,
normalize_coords=normalize_coords,
subtract_mean=subtract_mean,
divide_by_stddev=None,
swap_channels=swap_channels)
print("Model built")
*** Load the sub-sampled weights into the model ***
Load the weights that we've just created via sub-sampling.
weights_path = 'VGG_coco_SSD_300x300_iter_400000_subsampled_2_classes.h5'
model.load_weights(weights_path, by_name=True)
print("Weights file loaded : ", weights_path)`

In any case, one of those two tensors still represents 80 classes. I can't tell from the error message whether it's the kernel tensor of the model you created or the kernel of the weights file that you're trying to load into the model, but either the weights you're trying to load weren't actually sub-sampled to 2 classes or the model you're trying to load them into wasn't created with 2 classes.
I would recommend that you check the shapes of all classifier layers after the sub-sampling following the example in the tutorial where it does this check for the 'conv4_3_norm_mbox_conf' layer. Do the same for the other five classifier layers to see whether all shapes are correct. The number of output channels should be either 12 or 18 for all classifier layers.
Next, check the shapes of the weight of all the classifier layers for the model into which you want to load the weights. You can do that by inspecting model.get_layer('layer_name').get_weights(), which returns a list of Numpy arrays containing the weights for the respective layer.
Somewhere along the way will be the answer to what's going on.

As a follow up, on a "gut feeling" added a .flush() after the write and... it just started working as it should. My guess is that the Python shell signals the script execution as "done" while some background I/O might actually still be ongoing. On a ipynb it wouldn't make a difference because the UDATED file probably still is in the process cache, but if you're running it as two separate scripts back to back, the second one might start reading the file before the first actually ends it's update.
Create new datasets for the sub-sampled weights.
weights_destination_file[name][name].create_dataset(name='kernel:0', data=new_kernel)
weights_destination_file[name][name].create_dataset(name='bias:0', data=new_bias)
Flush buffers just in case
weights_destination_file.flush()
Also added this little bit to the box drawing code, just a little check in case we subsampled to less classes than the original:
Check if the index still exists in our new class list
if class_id<len(classes) :

Sorry about the code format, thought the "code tags" would do, like  would, but seems not :)
As for why not use ipynb, well, eventually i'll end up using parts of the code on my own stuff so it's just an "early decoupling". While i see ipynb's value as a showcase tool, for me it's just a PITA because if/when i want to use of some of the code, it's copy/paste time, and as you mentioned, potential source of error...
Anyway, thx for your work on this implementation of SSD for keras, it's heaven sent :) Any plans to extended it by say, adding classifier "options" like MobileNet/Inceptionv3?

Thanks a lot for pointing this out! So it was actually a bug, at least kind of. People using the notebook just didn't run into it I suppose. I added the flush statement to the Jupyter notebook so that this issue can't happen anymore.
I also fixed another bug by the way, random sampling threw an error before, now it works.
As for expanding to other base network architectures: That is very much the plan, especially the two you mentioned (MobileNet and InceptionV3), but also other, even more recent architectures.

ValueError: Dimension 2 in both shapes must be equal, but are 300 and

ValueError: Dimension 2 in both shapes must be equal, but are 300 and 3. Shapes are [3,3,300,64] and [3,3,3,64]. for 'Assign' (op: 'Assign') with input shapes: [3,3,300,64], [3,3,3,64].

Hello, thanks for this excellent work. we run the ssd300 successfully, but when we run the ssd512 with your pre-trained weights,  this issue occurred:
Dimension 0 in both shapes must be equal, but are 3 and 84. Shapes are [3,3,512,8] and [84,512,3,3]. for 'Assign_53' (op: 'Assign') with input shapes: [3,3,512,8], [84,512,3,3].
The full description as follow:

We checked the weights you supplied and nothing is wrong... the shape of weights is [3, 3, 512, 84] but the error tells the shape is inverted.
We set load_weights(skip_mismatch=True), it shows that all of conv_loc and conv_conf have the shape problem, but we are confused about how it happened...

Looking forward to your reply :)

@yf704475209 It looks like you're trying to load weights that were sub-sampled to 1 class into a model that was built to predict 20 classes. You have to build the model with the right number of classes.

Were you able to fix this @yf704475209? I'm getting the exact same error - trying to train a 1 class detector. I have double checked that the number of classes used when subsampling (classes_of_interest = 2) the weights is the same number as defined in the model (n_classes=1 - because the ssd_512() constructor adds 1 to it).

@shivam6294 are we talking about SSD300 or SSD512?

Hey @pierluigiferrari! I'm training a SSD512 model

You probably forgot to set the list of classifier layers correctly for SSD512. Note that SSD512 has one more predictor layer than SSD300 ('conv10_2_mbox_conf'). The list of classifier layers for SSD512 must be set as follows:
classifier_names = ['conv4_3_norm_mbox_conf',
                    'fc7_mbox_conf',
                    'conv6_2_mbox_conf',
                    'conv7_2_mbox_conf',
                    'conv8_2_mbox_conf',
                    'conv9_2_mbox_conf',
                    'conv10_2_mbox_conf']

Oh, I did set the classifier_names appropriately in the weight sampling script (same as above). I also set the predictor_sizes in the train script as:

@shivam6294 then I'm afraid I'm unable to reproduce your error. If I set the classifier names list as posted above, sub-sample trained SSD512 weights to one positive class, and try to load the resulting sub-sampled weights into a newly built SSD512, loading the weights works fine - no errors over here.


Test Image number

I see  25 RGB frames or optical flow stacks were sampled for testing, but In the train_val.prototxt, you still used segment temporal in video, so I'm  wondering how it is tested？
In the paper：
we follow the testing scheme of the original two-stream ConvNets [1], where we sample 25 RGB frames or optical ow stacks from the action videos. Meanwhile, we crop 4 corners and 1 center, and their horizontal
ipping from the sampled frames to evaluate the ConvNets. For the fusion of spatial and temporal stream networks,
In the train_val.prototxt:
layer {
name: "data"
type: "VideoData"
top: "data"
top: "label"
video_data_param {
source: "data/ucf101_rgb_val_split_3.txt"
batch_size: 1
new_length: 1
num_segments: 3
modality: RGB
name_pattern: "img_%05d.jpg"
}
transform_param{
crop_size: 224
mirror: false
mean_value: [104, 117, 123, 104, 117, 123, 104, 117, 123]
}
include: { phase: TEST }
}

Follow the test instructions in README. Caffe's on the fly testing is only for monitoring the training process.

Thank you very much!
I'll read it again


Topaz should not start any directory service if the remote directory is configured

Right now it is possible to configure a Topaz with a remote directory and a writer, importer, exporter, or model service.
When a remote directory is configured, topaz should not start any directory service.

fixed


Hide title bar

Hi. How do you hide the window title in full screen?

Hi,
I made the modification in my fork (along with another modification to allow to change RAM & CPU settings after the VM has been created).
@KhaosT I can submit a PR if you are interested. Or feel free to grab whatever you want from my repository.

Yes, please submit PR

PR submitted.

This is merged ^^


Request being cancelled with 302 plus request type is being cancelled

Hi!
So, i'm not sure if this is an axios request, but I wouldn't know where else to ask.
I'm making a POST request to my server, with what I'm think is a proper CORS response to handle requests from *, and after a succesful OPTIONS response, the request is being redirected as GET (even though I send POST) and cancelled.
Any idea if this is a  problem with how axios sent the initial request, or what?
Here are 2 images of the 2 requests:

Thanks

Can you POST to the URL outside of axios? Maybe try Postman?

Mmm, I can't replicate this issue now as I changed the backend language from PHP to NodeJS and now everything is working for me. So I'm not sure if maybe it was a backend issue?

In my experience with axios it seems that most CORS related issues stem from improperly configured backends. Glad that it's working now!


feat(demo): add 'steps' page (#165)

feat: 新增引导页
fix: 修复引导页文件名问题
部分预览图

General
✏ Mark the necessary items without changing the structure of the PR template.
Pull request template structure not broken
Type
ℹ What types of changes does your code introduce?
👉 Put an x in the boxes that apply
Bug fix (non-breaking change which fixes an issue)
New feature (non-breaking change which adds functionality)
Breaking change (fix or feature that would cause existing functionality to not work as expected)
This change requires a documentation update
Checklist
ℹ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in CONTRIBUTING.
👉 Put an x in the boxes that apply.
My code follows the style guidelines of this project
Is the code format correct
Is the git submission information standard?
My code follows the style guidelines of this project
I have performed a self-review of my own code
I have commented my code, particularly in hard-to-understand areas
I have made corresponding changes to the documentation
My changes generate no new warnings
I have added tests that prove my fix is effective or that my feature works
New and existing unit tests pass locally with my changes
Any dependent changes have been merged and published in downstream modules

@likui628 https://github.com/vbenjs/vben3/pull/283#discussion_r1405572483 大佬麻烦看一下 vue-vben-admin 这个问题需要改吗？还是保持原样

@likui628 #283 (comment) 大佬麻烦看一下 vue-vben-admin 这个问题需要改吗？还是保持原样

都可以


bootstrap errors

I recently started getting errors as part of the pex bootstrap at runtime. This was previously a working build, but a recent clean build of the virtualenv broke and I'm not sure what happened.
$ pip list | grep setuptools
setuptools                   40.8.0
$ pex --version
pex 1.5.3
$ pex . -m example --platform=macosx-10.13-x86_64 -o build/example
$ ./build/example --version
Traceback (most recent call last):
  File ".bootstrap/_pex/pex.py", line 349, in execute
    exit_code = self._wrap_coverage(self._wrap_profiling, self._execute)
  File ".bootstrap/_pex/pex.py", line 281, in _wrap_coverage
    return runner(*args)
  File ".bootstrap/_pex/pex.py", line 312, in _wrap_profiling
    return runner(*args)
  File ".bootstrap/_pex/pex.py", line 394, in _execute
    return self.execute_entry(self._pex_info.entry_point)
  File ".bootstrap/_pex/pex.py", line 506, in execute_entry
    return runner(entry_point)
  File ".bootstrap/_pex/pex.py", line 510, in execute_module
    cls.demote_bootstrap()
  File ".bootstrap/_pex/pex.py", line 412, in demote_bootstrap
    bootstrap_path_index = sys.path.index(bootstrap_path)
ValueError: '<redacted>/build/example/.bootstrap' is not in list

Because I was using a slightly older version, I upgraded to 1.6.1 and got a new but similar error:
$ pex --version
pex 1.6.1
$ pex . -m example --platform=macosx-10.13-x86_64 -o build/example
$ ./build/example --version
Traceback (most recent call last):
  File ".bootstrap/pex/pex.py", line 352, in execute
  File ".bootstrap/pex/pex.py", line 284, in _wrap_coverage
  File ".bootstrap/pex/pex.py", line 315, in _wrap_profiling
  File ".bootstrap/pex/pex.py", line 397, in _execute
  File ".bootstrap/pex/pex.py", line 495, in execute_entry
  File ".bootstrap/pex/pex.py", line 499, in execute_module
  File ".bootstrap/pex/pex.py", line 416, in demote_bootstrap
  File ".bootstrap/pex/third_party/__init__.py", line 343, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 257, in uninstall_all
  File ".bootstrap/pex/third_party/__init__.py", line 271, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 21, in _tracer
ImportError: No module named pex.tracer

It would be great to be able to reproduce. If you have something that can be public, that would be best. Short of that, can you provide - redacted as needed - output from:

PEX_VERBOSE=9 ./build/example --version
zipinfo ./build/example

Unfortunately the project isn't public, but I can provide that debugging info: https://gist.github.com/tgross/104235bc54e09cdfc9ecedae808b2eee

So, these bits look like the culprit and are not typical:
...
pex: Found site extra: /<redacted>
pex: Tainted path element: /<redacted>/build/example/.bootstrap
pex: Tainted path element: /<redacted>/build/example
...
pex: Tainted path element: /<redacted>/some-lib
pex: Scrubbing from user site: /Users/timgross/Library/Python/2.7/lib/python/site-packages
pex: Scrubbing from site-packages: /<redacted>/build/example/.bootstrap
pex: Scrubbing from site-packages: /<redacted>/build/example
...
[etc]

Is the local distribution (.) you're including in the pex also installed somehow in the interpreter sys.path? It appears to be. This may or may not be something pex should support, but I want to first narrowly focus on getting a repro.

I'm running the pex build in a virtualenv, so sys.path looks like the following:
$ . .virtualenv/bin/activate
$ python
>>> import sys
>>> sys.path
['', '/RedactedPath/.virtualenv/lib/python27.zip', '/RedactedPath/.virtualenv/lib/python2.7', '/RedactedPath/.virtualenv/lib/python2.7/plat-darwin', '/RedactedPath/.virtualenv/lib/python2.7/plat-mac', '/RedactedPath/.virtualenv/lib/python2.7/plat-mac/lib-scriptpackages', '/RedactedPath/.virtualenv/lib/python2.7/lib-tk', '/RedactedPath/.virtualenv/lib/python2.7/lib-old', '/RedactedPath/.virtualenv/lib/python2.7/lib-dynload'<EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS><EMAIL_ADDRESS>'/RedactedPath/.virtualenv/lib/python2.7/site-packages']

Yay! I can repro using https://github.com/jsirois/pex-issues-664.
jsirois@gill /tmp/pex-issues-664 (master) $ ./scripts/repro.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   595    0   595    0     0   1070      0 --:--:-- --:--:-- --:--:--  1068
100 1770k  100 1770k    0     0   912k      0  0:00:01  0:00:01 --:--:-- 2492k
...
Saving PEX file to build/example
Should work:
Hello World!
[sudo] password for jsirois:
Created /usr/lib/python2.7/site-packages/problematic.pth with contents /tmp/pex-issues-664 and now should fail:
Traceback (most recent call last):
  File ".bootstrap/pex/pex.py", line 352, in execute
  File ".bootstrap/pex/pex.py", line 284, in _wrap_coverage
  File ".bootstrap/pex/pex.py", line 315, in _wrap_profiling
  File ".bootstrap/pex/pex.py", line 397, in _execute
  File ".bootstrap/pex/pex.py", line 495, in execute_entry
  File ".bootstrap/pex/pex.py", line 499, in execute_module
  File ".bootstrap/pex/pex.py", line 416, in demote_bootstrap
  File ".bootstrap/pex/third_party/__init__.py", line 343, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 257, in uninstall_all
  File ".bootstrap/pex/third_party/__init__.py", line 271, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 21, in _tracer
ImportError: No module named pex.tracer

The key issue is the .pth file adding the project root directory to the sys.path via the sitecustomize system. Do you have something like that going on? If so, is it intended? If so, can you describe the use case?
Thanks!

I'm not knowingly adding that but I suspect based on what I'm seeing here that the virtualenv is part of the problem. When I'm in the virtualenv site.getsitepackages() returns an AttributeError.
▶ . .virtualenv/bin/activate
(.virtualenv)
▶ python
Python 2.7.15 (default, Sep 18 2018, 20:16:18)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-9<IP_ADDRESS>)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import site
>>> site.getsitepackages()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'getsitepackages'

▶ deactivate
▶ python
Python 2.7.15 (default, Sep 18 2018, 20:16:18)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-9<IP_ADDRESS>)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import site
>>> site.getsitepackages()
<EMAIL_ADDRESS><EMAIL_ADDRESS>

My use case is that I have a command-line application (let's call it example) with a setup.py that includes its dependencies. We use pip install to install those dependencies into a virtualenv so we can run unit tests. And then we build the pex.
$(venv) = .virtualenv

setup:
	test -d $(venv) || virtualenv $(venv)
	$(venv)/bin/pip install -e .[test]

test:
	$(venv)/bin/python test.py

build:
	$(venv)/bin/pex . -m example --platform=macosx-10.13-x86_64 -o build/example

It's entirely possible I'm just misusing pex here by not using a requirements file rather than pulling from the virtualenv (although, as I said, it was working before). But if I try making a requirements file and then running pex -r requirements.txt -m example -o build/example I end up getting ImportError: No module named example.

Thinking more, but never mind the repro repo's use of a requirements file - this was just me starting of the debugging session trying to emulate all your deps from the logs in https://gist.github.com/tgross/104235bc54e09cdfc9ecedae808b2eee since that's all I had to go on and was not yet sure what the problem was. I'll trim the repro repo.

Does .virtualenv have any .pth files? If so can you list and cat them here?

Aha - yes, it does. When you pip install -e, .virtualenv/lib/python2.7/site-packages/easy-install.pth is created by pip and it points to the project dir! So this is the cause. Thinking on solutions...

No it doesn't. But in the interest of eliminating the virtualenv as a problem I removed it and I still get the same import error.
I bootstrapped pex and am invoking it from /usr/local/bin/pex, with the requirements file. So just plain ol' pex -vvv -r requirements.txt -m example --platform=macosx-10.13-x86_64 -o build/example

$ /usr/local/bin/pex -vvv -r requirements.txt -m example --platform=macosx-10.13-x86_64 -o build/example
pex: crawling link i=0 link=Link('file:///Users/timgross/.pex/build') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/backports-ssl-match-hostname/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/boto3/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/botocore/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/certifi/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/chardet/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/click/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/configparser/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/docker/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/docker-pycreds/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/dockerpty/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/docutils/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/enum34/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/flake8/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/futures/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/httplib2/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/idna/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/ipaddress/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/jmespath/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/magiclog/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/mccabe/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/oauth2client/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/pyasn1/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/pyasn1-modules/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/pycodestyle/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/pyflakes/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/python-dateutil/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/pytz/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/requests/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/rollbar/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/rsa/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/s3transfer/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/six/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/stackclimber/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/tzlocal/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/urllib3/') follow_links=False
pex: crawling link i=0 link=Link('https://pypi.org/simple/websocket-client/') follow_links=False
pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/backpopex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/backports.ssl_match_hostname-<IP_ADDRESS>-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/buildpex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpwfnvTT/backports.ssl_match_hostname-<IP_ADDRESS>-py2.py3-none-any.whl into distpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/boto3-1.7.57-py2.py3-none-any.whl                                                                      pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/boto3-1.7.57-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/boto3-1.7.57-py2.py3-nopex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpsJ4G9m/boto3-1.7.57-py2.py3-none-any.whl into distribution                pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/dockerpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/dockerpty-0.4.1-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/dockerpty-0.4.1-py2-nonepex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpwgE95f/dockerpty-0.4.1-py2-none-any.whl into distribution                 pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/jmespapex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/jmespath-0.9.3-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/jmespath-0.9.3-py2.pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmphsB6gG/jmespath-0.9.3-py2.py3-none-any.whl into distribution              pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/botocopex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/botocore-1.10.57-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/botocore-1.10.57-pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpkFXv37/botocore-1.10.57-py2.py3-none-any.whl into distribution            pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/oauth2pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/oauth2client-4.1.2-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/oauth2client-4.1.pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpb_e9aZ/oauth2client-4.1.2-py2.py3-none-any.whl into distribution          pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/dockerpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/docker_pycreds-0.4.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/docker_pycreds-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpqvu42L/docker_pycreds-0.4.0-py2.py3-none-any.whl into distribution        pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/stackcpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/stackclimber-0.99-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/stackclimber-0.99-py2-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpXzrmas/stackclimber-0.99-py2-none-any.whl into distribution               pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/configpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/configparser-3.7.1-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/configparser-3.7.1-pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpNXE_oB/configparser-3.7.1-py2-none-any.whl into distribution              pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyasn1pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyasn1_modules-0.2.4-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/pyasn1_modules-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpARJcds/pyasn1_modules-0.2.4-py2.py3-none-any.whl into distribution        pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/six-1.pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/six-1.12.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/six-1.12.0-py2.py3-none-apex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpzZeaik/six-1.12.0-py2.py3-none-any.whl into distribution                  pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/click-pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/click-6.7-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/click-6.7-py2.py3-none-anypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpUnNnjg/click-6.7-py2.py3-none-any.whl into distribution                   pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/docutipex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/docutils-0.14-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/docutils-0.14-py2-none-anypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpuvSdx8/docutils-0.14-py2-none-any.whl into distribution                   pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/certifpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/certifi-2018.4.16-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/certifi-2018.4.16-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp3ur2nJ/certifi-2018.4.16-py2.py3-none-any.whl into distribution           pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/flake8pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/flake8-3.6.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/flake8-3.6.0-py2.py3-nopex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmphMVGLe/flake8-3.6.0-py2.py3-none-any.whl into distribution                pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/urllibpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/urllib3-1.24.1-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/urllib3-1.24.1-py2.pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp0Dp3Tw/urllib3-1.24.1-py2.py3-none-any.whl into distribution              pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/idna-2pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/idna-2.7-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/idna-2.7-py2.py3-none-any.wpex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpcSH4z6/idna-2.7-py2.py3-none-any.whl into distribution                    pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/rsa-4.pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/rsa-4.pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5dbpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pytz-2pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pytz-2018.9-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/pytz-2018.9-py2.py3-nonepex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpetNK8L/pytz-2018.9-py2.py3-none-any.whl into distribution                 pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/tzlocapex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/tzlocal-1.5.1-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/tzlocal-1.5.1-py2-none-anypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpVolOXJ/tzlocal-1.5.1-py2-none-any.whl into distribution                   pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/httplipex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/httplib2-0.11.3-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/httplib2-0.11.3-py2-nonepex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpfRLYmR/httplib2-0.11.3-py2-none-any.whl into distribution                 pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pythonpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/python_dateutil-2.7.5-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/python_dateutipex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpG3lo8L/python_dateutil-2.7.5-py2.py3-none-any.whl into distribution       pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/rollbapex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/rollbar-0.14.1-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/rollbar-0.14.1-py2-none-apex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmppvQFta/rollbar-0.14.1-py2-none-any.whl into distribution                  pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/ipaddrpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/ipaddress-1.0.22-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/ipaddress-1.0.22-pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpFyVhIJ/ipaddress-1.0.22-py2.py3-none-any.whl into distribution            pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/requespex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/requests-2.20.1-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/requests-2.20.1-py2.pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp4QtJtz/requests-2.20.1-py2.py3-none-any.whl into distribution             pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyflakpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyflakes-2.0.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/pyflakes-2.0.0-py2.pypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp4qJ2vO/pyflakes-2.0.0-py2.py3-none-any.whl into distribution              pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/enum34pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/enum34-1.1.6-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/enum34-1.1.6-py2-none-any.wpex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpU5sNxG/enum34-1.1.6-py2-none-any.whl into distribution                    pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/magiclpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/magiclog-1.0.2-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/magiclog-1.0.2-py2-none-apex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmppOI_ZC/magiclog-1.0.2-py2-none-any.whl into distribution                  pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/futurepex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/futures-3.2.0-py2-none-any.whl :: Fetching file:///Users/timgross/.pex/build/futures-3.2.0-py2-none-anypex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpAPYNm5/futures-3.2.0-py2-none-any.whl into distribution                   pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/s3tranpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/s3transfer-0.1.13-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/s3transfer-0.1.13-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpGWiaxl/s3transfer-0.1.13-py2.py3-none-any.whl into distribution           pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/mccabepex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/mccabe-0.6.1-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/mccabe-0.6.1-py2.py3-nopex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpXsMTOg/mccabe-0.6.1-py2.py3-none-any.whl into distribution                pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/chardepex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/chardet-3.0.4-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/chardet-3.0.4-py2.py3-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpOArnqL/chardet-3.0.4-py2.py3-none-any.whl into distribution               pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pycodepex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pycodestyle-2.4.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/pycodestyle-2.4.0-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp55utaC/pycodestyle-2.4.0-py2.py3-none-any.whl into distribution           pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/dockerpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/docker-3.2.1-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/docker-3.2.1-py2.py3-nopex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpPOxvsJ/docker-3.2.1-py2.py3-none-any.whl into distribution                pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/websocpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/websocket_client-0.48.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/websocket_clpex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpL9OBen/websocket_client-0.48.0-py2.py3-none-any.whl into distribution     pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyasn1pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/pyasn1-0.4.5-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/pyasn1-0.4.5-py2.py3-nopex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpmwTVCc/pyasn1-0.4.5-py2.py3-none-any.whl into distribution                pex: crawling link i=0 link=Link('https://pypi.org/simple/setuptools/') follow_links=False
pex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/setuptpex: Building pex :: Resolving distributions :: Fetching file:///Users/timgross/.pex/build/setuptools-40.8.0-py2.py3-none-any.whl :: Fetching file:///Users/timgross/.pex/build/setuptools-40.8.0-pex: Building pex :: Resolving distributions :: Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpKR3VB1/setuptools-40.8.0-py2.py3-none-any.whl into distribution             backports.ssl-match-hostname==<IP_ADDRESS> -> backports.ssl-match-hostname <IP_ADDRESS>
  boto3==1.7.57 -> boto3 1.7.57
  dockerpty==0.4.1 -> dockerpty 0.4.1
  jmespath==0.9.3 -> jmespath 0.9.3
  botocore==1.10.57 -> botocore 1.10.57
  oauth2client==4.1.2 -> oauth2client 4.1.2
  docker-pycreds==0.4.0 -> docker-pycreds 0.4.0
  stackclimber==0.99 -> stackclimber 0.99
  configparser==3.7.1 -> configparser 3.7.1
  pyasn1-modules==0.2.4 -> pyasn1-modules 0.2.4
  six==1.12.0 -> six 1.12.0
  click==6.7 -> click 6.7
  docutils==0.14 -> docutils 0.14
  certifi==2018.4.16 -> certifi 2018.4.16
  flake8==3.6.0 -> flake8 3.6.0
  setuptools>=30 -> setuptools 40.8.0
  urllib3==1.24.1 -> urllib3 1.24.1
  idna==2.7 -> idna 2.7
  rsa==4.0 -> rsa 4.0
  pytz==2018.9 -> pytz 2018.9
  tzlocal==1.5.1 -> tzlocal 1.5.1
  httplib2==0.11.3 -> httplib2 0.11.3
  python-dateutil==2.7.5 -> python-dateutil 2.7.5
  rollbar==0.14.1 -> rollbar 0.14.1
  ipaddress==1.0.22 -> ipaddress 1.0.22
  requests==2.20.1 -> requests 2.20.1
  pyflakes==2.0.0 -> pyflakes 2.0.0
  enum34==1.1.6 -> enum34 1.1.6
  magiclog==1.0.2 -> magiclog 1.0.2
  futures==3.2.0 -> futures 3.2.0
  s3transfer==0.1.13 -> s3transfer 0.1.13
  mccabe==0.6.1 -> mccabe 0.6.1
  chardet==3.0.4 -> chardet 3.0.4
  pycodestyle==2.4.0 -> pycodestyle 2.4.0
  docker==3.2.1 -> docker 3.2.1
  websocket-client==0.48.0 -> websocket-client 0.48.0
  pyasn1==0.4.5 -> pyasn1 0.4.5
pex: Building pex: 5009.3ms
pex:   Resolving interpreters: 0.1ms
pex:   Resolving distributions: 4987.1ms
pex:     Fetching file:///Users/timgross/.pex/build/backports.ssl_match_hostname-<IP_ADDRESS>-py2.py3-none-any.whl: 1.0ms
pex:       Fetching file:///Users/timgross/.pex/build/backports.ssl_match_hostname-<IP_ADDRESS>-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpwfnvTT/backports.ssl_match_hostname-<IP_ADDRESS>-py2.py3-none-any.whl into distribution: 1.3ms
pex:     Fetching file:///Users/timgross/.pex/build/boto3-1.7.57-py2.py3-none-any.whl: 1.0ms
pex:       Fetching file:///Users/timgross/.pex/build/boto3-1.7.57-py2.py3-none-any.whl: 0.5ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpsJ4G9m/boto3-1.7.57-py2.py3-none-any.whl into distribution: 1.3ms
pex:     Fetching file:///Users/timgross/.pex/build/dockerpty-0.4.1-py2-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/dockerpty-0.4.1-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpwgE95f/dockerpty-0.4.1-py2-none-any.whl into distribution: 1.1ms
pex:     Fetching file:///Users/timgross/.pex/build/jmespath-0.9.3-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/jmespath-0.9.3-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmphsB6gG/jmespath-0.9.3-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/botocore-1.10.57-py2.py3-none-any.whl: 5.7ms
pex:       Fetching file:///Users/timgross/.pex/build/botocore-1.10.57-py2.py3-none-any.whl: 5.1ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpkFXv37/botocore-1.10.57-py2.py3-none-any.whl into distribution: 5.8ms
pex:     Fetching file:///Users/timgross/.pex/build/oauth2client-4.1.2-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/oauth2client-4.1.2-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpb_e9aZ/oauth2client-4.1.2-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/docker_pycreds-0.4.0-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/docker_pycreds-0.4.0-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpqvu42L/docker_pycreds-0.4.0-py2.py3-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/stackclimber-0.99-py2-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/stackclimber-0.99-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpXzrmas/stackclimber-0.99-py2-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/configparser-3.7.1-py2-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/configparser-3.7.1-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpNXE_oB/configparser-3.7.1-py2-none-any.whl into distribution: 1.1ms
pex:     Fetching file:///Users/timgross/.pex/build/pyasn1_modules-0.2.4-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/pyasn1_modules-0.2.4-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpARJcds/pyasn1_modules-0.2.4-py2.py3-none-any.whl into distribution: 1.2ms
pex:     Fetching file:///Users/timgross/.pex/build/six-1.12.0-py2.py3-none-any.whl: 0.9ms
pex:       Fetching file:///Users/timgross/.pex/build/six-1.12.0-py2.py3-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpzZeaik/six-1.12.0-py2.py3-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/click-6.7-py2.py3-none-any.whl: 0.6ms
pex:       Fetching file:///Users/timgross/.pex/build/click-6.7-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpUnNnjg/click-6.7-py2.py3-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/docutils-0.14-py2-none-any.whl: 1.3ms
pex:       Fetching file:///Users/timgross/.pex/build/docutils-0.14-py2-none-any.whl: 0.8ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpuvSdx8/docutils-0.14-py2-none-any.whl into distribution: 3.3ms
pex:     Fetching file:///Users/timgross/.pex/build/certifi-2018.4.16-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/certifi-2018.4.16-py2.py3-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp3ur2nJ/certifi-2018.4.16-py2.py3-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/flake8-3.6.0-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/flake8-3.6.0-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmphMVGLe/flake8-3.6.0-py2.py3-none-any.whl into distribution: 1.2ms
pex:     Fetching file:///Users/timgross/.pex/build/urllib3-1.24.1-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/urllib3-1.24.1-py2.py3-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp0Dp3Tw/urllib3-1.24.1-py2.py3-none-any.whl into distribution: 2.2ms
pex:     Fetching file:///Users/timgross/.pex/build/idna-2.7-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/idna-2.7-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpcSH4z6/idna-2.7-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/rsa-4.0-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/rsa-4.0-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpyBmm4j/rsa-4.0-py2.py3-none-any.whl into distribution: 1.2ms
pex:     Fetching file:///Users/timgross/.pex/build/pytz-2018.9-py2.py3-none-any.whl: 1.1ms
pex:       Fetching file:///Users/timgross/.pex/build/pytz-2018.9-py2.py3-none-any.whl: 0.7ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpetNK8L/pytz-2018.9-py2.py3-none-any.whl into distribution: 5.5ms
pex:     Fetching file:///Users/timgross/.pex/build/tzlocal-1.5.1-py2-none-any.whl: 1.0ms
pex:       Fetching file:///Users/timgross/.pex/build/tzlocal-1.5.1-py2-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpVolOXJ/tzlocal-1.5.1-py2-none-any.whl into distribution: 0.9ms
pex:     Fetching file:///Users/timgross/.pex/build/httplib2-0.11.3-py2-none-any.whl: 1.1ms
pex:       Fetching file:///Users/timgross/.pex/build/httplib2-0.11.3-py2-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpfRLYmR/httplib2-0.11.3-py2-none-any.whl into distribution: 1.7ms
pex:     Fetching file:///Users/timgross/.pex/build/python_dateutil-2.7.5-py2.py3-none-any.whl: 0.9ms
pex:       Fetching file:///Users/timgross/.pex/build/python_dateutil-2.7.5-py2.py3-none-any.whl: 0.5ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpG3lo8L/python_dateutil-2.7.5-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/rollbar-0.14.1-py2-none-any.whl: 1.0ms
pex:       Fetching file:///Users/timgross/.pex/build/rollbar-0.14.1-py2-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmppvQFta/rollbar-0.14.1-py2-none-any.whl into distribution: 2.0ms
pex:     Fetching file:///Users/timgross/.pex/build/ipaddress-1.0.22-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/ipaddress-1.0.22-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpFyVhIJ/ipaddress-1.0.22-py2.py3-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/requests-2.20.1-py2.py3-none-any.whl: 0.6ms
pex:       Fetching file:///Users/timgross/.pex/build/requests-2.20.1-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp4QtJtz/requests-2.20.1-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/pyflakes-2.0.0-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/pyflakes-2.0.0-py2.py3-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp4qJ2vO/pyflakes-2.0.0-py2.py3-none-any.whl into distribution: 0.9ms
pex:     Fetching file:///Users/timgross/.pex/build/enum34-1.1.6-py2-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/enum34-1.1.6-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpU5sNxG/enum34-1.1.6-py2-none-any.whl into distribution: 0.9ms
pex:     Fetching file:///Users/timgross/.pex/build/magiclog-1.0.2-py2-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/magiclog-1.0.2-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmppOI_ZC/magiclog-1.0.2-py2-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/futures-3.2.0-py2-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/futures-3.2.0-py2-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpAPYNm5/futures-3.2.0-py2-none-any.whl into distribution: 0.8ms
pex:     Fetching file:///Users/timgross/.pex/build/s3transfer-0.1.13-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/s3transfer-0.1.13-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpGWiaxl/s3transfer-0.1.13-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/mccabe-0.6.1-py2.py3-none-any.whl: 0.9ms
pex:       Fetching file:///Users/timgross/.pex/build/mccabe-0.6.1-py2.py3-none-any.whl: 0.4ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpXsMTOg/mccabe-0.6.1-py2.py3-none-any.whl into distribution: 1.1ms
pex:     Fetching file:///Users/timgross/.pex/build/chardet-3.0.4-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/chardet-3.0.4-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpOArnqL/chardet-3.0.4-py2.py3-none-any.whl into distribution: 1.1ms
pex:     Fetching file:///Users/timgross/.pex/build/pycodestyle-2.4.0-py2.py3-none-any.whl: 0.6ms
pex:       Fetching file:///Users/timgross/.pex/build/pycodestyle-2.4.0-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmp55utaC/pycodestyle-2.4.0-py2.py3-none-any.whl into distribution: 1.6ms
pex:     Fetching file:///Users/timgross/.pex/build/docker-3.2.1-py2.py3-none-any.whl: 0.7ms
pex:       Fetching file:///Users/timgross/.pex/build/docker-3.2.1-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpPOxvsJ/docker-3.2.1-py2.py3-none-any.whl into distribution: 1.2ms
pex:     Fetching file:///Users/timgross/.pex/build/websocket_client-0.48.0-py2.py3-none-any.whl: 0.9ms
pex:       Fetching file:///Users/timgross/.pex/build/websocket_client-0.48.0-py2.py3-none-any.whl: 0.5ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpL9OBen/websocket_client-0.48.0-py2.py3-none-any.whl into distribution: 1.1ms
pex:     Fetching file:///Users/timgross/.pex/build/pyasn1-0.4.5-py2.py3-none-any.whl: 0.8ms
pex:       Fetching file:///Users/timgross/.pex/build/pyasn1-0.4.5-py2.py3-none-any.whl: 0.3ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpmwTVCc/pyasn1-0.4.5-py2.py3-none-any.whl into distribution: 1.0ms
pex:     Fetching file:///Users/timgross/.pex/build/setuptools-40.8.0-py2.py3-none-any.whl: 1.2ms
pex:       Fetching file:///Users/timgross/.pex/build/setuptools-40.8.0-py2.py3-none-any.whl: 0.8ms
pex:     Translating /private/var/folders/gl/bkp083_96l5db_cqk2rf7zlc0000gp/T/tmpKR3VB1/setuptools-40.8.0-py2.py3-none-any.whl into distribution: 1.5ms
pex: Vendoring pkg_resources from VendorSpec(key='setuptools', version='40.6.2') @ /Users/timgross/.pex/install/pex-1.6.1-py2.py3-none-any.whl.26e6619f9967854d2bde2b60ae396e7c95b36e18/pex-1.6.1-py2.py3-none-any.whl/pex/vendor/_vendored/setuptools
Saving PEX file to build/example

$ ./build/example --version
Traceback (most recent call last):
  File ".bootstrap/pex/pex.py", line 352, in execute
  File ".bootstrap/pex/pex.py", line 284, in _wrap_coverage
  File ".bootstrap/pex/pex.py", line 315, in _wrap_profiling
  File ".bootstrap/pex/pex.py", line 397, in _execute
  File ".bootstrap/pex/pex.py", line 495, in execute_entry
  File ".bootstrap/pex/pex.py", line 499, in execute_module
  File ".bootstrap/pex/pex.py", line 416, in demote_bootstrap
  File ".bootstrap/pex/third_party/__init__.py", line 343, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 257, in uninstall_all
  File ".bootstrap/pex/third_party/__init__.py", line 271, in uninstall
  File ".bootstrap/pex/third_party/__init__.py", line 21, in _tracer
ImportError: No module named pex.tracer

To be pedantic, you're saying the interpreter listed when running PEX_VERBOSE=9 ./build/example 2>&1 | grep PythonInterpreter has no .pth files in it's lib/python2.7/site-packages directory?

RE my:

Aha - yes, it does. When you pip install -e, .virtualenv/lib/python2.7/site-packages/easy-install.pth is created by pip and it points to the project dir! So this is the cause. Thinking on solutions...

NB that setuptools documents that behavior: https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode

Correct:
$ PEX_VERBOSE=9 ./build/example 2>&1 | grep PythonInterpreter
pex: E: tags for 'macosx_10_13_x86_64' x<EMAIL_ADDRESS>...
$ find<EMAIL_ADDRESS>-name '*.pth'
# returns nothing

If I used a virtualenv to bootstrap pex (as described in the docs), have I just reintroduced the problem?

The only interpreter that matters is the runtime interpreter of the built pex here. Can you dig a little more and confirm that none of the sys.path entries for the runtime interpreter of the build/example pex have .pth files?
You can do this with
$ find $($(PEX_VERBOSE=9 ./build/example 2>&1 | grep PythonInterpreter | sed -e "s|^.*PythonInterpreter('||" -e "s|'.*||") -c 'import sys; print("\n".join(sys.path))') -name "*.pth" 2>/dev/null
/usr/lib64/python2.7/site-packages/pygtk.pth
/usr/lib/python2.7/site-packages/pygtk.pth

Ah ha!
find $($(PEX_VERBOSE=9 ./build/example 2>&1 | grep PythonInterpreter | sed -e "s|^.*PythonInterpreter('||" -e "s|'.*||") -c 'import sys; print("\n".join(sys.path))') -name "*.pth" 2>/dev/null    /usr/local/lib/python2.7/site-packages/easy-install.pth
/Users/timgross/someotherproject/.venv/lib/python2.7/site-packages/astroid/tests/testdata/python3/data/foogle_fax-0.12.5-py2.7-nspkg.pth
/Users/timgross/someotherproject/.venv/lib/python2.7/site-packages/astroid/tests/testdata/python2/data/foogle_fax-0.12.5-py2.7-nspkg.pth
/Users/timgross/someotherproject/.venv/lib/python2.7/site-packages/pytest-cov.pth
/Users/timgross/someotherproject/.venv/lib/python2.7/site-packages/easy-install.pth

So there's some entirely other project that's somehow in the path here. That's super weird. I'll need to dig into why that is.

Ok, so after getting that out of my path I'm getting
Traceback (most recent call last):
  File ".bootstrap/pex/pex.py", line 352, in execute
  File ".bootstrap/pex/pex.py", line 284, in _wrap_coverage
  File ".bootstrap/pex/pex.py", line 315, in _wrap_profiling
  File ".bootstrap/pex/pex.py", line 397, in _execute
  File ".bootstrap/pex/pex.py", line 495, in execute_entry
  File ".bootstrap/pex/pex.py", line 502, in execute_module
  File<EMAIL_ADDRESS>line 182, in run_module
    mod_name, loader, code, fname = _get_module_details(mod_name)
  File<EMAIL_ADDRESS>line 107, in _get_module_details
    raise error(format(e))
ImportError: No module named example

But that's clearly just the lousy way my project is set up and nothing to do with PEX. I think I can take it from here. Thanks so much for your patience, @jsirois

Yay! OK, well, there may be a need to address the case where the pex is housed under a sitecustimize dir, but for now I'll call this victory and close as answered.


Websocket server disconnects

When running websocket_client.py & websocket_server.py I am encountering disconnects. This occurs upon pressing enter to send a message it's almost instant. I can usually only send 2 or 3 messages before it happens. I had GPT crunch the server .py and it made a few changes that attempt to handle the client connection a little better and it seems to have helped but then I ran into another error shown below.
I have not modified the client.
A revised version of websocket_server.py can be found at the link below if you want to take a look at it and choose to  incorporate it.
https://github.com/TheOnlyWiseJEDI/memgpt-altcode
Error generated upon disconnect:

@TheOnlyWiseJEDI I've had some success eliminating the keepalive ping timeout error, by tweaking the ping settings on both the client and server.
Server
Add ping timeout/interval to websockets.serve:
async with websockets.serve(self.handle_client, self.host, self.port, ping_timeout=60, ping_interval=10):
Client
Add ping timeout/interval to websockets.connect:
async with websockets.connect(uri, ping_timeout=60, ping_interval=10) as websocket:
However, as I work with the server I have come to realize that it's not actually saving agent state at any point (as far as I can tell).

Thanks for working on it. Technically I shouldn't have had a timeout problem because I was running the websocket client and  server on the same computer. Out of curiosity, is this time in milliseconds?
Either way there does seem to be another issue and it's not usable at the moment - I opened another ticket about it awhile back: https://github.com/cpacker/MemGPT/issues/481

Thanks for working on it. Technically I shouldn't have had a timeout problem because I was running the websocket client and server on the same computer. Out of curiosity, is this time in milliseconds?
Either way there does seem to be another issue and it's not usable at the moment - I opened another ticket about it awhile back: #481

Apologies, I forgot to mention another change I made:  I set a timeout in websocket.recv() on the client side so that it doesn't disconnect if the server response takes a while to generate:
response = await asyncio.wait_for(websocket.recv(), timeout=300)
The timeout values are in seconds, so that receive timeout is pretty extreme (5 minutes).  With theses changes, the client/server "works" for me, but it's not very useful because it isn't actually saving checkpoints or anything.  At best it's ok for chatting with an already-cultivated agent.

websockets.exceptions.ConnectionClosedError: received 1011 (internal error) keepalive ping timeout; then sent 1011 (internal error) keepalive ping timeout
i tried your settings, but got the error after a while of chatting
@BabellDev  is that true for you

websockets.exceptions.ConnectionClosedError: received 1011 (internal error) keepalive ping timeout; then sent 1011 (internal error) keepalive ping timeout
i tried your settings, but got the error after a while of chatting @BabellDev is that true for you

The error seems to go away for me when I make those changes, but I admit I didn't spend too much time testing it;  just confirmed that I could chat for a while without getting the error

@BabellDev any pointers on where I can improve this, this did work for the part where it instantly disconnected a few messages into the chat. I assumed the ping is handled by default from the websockets library

I dont know if this make sense or not but i disabled the ping ping_interval=None I was able to have a conversation for a longer time and then the client timeout kicked in to close the connection response = await asyncio.wait_for(websocket.recv(), CLIENT_TIMEOUT)

I dont know if this make sense or not but i disabled the ping ping_interval=None I was able to have a conversation for a longer time and then the client timeout kicked in to close the connection response = await asyncio.wait_for(websocket.recv(), CLIENT_TIMEOUT)

That's an interesting finding.  I'm afraid I'm not too familiar with this implementation, and haven't tried much else beyond tweaking those ping parameters.  Please report back if you are successful :)


Hyperparameter optimization

Hello Mathis:
I ran through your solution using Intel® Core™ i5 CPU 760 @ 2.80GHz × 4  and GeForce GTX 970/PCIe/SSE2 under Ubuntu 14.04 LTS in about 18days, got kappa value shown in the attached which is similar as you did in the competition.  I am planning either to go further with hyperparameter optimization or adjusting network depth or width. Any suggestion on this?
Cheers,
Daniel

I would probably try the following things, but I don't think there is much more to be gained this way either.

Make the networks deeper where possible.
Add another convnet to the ensemble.
Try using different rectifier units. Notably the elu unit that is now available in lasagne sounds promising.
You might be able to boost the score slightly if you try to compute optimal thresholds at the end rather than using 0.5, 1.5, 2.5, 3.5.
I think you can at least save some time during training if you remove the fully connected layers and/or add 'nonlinearity': None to the parameters for the output layer. The default linearity is rectify so the minimum the convnets can output at the moment is 0. You might have to tune the learning rate schedule again for this to work well though.


Floating point rounding issues in 0.15.x

Versions
0.15.0, 0.15.1
Steps to reproduce

Add a new honeycombio_trigger. I usedterraform {
  required_providers {
    honeycombio = {
      source  = "honeycombio/honeycombio"
      version = "= 0.15.0"
    }
  }
}

provider "honeycombio" {
  api_key = "testing"
}

resource "honeycombio_trigger" "fp_test" {
  name = "testing"

  dataset  = "testing"
  query_id = "testing"

  threshold {
    op    = ">"
    value = 1 - 0.99
  }
}

Run terraform plan
Set provider version to 0.14.0
Run terraform init -upgrade && terraform plan

With 0.15.0 (and 0.15.1), I get the error
│ Error: Provider produced invalid plan
│
│ Provider "registry.terraform.io/honeycombio/honeycombio" planned an invalid value for
│ honeycombio_trigger.fp_test.threshold[0].value: planned value cty.NumberFloatVal(0.01) does not match config value
│ cty.MustParseNumberVal("0.010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003").
│

But with 0.14.0, it generates the expected plan
  # honeycombio_trigger.fp_test will be created
  + resource "honeycombio_trigger" "fp_test" {
      + alert_type = "on_change"
      + dataset    = "testing"
      + frequency  = (known after apply)
      + id         = (known after apply)
      + name       = "testing"
      + query_id   = "testing"

      + threshold {
          + op    = ">"
          + value = 0.01
        }
    }

Additional context
In short, the Honeycomb provider is no longer handling floating point rounding the way it used to. Terraform itself produces floating point inaccuracies for 1 - x, where 0.783 <= x < 1.0, at least on my architecture:
> 1 - 0.782
0.218
> 1 - 0.783
0.21700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
> 1 - 0.995
0.004999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999964

Previously, the provider handled this gracefully, correctly rounding these decimals - but no longer.
This is a pattern we use heavily because we keep a central directory of services, SLOs, etc, and the triggers are generated based on them - so if we have an SLO of 0.995 defined on a service, we generate a failure trigger with threshold 1 - 0.995.

@jharley this leaves is stuck between a rock and a hard place, since 0.14.0 has the issue with recipients, and this 0.15.0 has this issue. Before we try to make significant workarounds, or look into the issue ourselves, do you have an idea of when this can be triaged and worked on?
Thought about looking at this again, but right now the provider throws this:
Stack trace from the terraform-provider-honeycombio_v0.15.1 plugin:

panic: runtime error: index out of range [-1]

goroutine 4812 [running]:
github.com/honeycombio/terraform-provider-honeycombio/internal/provider.(*triggerResource).Read(0x14000814000, {0x100e18580, 0x1400078b5c0}, {{{{0x100e1d0c8, 0x1400080ef90}, {0x100d1ff20, 0x14000c65cb0}}, {0x100e1e868, 0x140003c0820}}, 0x14000814050, ...}, ...)
	github.com/honeycombio/terraform-provider-honeycombio/internal/provider/trigger_resource.go:397 +0x764
github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).ReadResource(0x140001d5e40, {0x100e18580, 0x1400078b5c0}, 0x1400078b6e0, 0x1400051b3c0)
	github.com/hashicorp/terraform-plugin-framework@v1.2.0/internal/fwserver/server_readresource.go:97 +0x4a4
github.com/hashicorp/terraform-plugin-framework/internal/proto5server.(*Server).ReadResource(0x140001d5e40, {0x100e18580?, 0x1400078b410?}, 0x14000b102c0)
	github.com/hashicorp/terraform-plugin-framework@v1.2.0/internal/proto5server/server_readresource.go:53 +0x1a4
github.com/hashicorp/terraform-plugin-mux/tf5muxserver.muxServer.ReadResource({0x14000349ad0, 0x14000349b30, {0x140001b1b80, 0x2, 0x2}, {0x0, 0x0, 0x0}, {0x0, 0x0, ...}, ...}, ...)
	github.com/hashicorp/terraform-plugin-mux@v0.10.0/tf5muxserver/mux_server_ReadResource.go:26 +0xdc
github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server.(*server).ReadResource(0x140002c74a0, {0x100e18580?, 0x1400078a240?}, 0x14000624d20)
	github.com/hashicorp/terraform-plugin-go@v0.15.0/tfprotov5/tf5server/server.go:748 +0x3e8
github.com/hashicorp/terraform-plugin-go/tfprotov5/internal/tfplugin5._Provider_ReadResource_Handler({0x100ddfa00?, 0x140002c74a0}, {0x100e18580, 0x1400078a240}, 0x140003d20e0, 0x0)
	github.com/hashicorp/terraform-plugin-go@v0.15.0/tfprotov5/internal/tfplugin5/tfplugin5_grpc.pb.go:383 +0x170
google.golang.org/grpc.(*Server).processUnaryRPC(0x140002c21e0, {0x100e1d4e0, 0x140004c2680}, 0x140003899e0, 0x140004b45d0, 0x101318970, 0x0)
	google.golang.org/grpc@v1.54.0/server.go:1345 +0xc64
google.golang.org/grpc.(*Server).handleStream(0x140002c21e0, {0x100e1d4e0, 0x140004c2680}, 0x140003899e0, 0x0)
	google.golang.org/grpc@v1.54.0/server.go:1722 +0x82c
google.golang.org/grpc.(*Server).serveStreams.func1.2()
	google.golang.org/grpc@v1.54.0/server.go:966 +0x84
created by google.golang.org/grpc.(*Server).serveStreams.func1
	google.golang.org/grpc@v1.54.0/server.go:964 +0x290

Error: The terraform-provider-honeycombio_v0.15.1 plugin crashed!

@purajit I have just confirmed I can reproduce this bug, thanks for reporting it.
This appears to be a difference in how the new Terraform Plugin Framework parses things (0.15 of the provider is a migration of the honeycombio_trigger resource from the Plugin SDKv2 to the new Plugin Framework). I'll see what we can do about a quick fix here 👍🏻
As for the panic, that is another bug that we are aware of but I've yet to be given a reproducible case to trigger it. If you have such a thing I'd very much appreciate you sharing it so we can get that one squashed as well!

@purajit I've opened https://github.com/hashicorp/terraform-plugin-framework/issues/815 looking for guidance on how to handle this


fix: cancel request feedback

Description
Acknowledge a cancel command tweet by  liking the the tweet
Points worth noting
None
Type of change

[ ] Bug fix (non-breaking change which fixes an issue)
[ ] New feature (non-breaking change which adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
[ ] This change requires a documentation update

How has this been tested?

[ ] Unit test
[ ] Integration test

Checklist:

[ ] I have performed a self-review of my own code
[ ] I have commented on my code, particularly in hard-to-understand areas
[ ] I have made corresponding changes to the documentation
[ ] I have added tests that prove my fix is effective or that my feature works
[ ] New and existing unit tests pass locally with my changes

Related to #19


Simple SVG is not rendering properly

I am not sure if this is Lit related or just Fable, but given the following code:
let createBar index value =
    let ratio = 240 / 10
    html $"""
            <rect
              fill="red"
              x={( 320 / 10 )  * index}
              y={240 - ( value * ratio )}
              width={320 / 10}
              height="{value * ratio}"/>
        """

let chart () =
    html $"""
    <svg width="320" height="240">
      {
       seq { 1..11 } |> Seq.mapi(createBar)
      }
    </svg>
    """

It seems that the <rect> is not being rendered properly.  I can't seem to find any difference between the text, but when I try to edit the HTML and just remove either the space in between <rect> or something then the rect renders.
<svg width="320" height="240">
    <!--?lit$646399511$--><!---->
    <rect fill="red" x="0" y="216" width="32" height="24">
    </rect><!----><!---->
    <rect fill="red" x="32" y="192" width="32" height="48">
    </rect><!----><!---->
    <rect fill="red" x="64" y="168" width="32" height="72">
    </rect><!----><!---->
    <rect fill="red" x="96" y="144" width="32" height="96">
    </rect><!----><!---->
    <rect fill="red" x="128" y="120" width="32" height="120">
    </rect><!----><!---->
    <rect fill="red" x="160" y="96" width="32" height="144">
    </rect><!----><!---->
    <rect fill="red" x="192" y="72" width="32" height="168">
    </rect><!----><!---->
    <rect fill="red" x="224" y="48" width="32" height="192">
    </rect><!----><!---->
    <rect fill="red" x="256" y="24" width="32" height="216">
    </rect><!----><!---->
    <rect fill="red" x="288" y="0" width="32" height="240">
    </rect><!----><!---->
    <rect fill="red" x="320" y="-24" width="32" height="264">
    </rect><!---->
    </svg>

It's being called from a HookComponent
[<HookComponent>]
let Page() =
       html $"""{chart()}"""

I tried changing Seq.mapi to Lit.mapUnique but that didn't make a difference.
Also when I try to set a breakpoint on chart function then the function is called twice? Is that expected? Is it due to some lifecycle?

Don't remember exactly why but Lit requires you to use svg instead of html to render templates within SVG: https://lit.dev/docs/api/templates/#svg
With Fable.Lit you just need to replace html with svg. The tricky part is that when rendering the outer <svg></svg> element is OK to use html but not with a nested template. So in your example above you need to change the first html in createBar but not the one in chart(). There's a sample in this repo: https://github.com/fable-compiler/Fable.Lit/blob/6317d3a32ed91927984b1fc03aa7da3fc02affa3/sample/Clock.fs#L99-L114
Note that when creating the SVG element html is used: https://github.com/fable-compiler/Fable.Lit/blob/6317d3a32ed91927984b1fc03aa7da3fc02affa3/sample/Clock.fs#L177-L194
Sorry this is a bit confusing, it's like this in the Lit library and I didn't find a way to circumvent it.

No worries, still trying to grok web components too. Is this related? https://twitter.com/rich_harris/status/1141831377828102145?lang=en
For future readers here's the solution:
let createBar index value =
    let ratio = 240 / 10
    svg $"""
            <rect
              fill="red"
              x={( 320 / 10 )  * index}
              y={240 - ( value * ratio )}
              width={320 / 10}
              height="{value * ratio}"/>
        """

let chart () =
    html $"""
    <svg width="320" height="240">
      {
       seq { 1..11 } |> Seq.mapi(createBar)
      }
    </svg>
    """

Oh, maybe... I thought Lit templates were independent of web components, but apparently in this case they're related. This is what the Lit documentation says:


Issue with G3 special character set

I have been having an issue with displaying a quaver (music note) using Latin schema. A peek into the code shows that the implementation of kLatinSpecialTable does not match the way its index is being calculated in HandleGLGR, where for GraphicSet::kLatinSpecial case we have:
uint32_t index = (uint32_t)ch - 0x21;
So, for ch = 0x21 we will get 0x0021, while we should get 0x266a according to ABNT 15608-3

@DanielBujnik
Thank you for your bug report. I have tried to fix it in 9917cb311c93d884cb820d122911a211042da26c

Many thanks for prompt fix @xqq.


Watching creates an infinite loop

Hi,
I'm just getting started in the Laravel world, and I'm trying to use this plugin too.
When I use it with gulp watch, this creates an infinite loop, as every time a view is compressed, it is seen as changed so it gets compressed again… and again… and again… you see the point.
Is there any way to avoid that? Maybe by not compressing a view that's already compressed (eg. if weight is the same after and before, just not save it)?

+1 Same here.

The solution above solves the infinite loop, but creates another problem: the view cache is not updated, so you'll never see changes in your code.


User Search / Listing Not Working.

Describe the bug
List users endpoint /api/users fails to return a proper response.
To reproduce
params := users.NewSearchUsersParams()
params.Page = tools.PtrOf(int64(1))
params.Perpage = tools.PtrOf(int64(5000))
usersData, err := s.officialClient.Users.SearchUsers(params, s.getAuth())

Expected behavior
A valid response / payload.  Instead the follow error is returned:
json: cannot unmarshal array into Go value of type models.SearchUserQueryResult

Hey @safaci2000, thank you for pointing this out! Does this still occur with the latest main? Yesterday's PR about the retries reverted the custom changes around how responses are handled to goswagger's default response handling.

Awesome, this has been resolved.  It's been ongoing for a while.


chore: prettier config update, import sorting

Pull Request

📝 Description (short summary, TL;DR)

What changed?

📌 Additional Notes

🔗 Related Issues

🔄 Closes #
🔍 Type of Change

[ ] 🐛 Bug fix (non-breaking change which fixes an issue)
[ ] ✨ New feature (non-breaking change which adds functionality)
[ ] 💥 Breaking change (would cause existing functionality to not work)
[ ] 📚 Documentation update
[ ] 🎨 Style/UI update
[ ] ♻ Code refactoring
[ ] 📦 Dependency update
[ ] 🧪 Test update
[ ] 🔧 Configuration change

✅ Checklist

Code Quality

[ ] 👀 I have performed a self-review
[ ] 💬 I have added necessary comments
[ ] ⚠ No new warnings or errors are generated
[ ] ⚡ I have added/updated tests

Git Hygiene

[ ] 🔍 My commits are small and have clear messages
[ ] 🔀 I have rebased on the latest main branch
[ ] 🧩 This PR is small and focused on a single change

🧪 Testing

[ ] 👉 Manual testing

📸 Screenshots

#86  👈 (View in Graphite)
development

This stack of pull requests is managed by Graphite. Learn more about stacking.


James 1623 - Hystrix wrapping for Mailbox and data-*

This PRs :

Introduces basic Hystrix wrapping for :
- MailRepository store with no fallback
- UsersRepository with no fallback
- DomainList ( with fallback mode to default domain )
- RecipientRewriteTable ( with FallBackMode to no rewrite )

( With these conditions SMTP mails gets received even if storage backend is unavailable )
In addition to this, it handles configuration issues for these components and those from MAILBOX-253 ( one line configuration for each component ), and documentation modifications.

@chibenwa could you close this one and open it on https://github.com/apache/james-project instead ?

Yes of course...
I also thinkI will have some time to add metrics and dashboard this week-end...


better search in docs

My anecdotal experience is that the search bar in dask docs rarely gives me the page I actually want. It doesn't appear to do a good job on search term proximity or non-exact matches and maybe indexes too much on the API sections.
For example, if I search distributed docs for "worker plugin"
https://distributed.dask.org/en/stable/search.html?q=worker+plugin
it's quite challenging to see the result that I actually want.
Anyone know anything about improving / changing the search engine used for this functionality?

Poking around on search features in the RTD docs I found a section on configuring the search ranking. Reading this it seems like we could make some pages more likely to show up than others, if that's something we wanted to explore.
@ntabris there's also this section on using advanced search features-- not sure if you've already tried some of these techniques?
cc @jsignell @jacobtomlinson

@ntabris there's also this section on using advanced search features-- not sure if you've already tried some of these techniques?

FWIW I find the results of searching for "worker plugin" (with the quotes) to be more meaningful

FWIW I find the results of searching for "worker plugin" (with the quotes) to be more meaningful

Hm, those results seem even worse to me since the top hits are all API/docstrings and the page that actually explains worker plugins is much further down.

Fair point. I suppose it ultimately depends on what you're looking for. My previous comment https://github.com/dask/dask/issues/9280#issuecomment-1185808265 was because the top results were at least related to plugins as opposed to about the worker generally (but not related to the plugin system)


Clarification: can an order update remove a horizon?

Suppose you send an order like this:

the base only covers the first 3 nodes, up to node 90
the rest is the horizon

Then you send an order update, to extend the base further up to 107:

note that although the base is extended, the horizon has been removed

This looks like a special case of horizon modification https://github.com/VDA5050/VDA5050/issues/15, where the horizon is simply removed altogether.
The specification does not say this explicitly, so it is better to double-check - is the horizon set in stone, and can it be only extended? Or are such modifications as depicted here, or in issue #15, also valid?

I think this is defined clearly.

In the English draft it says

MC has the option to make changes to the horizon by sending entirely different nodes as the new base.

For me, both say clearly, that the horizon can change. From my point of view, the word "change" of course includes "delete".

I agree, "change" includes "delete". The alternative would be to change the nodes inside the horizon to identical nodes with edges of length zero. I think this is covered by the norm, but is more a corner case than a typically formed order.

The alternative would be to change the nodes inside the horizon to identical nodes with edges of length zero.

No, in my opinion this is no option. Think of track-guided AGVs, that are using RFID-Tags for Localization. They are typically not prepared for "non-movement-edges".

@MaximilianPenninger: Yes, I think this leads to a lot of problems, but we haven't found anything in the norm which says "Don't do it." Do you know the section, which says this is forbidden?

Thanks for the clarification. I believe it would be a bit more reassuring if the text were edited to explicitly say that deleting a horizon is acceptable, e.g. : "MC has the option to make changes to the horizon by sending entirely different nodes, or deleting some of them."

In discussion within VDA and VDMA

Added the clarification to the specification in https://github.com/VDA5050/VDA5050/commit/e19cc603884eb45a15cb3c90700955ec8ed66b5e.


Bug: Short-lived metadata is not resigned on RSTUF instance startup

What happened?
I have an RSTUF server that is mostly off and is powered on only periodically.
As of my understanding, RSTUF short-lived metadata signed with online keys (timestamp, snapshot and target delegated roles)
is supposed to be resigned automatically when the instance is powered on, which does not happen,
causing the TUF client trying to validate the metadata to fail.
The following RSTUF images are used in the deployment:

rstuf-worker: ghcr.io/repository-service-tuf/repository-service-tuf-worker@sha256:6f5376333fffd7cdf61e466ce691579a84e21104dc5f5239e36b42870806fce3
rstuf-api: ghcr.io/repository-service-tuf/repository-service-tuf-api@sha256:8ee4806abafde4c0c9fb5a2ee772e88094a5ff732be5325061ad9e79c803d8b1

What steps did you take?
Turned off the instance and after some time turned on.
What behavior did you expect?
Short-lived metadata to be resigned.
Relevant log output
No response
Code of Conduct

[X] I agree to follow this project's Code of Conduct

@fridex, FYI, I'm working on trying to reproduce and investigate it.


Computing Embeddings from Transformer?

Hello,
Is there any ability to create an API for producing embeddings from input sequences? Users could implement this themselves if #19 turns out to be true. If not, perhaps an embedding API could be exposed without having to make weights publicly available?
Thanks!

Hi @nickbhat there's a function intended for this: https://github.com/Merck/BioPhi/blob/f764b6188211eb2d4e6b4f091729f5ab89c7e406/biophi/humanization/methods/sapiens/predict.py#L36
However, looks like the return_all_hiddens arg is actually ignored :) Do you want to create a pull request by any chance? I'm always happy to get more contributors.
It would be a simple fix here: https://github.com/Merck/BioPhi/blob/f764b6188211eb2d4e6b4f091729f5ab89c7e406/biophi/humanization/methods/sapiens/roberta.py#L76
Btw, this way we can only get the embeddings, if you also wanted the attention weights, that would require some changes to fairseq code.

Fixed by https://github.com/Merck/BioPhi/pull/21/
Example usage:
from biophi.humanization.methods.sapiens.predict import sapiens_predict_seq

pred, extra = sapiens_predict_seq(
    seq=seq, # seq should be the variable region sequence only
    chain_type='H', # chain type is H or L
    return_all_hiddens=True
)

embeddings_per_layer = extra['inner_states']


Add notebook about the Assistants api and the Node.js SDK

Summary
This notebook teaches developers to get started with the Assistants API using the Node.js SDK. It explains how to build a travel agent that utilizes both the code interpreter and knowledge retrieval tools.
In addition to the textual article, I have also recorded an interactive walk-through of the code. This will help learners who prefer watching videos over reading text.
Motivation
There are currently no tutorials in the cookbook that teach JavaScript developers to get started with the Assistants API. This PR fixes this.

For new content
When contributing new content, read through our contribution guidelines, and mark the following action items as completed:

[x] I have added a new entry in registry.yaml (and, optionally, in authors.yaml) so that my content renders on the cookbook website.
[x] I have conducted a self-review of my content based on the contribution guidelines:

[x] Relevance: This content is related to building with OpenAI technologies and is useful to others.
[x] Uniqueness: I have searched for related examples in the OpenAI Cookbook, and verified that my content offers new insights or unique information compared to existing documentation.
[x] Spelling and Grammar: I have checked for spelling or grammatical mistakes.
[x] Clarity: I have done a final read-through and verified that my submission is well-organized and easy to understand.
[x] Correctness: The information I include is correct and all of my code executes successfully.
[x] Completeness: I have explained everything fully, including all necessary references and citations.

We will rate each of these areas on a scale from 1 to 4, and will only accept contributions that score 3 or higher on all areas. Refer to our contribution guidelines for more details.

@perborgen It would be nice if the cookbook also talked about custom functions. Are you planning on adding those too?

@perborgen nice, this looks already good! But as far as I understand, the functions API for the assistants API behave differently or at least the API is different compared to the functions as you wrote the cookbook for them. I enjoyed the cookbook for the assistants API for python, as this covered all the topics in one compact document (including Tools > Functions). I would love to see something like this also for Node.js

I see your point, @TimPietrusky. I'm considering to either add functions to this one, or to create a whole new notebook about Assistant functions with Node. Curious to hear what you think about this @simonpfish ?

Would love to get this PR merged given that @simonpfish approved it last month :)


testVersion: no one follows the manual :(

Issue description
The example from the manual:
passthru.tests.version = testVersion {
  package = seaweedfs;
  command = "weed version";
};

https://nixos.org/manual/nixpkgs/unstable/#tester-testVersion
Literally all instances in nixpkgs use testers.testVersion:
https://github.com/NixOS/nixpkgs/blob/18105ef3b7c56f55d1c36ad8a023d1a79eeab0f3/pkgs/applications/networking/seaweedfs/default.nix#L23-L24
The manual and nixpkgs should be consistent. As a contributor, i should be able to use examples from the manual (it does not even work).
error: undefined variable 'testVersion'
Steps to reproduce
https://github.com/NixOS/nixpkgs/search?p=1&q=testVersion

To make the example from the manual work, you have to add:
{ testers, ... }:
let
  inherit (testers) testVersion;
in
stdenv.mkDerivation rec {
...

which adds 3 lines instead of testers.
i think it is more readable, idiomatic and elegant, but also clutters the devication... so the version used in nixpkgs seems to be pragmatic.
i suggest we update the manual to reflect nixpkgs. do you agree?

I would prefer the testers. version. Inherits in a let block should only be used, when the attribute is need many times and is a common well known attribute, e.g. lib, version, ...

testVersion used to be it's own attribute before it got moved to testers.testVersion, I'm guessing the manual was just forgotten to be updated.

Opened a PR that updates the documentation: https://github.com/NixOS/nixpkgs/pull/190818

testVersion used to be it's own attribute before it got moved to testers.testVersion, I'm guessing the manual was just forgotten to be updated.

yup I forgot


Use of RAII and automatic type deduction.

Implemented RAII to ensure resource safety and exception safety
Leveraged range-based for loops for cleaner and more efficient iteration
Addressed and resolved all project-related warnings for enhanced code quality

Very cool! Thanks @zenon8adams! 🙂


Start up issue

Hello, I have a problem running sh bootstrap.sh. The program is running properly, but I can't access the site http://<IP_ADDRESS>:5000. It raises error The requested URL was not found on the server.  I have tried several methods but I still can't modify the default openning address of flask.

Hi, based on your description, the server is running successful, we don't have support get method for the route path "/", so you can't directly access http://<IP_ADDRESS>:5000. Please see the api doc https://github.com/bytedance/Jeddak-DPSQL/blob/master/doc/ZH/service_api.md, use api such as http://<IP_ADDRESS>:5000/api/v1/query.

Thanks, this problem has been solved!