codecov[bot]: # [Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=h1) Report
> Merging [#60](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=desc) into [master](https://codecov.io/gh/sernst/cauldron/commit/8b847dfc49a20186db0d3a506eda55370deb92e3?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/sernst/cauldron/pull/60/graphs/tree.svg?width=650&token=VXJ1BzmoVE&height=150&src=pr)](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master      #60   +/-   ##
=======================================
  Coverage   98.33%   98.33%           
=======================================
  Files         226      226           
  Lines        9869     9869           
=======================================
  Hits         9705     9705           
  Misses        164      164
```


| [Impacted Files](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cauldron/cli/commands/open/\_\_init\_\_.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vY2xpL2NvbW1hbmRzL29wZW4vX19pbml0X18ucHk=) | `86.56% <ø> (-0.2%)` | :arrow_down: |
| [cauldron/cli/commands/open/opener.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vY2xpL2NvbW1hbmRzL29wZW4vb3BlbmVyLnB5) | `100% <100%> (ø)` | :arrow_up: |
| [.../test/cli/server/routes/synchronize/test\_status.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vdGVzdC9jbGkvc2VydmVyL3JvdXRlcy9zeW5jaHJvbml6ZS90ZXN0X3N0YXR1cy5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [cauldron/session/projects/project.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vc2Vzc2lvbi9wcm9qZWN0cy9wcm9qZWN0LnB5) | `96.65% <100%> (+0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=footer). Last update [8b847df...f8262a8](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

codecov[bot]: # [Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=h1) Report
> Merging [#60](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=desc) into [master](https://codecov.io/gh/sernst/cauldron/commit/8b847dfc49a20186db0d3a506eda55370deb92e3?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/sernst/cauldron/pull/60/graphs/tree.svg?width=650&token=VXJ1BzmoVE&height=150&src=pr)](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master      #60   +/-   ##
=======================================
  Coverage   98.33%   98.33%           
=======================================
  Files         226      226           
  Lines        9869     9869           
=======================================
  Hits         9705     9705           
  Misses        164      164
```


| [Impacted Files](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cauldron/cli/commands/open/\_\_init\_\_.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vY2xpL2NvbW1hbmRzL29wZW4vX19pbml0X18ucHk=) | `86.56% <ø> (-0.2%)` | :arrow_down: |
| [cauldron/cli/commands/open/opener.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vY2xpL2NvbW1hbmRzL29wZW4vb3BlbmVyLnB5) | `100% <100%> (ø)` | :arrow_up: |
| [.../test/cli/server/routes/synchronize/test\_status.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vdGVzdC9jbGkvc2VydmVyL3JvdXRlcy9zeW5jaHJvbml6ZS90ZXN0X3N0YXR1cy5weQ==) | `100% <100%> (ø)` | :arrow_up: |
| [cauldron/session/projects/project.py](https://codecov.io/gh/sernst/cauldron/pull/60/diff?src=pr&el=tree#diff-Y2F1bGRyb24vc2Vzc2lvbi9wcm9qZWN0cy9wcm9qZWN0LnB5) | `96.65% <100%> (+0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=footer). Last update [8b847df...f8262a8](https://codecov.io/gh/sernst/cauldron/pull/60?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

coveralls: 
[![Coverage Status](https://coveralls.io/builds/22361673/badge)](https://coveralls.io/builds/22361673)

Coverage remained the same at 98.338% when pulling **f8262a812166a4fe91a395607c9835bab6855ac7 on 59-libs-loading** into **8b847dfc49a20186db0d3a506eda55370deb92e3 on master**.

diff --git a/cauldron/cli/commands/open/__init__.py b/cauldron/cli/commands/open/__init__.py
index 8112986..138814e 100644
--- a/cauldron/cli/commands/open/__init__.py
+++ b/cauldron/cli/commands/open/__init__.py
@@ -1,7 +1,6 @@
 import os
 import typing
 from argparse import ArgumentParser
-import requests
 
 import cauldron
 from cauldron import cli
diff --git a/cauldron/cli/commands/open/opener.py b/cauldron/cli/commands/open/opener.py
index 35ade2f..2300c43 100644
--- a/cauldron/cli/commands/open/opener.py
+++ b/cauldron/cli/commands/open/opener.py
@@ -171,7 +171,10 @@ def open_project(
             message='Unable to write project notebook data'
         ).console(whitespace=1).response
 
-    runner.add_library_path(project.source_directory)
+    # Should no longer be needed because the source directory is included
+    # in the library directories as of v0.4.7
+    # runner.add_library_path(project.source_directory)
+    runner.reload_libraries(project.library_directories)
 
     return response.update(
         project=project.kernel_serialize()
diff --git a/cauldron/cli/sync/files.py b/cauldron/cli/sync/files.py
index 9a0e5ba..3255e1d 100644
--- a/cauldron/cli/sync/files.py
+++ b/cauldron/cli/sync/files.py
@@ -159,7 +159,13 @@ def send_all_in(
         directory
     ).rstrip(os.path.sep)
 
-    for file_path in glob.iglob(glob_path, recursive=True):
+    # Only send files that have non-zero size
+    file_paths = (
+        p
+        for p in glob.iglob(glob_path, recursive=True)
+        if os.path.isfile(p) and os.path.getsize(p) > 0
+    )
+    for file_path in file_paths:
         relative_path = file_path[len(root_path):].lstrip(os.path.sep)
 
         response = send(
diff --git a/cauldron/session/projects/project.py b/cauldron/session/projects/project.py
index 3698457..428a967 100644
--- a/cauldron/session/projects/project.py
+++ b/cauldron/session/projects/project.py
@@ -51,11 +51,9 @@ class Project:
         self.remote_source_directory = None  # type: str
 
         def as_shared_cache(source):
-            if source is None:
-                return SharedCache()
-            if not hasattr(source, 'fetch'):
+            if source and not hasattr(source, 'fetch'):
                 return SharedCache().put(**source)
-            return source
+            return source or SharedCache()
 
         self.stop_condition = StopCondition(False, False)  # type: StopCondition
         self.shared = as_shared_cache(shared)
@@ -100,6 +98,9 @@ class Project:
         # Include the remote shared library folder as well
         folders.append('../__cauldron_shared_libs')
 
+        # Include the project directory as well
+        folders.append(self.source_directory)
+
         return [
             environ.paths.clean(os.path.join(self.source_directory, folder))
             for folder in folders
diff --git a/cauldron/settings.json b/cauldron/settings.json
index ce8a660..828015e 100644
--- a/cauldron/settings.json
+++ b/cauldron/settings.json
@@ -1,4 +1,4 @@
 {
-  "version": "0.4.6",
+  "version": "0.4.7",
   "notebookVersion": "v1"
 }

Library Directories without Reload
Right now when not auto-reloading libraries, the library directories do not always get reliably added during notebook initialization.
diff --git a/cauldron/test/cli/server/routes/synchronize/test_status.py b/cauldron/test/cli/server/routes/synchronize/test_status.py
index d079684..f13c041 100644
--- a/cauldron/test/cli/server/routes/synchronize/test_status.py
+++ b/cauldron/test/cli/server/routes/synchronize/test_status.py
@@ -44,5 +44,5 @@ class TestStatus(scaffolds.ResultsTest):
         project = cauldron.project.get_internal_project()
         results = status.of_project(project)
 
-        self.assertEqual(len(results['libraries']), 2)
+        self.assertEqual(len(results['libraries']), 3)
         self.assertEqual(len(results['project'].keys()), 1)

pip install -e .[dev]
parse_log_pytest
requirements.txt
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
beautifulsoup4==4.12.3
bokeh==2.3.3
-e git+https://github.com/sernst/cauldron.git@8b847dfc49a20186db0d3a506eda55370deb92e3#egg=cauldron_notebook
certifi==2021.5.30
charset-normalizer==2.0.12
click==8.0.4
coverage==6.2
cycler==0.11.0
dataclasses==0.8
Flask==2.0.3
idna==3.10
importlib-metadata==4.8.3
iniconfig==1.1.1
itsdangerous==2.0.1
Jinja2==3.0.3
kiwisolver==1.3.1
Markdown==3.3.7
MarkupSafe==2.0.1
matplotlib==3.3.4
numpy==1.19.5
packaging==21.3
pandas==1.1.5
Pillow==8.4.0
plotly==5.18.0
pluggy==1.0.0
py==1.11.0
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
pytest-runner==5.3.2
python-dateutil==2.9.0.post0
pytz==2025.2
PyYAML==6.0.1
requests==2.27.1
scipy==1.5.4
seaborn==0.11.2
six==1.17.0
soupsieve==2.3.2.post1
tenacity==8.2.2
tomli==1.2.3
tornado==6.1
typing_extensions==4.1.1
urllib3==1.26.20
Werkzeug==2.0.3
zipp==3.6.0

name: cauldron
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - beautifulsoup4==4.12.3
      - bokeh==2.3.3
      - charset-normalizer==2.0.12
      - click==8.0.4
      - coverage==6.2
      - cycler==0.11.0
      - dataclasses==0.8
      - flask==2.0.3
      - idna==3.10
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - itsdangerous==2.0.1
      - jinja2==3.0.3
      - kiwisolver==1.3.1
      - markdown==3.3.7
      - markupsafe==2.0.1
      - matplotlib==3.3.4
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - pillow==8.4.0
      - plotly==5.18.0
      - pluggy==1.0.0
      - py==1.11.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytest-runner==5.3.2
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyyaml==6.0.1
      - requests==2.27.1
      - scipy==1.5.4
      - seaborn==0.11.2
      - six==1.17.0
      - soupsieve==2.3.2.post1
      - tenacity==8.2.2
      - tomli==1.2.3
      - tornado==6.1
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - werkzeug==2.0.3
      - zipp==3.6.0
prefix: /opt/conda/envs/cauldron

cauldron/test/cli/server/routes/synchronize/test_status.py::TestStatus::test_of_project
cauldron/test/cli/server/routes/synchronize/test_status.py::TestStatus::test_of_directory cauldron/test/cli/server/routes/synchronize/test_status.py::TestStatus::test_of_file cauldron/test/cli/server/routes/synchronize/test_status.py::TestStatus::test_of_file_missing
cauldron/cli/sync/files.py cauldron/session/projects/project.py cauldron/settings.json cauldron/cli/commands/open/__init__.py cauldron/cli/commands/open/opener.py
cauldron/cli/sync/files.py cauldron/session/projects/project.py cauldron/settings.json cauldron/cli/commands/open/__init__.py cauldron/cli/commands/open/opener.py