Answers.Body: <p>I also figured out another way to fix this problem. After going back to the tutorial I was talking about I saw that it was made back in 2021. After seeing this I wonder if we were using the same verions of each package, turns out we were not. I'm not sure what version of nglview they were using, but they were using biopython 1.79 which was the latest verion back in 2021 and I was using biopython 1.80. While using biopython 1.80 I was getting the error seen above. But now that I'm using biopython 1.79 I get this
  <a href="https://i.sstatic.net/iRzUG.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/iRzUG.png" alt="enter image description here" /></a></p>
  <p>So I guess there is something going on with biopython 1.80, so I'm going to stick with 1.79</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T17:36:55.103Z
Answers.Text: Thanks, for posting back a solution. Could you kindly upvote @pippo1980's response please? I'm not an expert, by any means, but it looks to be a good response to me. Certainly useful.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T12:40:11.880Z
Answers.Text: yep, same happens with my error, it goes away if I use biopython 1.79
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T17:21:36.050Z
Answers.LastActivityDate: 2022-12-13T17:21:36.050Z
Answers.UserDisplayName: Jeremiah Wade
Answers.Body: <p>This is an issue with Biopython 1.80, in particular introduced by <a href="https://github.com/biopython/biopython/commit/be77131200821bb01254c87fb14ee1bf6c81dd4b" rel="nofollow noreferrer">a commit</a> that automatically closes IO objects sent to <code>PDBIO.save</code>.</p>
  <p>I made <a href="https://github.com/biopython/biopython/pull/4200" rel="nofollow noreferrer">a PR</a> to change the behaviour which fixes this issue and should hopefully be in the next Biopython release. Until then, avoiding using Biopython 1.80 should work.</p>
  <p>Thanks @jeremiah-wade and @pippo1980 for digging into this.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T23:58:09.417Z
Answers.Text: it took You 2 lines to explain what it took me a couple of days to figure out ... . My question is what is / if is there one the pitfall of having unclosed IO objects around ? I am really new to coding and python so in really plain words if you can. thanks again
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T00:03:10.757Z
Answers.Text: and on the same line, any chance to modifying the nglview adaptor.py  class BiopythonStructure(Structure) ??
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T11:59:52.403Z
Answers.Text: It's explained a bit in the linked PR but you can't read from a closed `StringIO` object. So if the `PDBIO.save` function closes the object then an error will be thrown when the string is read back. In general closing an IO object is best done with a `with` block or `.close()`, rather than being done silently when the object is given as a function argument. In general the `with` block is better since it's quite common to forget to call `.close()`. Closing IO objects once they are no longer needed frees memory and lets other software use them safely.
Answers.UserDisplayName: jgreener
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-15T15:23:23.833Z
Answers.Text: They could just add a if isinstance(filename , StringIO) and close_file = 0 in PDBIO like 1.79 and change close_file = 1 for the #filehandle I hope bit
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-16T12:22:05.710Z
Answers.Text: think solution could be like PDBParser handles it: `from Bio.File import as_handle` ,  https://github.com/biopython/biopython/blob/7ef56557bdca66eabd62334e61c4dc3153c997ff/Bio/File.py#L29 and in PDBIO.py  save method change  `with fhandle:`  to `with as_handle(fhandle):`
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-18T00:36:13.727Z
Answers.Text: or remove  `if isinstance else ...` and  change `with fhandle:    to   `with as_handle(file, mode = 'w') as fhandle:
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-14T17:33:26.187Z
Answers.LastActivityDate: 2022-12-14T17:33:26.187Z
Answers.UserDisplayName: jgreener
Answers.Body: <p>I had a similar problem with:</p>
  <pre><code>from Bio.PDB import * 
  import nglview as nv
  
  
  parser = PDBParser(QUIET = True)
  structure = parser.get_structure(&quot;2ms2&quot;, &quot;2ms2.pdb&quot;)
  
  save_pdb = PDBIO()
  save_pdb.set_structure(structure)
  save_pdb.save('pdb_out.pdb')
  
  view = nv.show_biopython(structure)
  view
  </code></pre>
  <p>error was like in question:</p>
  <pre><code>.................site-packages/nglview/adaptor.py:201, in BiopythonStructure.get_structure_string(self)
      199 io_str = StringIO()
      200 io_pdb.save(io_str)
  --&gt; 201 return io_str.getvalue()
  
  ValueError: I/O operation on closed file
  </code></pre>
  <p>I modified <code>site-packages/nglview/adaptor.py:201, in  BiopythonStructure.get_structure_string(self)</code>:</p>
  <pre><code>def get_structure_string(self):
          from Bio.PDB import PDBIO
          from io import StringIO
          io_pdb = PDBIO()
          io_pdb.set_structure(self._entity)
          io_str = StringIO()
          io_pdb.save(io_str)
          return io_str.getvalue()
  
  </code></pre>
  <p>with :</p>
  <pre><code>def get_structure_string(self):
          from Bio.PDB import PDBIO
          
          import mmap
          
          io_pdb = PDBIO()
          
          io_pdb.set_structure(self._entity)
          
          mo = mmap_str()
          
          io_pdb.save(mo)
          
          return mo.read()
  
  </code></pre>
  <p>and added this new class <code>mmap_str()</code> , in same file:</p>
  <pre><code>import mmap
  import copy
  
  class mmap_str():
  
      import mmap #added import at top
      
      instance = None
  
      def __init__(self):
      
          self.mm = mmap.mmap(-1, 2)
          
          self.a = ''
          
          b = '\n'
          
          self.mm.write(b.encode(encoding = 'utf-8'))
          
          self.mm.seek(0)
          
          #print('self.mm.read().decode() ',self.mm.read().decode(encoding = 'utf-8'))
          
          self.mm.seek(0)
          
      def __new__(cls, *args, **kwargs):
          if not isinstance(cls.instance, cls):
              cls.instance = object.__new__(cls)
          return cls.instance
          
      def write(self, string):
          
          self.a = str(copy.deepcopy(self.mm.read().decode(encoding = 'utf-8'))).lstrip('\n')
          
          self.mm.seek(0)
          
          #print('a -&gt; ', self.a)
          
          len_a = len(self.a)
          
          self.mm = mmap.mmap(-1, len(self.a)+len(string))
          
          #print('a :', self.a)
          
          #print('len self.mm ', len(self.mm))
          
          #print('lenght string : ', len(string))
          
          #print(bytes((self.a+string).encode()))
          
          self.mm.write(bytes((self.a+string).encode()))
          
          self.mm.seek(0)
          
          #print('written once ')
          
          #self.mm.seek(0)
          
      def read(self):
      
          self.mm.seek(0)
          
          a = self.mm.read().decode().lstrip('\n')
          
          self.mm.seek(0)
          
          return a
          
      def __enter__(self):
          
          return self
   
      def __exit__(self, *args):
          
          pass
  
  </code></pre>
  <p>if I uncomment the print statements I'll get the :</p>
  <pre><code>IOPub data rate exceeded.
  The notebook server will temporarily stop sending output
  to the client in order to avoid crashing it. 
  </code></pre>
  <p>error , but commenting them out I get:</p>
  <p><a href="https://i.sstatic.net/siSKY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/siSKY.png" alt="" /></a></p>
  <p>while using the<code>nglview.show_file(filename)</code> I get:</p>
  <p><a href="https://i.sstatic.net/olG6j.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/olG6j.png" alt="enter image description here" /></a></p>
  <p>tha's because, as could be seen looking at the <code>pdb_out.pdb</code> file</p>
  <p>outputted by my code, <code>Biopytho.PDB.PDBParser.get_structure(name , filename)</code> doesnt retrieve the pdb header responsible for generate full CRYSTALLOGRAPHIC SYMMETRY/or biopython can't handle it (not sure about this, help if you know better),  but just the coordinates.</p>
  <p>Still don't understand what is going on with the :</p>
  <pre><code>--&gt; 201 return io_str.getvalue()
  
  ValueError: I/O operation on closed file
  </code></pre>
  <p>it could be something related to jupiter ipykernal ? hope somebody could shed more light into this, dont know how the framework runs, but is definitely different from a normal python interpreter. As an example:</p>
  <p><a href="https://i.sstatic.net/cXRlL.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cXRlL.png" alt="enter image description here" /></a></p>
  <p>Same code in one of my Python virtualenv, will run forever, so it could be ipykernel dont like <code>StringIO()</code>s or do something strange to them ?</p>
  <p>OK thanks to the hint in the answer below, I went inspecting PDBIO.py in github repo for version Biopython 1.80 and compared the save method of PDBIO : <a href="https://github.com/biopython/biopython/blob/5ffdce852ba3721ca945ec383a69382507b4fa1b/Bio/PDB/PDBIO.py#L299" rel="nofollow noreferrer">def save(self, file, select=_select, write_end=True, preserve_atom_numbering=False):</a> with the one in Biopython 1.79,</p>
  <p>see first bit:
  <a href="https://i.sstatic.net/PCtMW.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PCtMW.png" alt="enter image description here" /></a></p>
  <p>and last bit:
  <a href="https://i.sstatic.net/1hjO5.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/1hjO5.png" alt="enter image description here" /></a></p>
  <p>so apparently the big difference is the <code>with fhandle:</code> block in version 1.80.</p>
  <p>So I realized that changing <code>adaptor.py</code> with adding a subclass of <code>StringIO</code> that looks like:</p>
  <pre><code>from io import StringIO
  class StringIO(StringIO):
  
      def __exit__(self, *args, **kwargs):
          
          print('exiting from subclassed StringIO !!!!!')
          
          pass
  </code></pre>
  <p>and modifying <code>def get_structure_string(self):</code> like this:</p>
  <pre><code>def get_structure_string(self):
          from Bio.PDB import PDBIO
          #from io import StringIO
          io_pdb = PDBIO()
          io_pdb.set_structure(self._entity)
          io_str = StringIO()
          io_pdb.save(io_str)
          return io_str.getvalue()
  
  
  </code></pre>
  <p>was enough to get my Biopython 1.80 work in jupiter with nglview.</p>
  <p>That told I am not sure what are the pitfalls of not closing the StringIO object we use for the visualization, but apparently its what Biopython 1.79 was doing like my first answer using a mmap object was doing too (not closing the mmap_str)</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T15:50:00.133Z
Answers.Text: What operating system are you on? I'm wondering if it could be a Windows issue, I can also test later on my Windows machine. There was a similar error reported a while ago for iPython and `StringIO`: https://github.com/ipython/ipython/issues/9168.
Answers.UserDisplayName: jgreener
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T16:33:46.980Z
Answers.Text: I am on a Debian VM (VMware on Debian Host), dont remember ipykernel version but tried downgrading it lower than 8 because of this  https://github.com/ipython/ipython/issues/9168 but getting same error nevertheless
Answers.UserDisplayName: pippo1980
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-13T08:49:47.930Z
Answers.LastActivityDate: 2022-12-15T07:26:19.927Z
Answers.LastEditDate: 2022-12-15T07:26:19.927Z
Answers.UserDisplayName: pippo1980
Answers.Body: <p>tried to understand git, I ended up with this, seems more coherent with the previous habits in the biopython project, but cant push it.</p>
  <p><a href="https://i.sstatic.net/zGqfC.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/zGqfC.png" alt="enter image description here" /></a></p>
  <p>Anyone could pass it along ? [of course needs to be checked out, my tests are OK, but I am a novice].</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-12-19T12:44:09.193Z
Answers.LastActivityDate: 2022-12-19T12:44:09.193Z
Answers.UserDisplayName: pippo1980
Body: <p>So I have been trying to get into visualizing proteins in python, so after some research I ended up on a tutorial that was teaching you how to visualize a protein from the COVID-19 virus, so I went and setup anaconda, got jupyter notebook working in vscode, and downloaded the necessary files from the PDB database, and made sure they were in the same directory as my notebook but when I run the the <code>nglview.show_biopython(structure)</code> function I get <code>ValueError: I/O opertation on a closed file</code>. I'm stymied this is my first time using jupyter notebook so maybe there is something I'm missing, I don't know.</p>
  <p>This what the code looks like</p>
  <pre class="lang-py prettyprint-override"><code>from Bio.PDB import * 
  import nglview as nv
  
  
  parser = PDBParser()
  structure = parser.get_structure(&quot;6YYT&quot;, &quot;6YYT.pdb&quot;)
  view = nv.show_biopython(structure)
  </code></pre>
  <p>The error looks like this</p>
  <pre><code>Output exceeds the size limit. Open the full output data in a text editor
  ---------------------------------------------------------------------------
  ValueError                                Traceback (most recent call last)
  ~\AppData\Local\Temp\ipykernel_8776\2743687014.py in &lt;module&gt;
  ----&gt; 1 view = nv.show_biopython(structure)
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\show.py in show_biopython(entity, **kwargs)
      450     '''
      451     entity = BiopythonStructure(entity)
  --&gt; 452     return NGLWidget(entity, **kwargs)
      453 
      454 
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in __init__(self, structure, representations, parameters, **kwargs)
      243         else:
      244             if structure is not None:
  --&gt; 245                 self.add_structure(structure, **kwargs)
      246 
      247         if representations:
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in add_structure(self, structure, **kwargs)
     1111         if not isinstance(structure, Structure):
     1112             raise ValueError(f'{structure} is not an instance of Structure')
  -&gt; 1113         self._load_data(structure, **kwargs)
     1114         self._ngl_component_ids.append(structure.id)
     1115         if self.n_components &gt; 1:
  ...
  --&gt; 200         return io_str.getvalue()
      201 
      202 
  
  ValueError: I/O operation on closed file
  </code></pre>
  <p>I only get this error when using <code>nglview.show_biopython</code>, when I run the <code>get_structure()</code> function it appears to read the file just fine. I can visualize other molucles just fine, or maybe that's because I was using the ASE library instead of a file. I don't know, that's why I'm here.</p>
  <p>Update: Recently I found out that I can visualize the protein using <code>nglview.show_file()</code> instead of using <code>nglview.show_biopython()</code>. Even though I can visualize proteins now and technically my problem has been solved I would still like to know why the <code>show_biopython()</code> function isn't working properly.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-12-12T15:45:24.230Z
Comments.Text: I tried this in Jupyter Lab and VS code but couldn't reproduce the error. What OS are you on and what are your versions of Python, Biopython and nglview? I would like to help fix this as I added the `show_biopython` function many moons ago. In particular it seems that the `StringIO` object at https://github.com/nglviewer/nglview/blob/master/nglview/adaptor.py#L193-L200 gets closed early, preventing it being read.
Comments.UserDisplayName: jgreener
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-12-13T00:04:35.670Z
Comments.Text: @jgreener I'm on windows, the anaconda python kernel version is 3.9.13, my nglview version is 3.03 and my biopython version is 1.80.
Comments.UserDisplayName: Jeremiah Wade
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-12-13T08:48:11.197Z
Comments.Text: answered, better tried to here : https://stackoverflow.com/questions/74737766/file-i-o-error-using-nglview-show-biopythonstructure/74782007#74782007
Comments.UserDisplayName: pippo1980
Tags: <python><structural-biology><biopython>
Title: File I/O error using nglview.show_biopython(structure)
ThreadText: # File I/O error using nglview.show_biopython(structure)
  
  (Asked by: username_0 on 2022-12-09)
  
  So I have been trying to get into visualizing proteins in python, so after some research I ended up on a tutorial that was teaching you how to visualize a protein from the COVID-19 virus, so I went and setup anaconda, got jupyter notebook working in vscode, and downloaded the necessary files from the PDB database, and made sure they were in the same directory as my notebook but when I run the the `nglview.show_biopython(structure)` function I get `ValueError: I/O opertation on a closed file`. I'm stymied this is my first time using jupyter notebook so maybe there is something I'm missing, I don't know.
  
  This what the code looks like
  
  ```py
  from Bio.PDB import * 
  import nglview as nv
  
  parser = PDBParser()
  structure = parser.get_structure("6YYT", "6YYT.pdb")
  view = nv.show_biopython(structure)
  
  ```
  
  The error looks like this
  
  ```
  Output exceeds the size limit. Open the full output data in a text editor
  ---------------------------------------------------------------------------
  ValueError                                Traceback (most recent call last)
  ~\AppData\Local\Temp\ipykernel_8776\2743687014.py in <module>
  ----> 1 view = nv.show_biopython(structure)
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\show.py in show_biopython(entity, **kwargs)
      450     '''
      451     entity = BiopythonStructure(entity)
  --> 452     return NGLWidget(entity, **kwargs)
      453 
      454 
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in __init__(self, structure, representations, parameters, **kwargs)
      243         else:
      244             if structure is not None:
  --> 245                 self.add_structure(structure, **kwargs)
      246 
      247         if representations:
  
  c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in add_structure(self, structure, **kwargs)
     1111         if not isinstance(structure, Structure):
     1112             raise ValueError(f'{structure} is not an instance of Structure')
  -> 1113         self._load_data(structure, **kwargs)
     1114         self._ngl_component_ids.append(structure.id)
     1115         if self.n_components > 1:
  ...
  --> 200         return io_str.getvalue()
      201 
      202 
  
  ValueError: I/O operation on closed file
  
  ```
  
  I only get this error when using `nglview.show_biopython`, when I run the `get_structure()` function it appears to read the file just fine. I can visualize other molucles just fine, or maybe that's because I was using the ASE library instead of a file. I don't know, that's why I'm here.
  
  Update: Recently I found out that I can visualize the protein using `nglview.show_file()` instead of using `nglview.show_biopython()`. Even though I can visualize proteins now and technically my problem has been solved I would still like to know why the `show_biopython()` function isn't working properly.
  
  **Tags:** python, structural-biology, biopython
  
  > **Comments:**
  > **username_1**: I tried this in Jupyter Lab and VS code but couldn't reproduce the error. What OS are you on and what are your versions of Python, Biopython and nglview? I would like to help fix this as I added the `show_biopython` function many moons ago. In particular it seems that the `StringIO` object at https://github.com/nglviewer/nglview/blob/master/nglview/adaptor.py#L193-L200 gets closed early, preventing it being read.  
  > **username_0**: @username_1 I'm on windows, the anaconda python kernel version is 3.9.13, my nglview version is 3.03 and my biopython version is 1.80.  
  > **username_2**: answered, better tried to here : https://stackoverflow.com/questions/74737766/file-i-o-error-using-nglview-show-biopythonstructure/74782007#74782007  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_0 on 2022-12-13. Score: 4
  
  I also figured out another way to fix this problem. After going back to the tutorial I was talking about I saw that it was made back in 2021. After seeing this I wonder if we were using the same verions of each package, turns out we were not. I'm not sure what version of nglview they were using, but they were using biopython 1.79 which was the latest verion back in 2021 and I was using biopython 1.80. While using biopython 1.80 I was getting the error seen above. But now that I'm using biopython 1.79 I get this
  [![enter image description here](https://i.sstatic.net/iRzUG.png)](https://i.sstatic.net/iRzUG.png)
  
  So I guess there is something going on with biopython 1.80, so I'm going to stick with 1.79
  
  > **Comments:**
  > **username_3**: Thanks, for posting back a solution. Could you kindly upvote @username_2's response please? I'm not an expert, by any means, but it looks to be a good response to me. Certainly useful.  
  > **username_2**: yep, same happens with my error, it goes away if I use biopython 1.79  
  
  ---
  
  ### Answer by username_1 on 2022-12-14. Score: 3
  
  This is an issue with Biopython 1.80, in particular introduced by [a commit](https://github.com/biopython/biopython/commit/be77131200821bb01254c87fb14ee1bf6c81dd4b) that automatically closes IO objects sent to `PDBIO.save`.
  
  I made [a PR](https://github.com/biopython/biopython/pull/4200) to change the behaviour which fixes this issue and should hopefully be in the next Biopython release. Until then, avoiding using Biopython 1.80 should work.
  
  Thanks @username_0-username_0 and @username_2 for digging into this.
  
  > **Comments:**
  > **username_2**: it took You 2 lines to explain what it took me a couple of days to figure out ... . My question is what is / if is there one the pitfall of having unclosed IO objects around ? I am really new to coding and python so in really plain words if you can. thanks again  
  > **username_2**: and on the same line, any chance to modifying the nglview adaptor.py  class BiopythonStructure(Structure) ??  
  > **username_1**: It's explained a bit in the linked PR but you can't read from a closed `StringIO` object. So if the `PDBIO.save` function closes the object then an error will be thrown when the string is read back. In general closing an IO object is best done with a `with` block or `.close()`, rather than being done silently when the object is given as a function argument. In general the `with` block is better since it's quite common to forget to call `.close()`. Closing IO objects once they are no longer needed frees memory and lets other software use them safely.  
  > **username_2**: They could just add a if isinstance(filename , StringIO) and close_file = 0 in PDBIO like 1.79 and change close_file = 1 for the #filehandle I hope bit  
  > **username_2**: think solution could be like PDBParser handles it: `from Bio.File import as_handle` ,  https://github.com/biopython/biopython/blob/7ef56557bdca66eabd62334e61c4dc3153c997ff/Bio/File.py#L29 and in PDBIO.py  save method change  `with fhandle:`  to `with as_handle(fhandle):`  
  > **username_2**: or remove  `if isinstance else ...` and  change `with fhandle:    to   `with as_handle(file, mode = 'w') as fhandle:  
  
  ---
  
  ### Answer by username_2 on 2022-12-13. Score: 3
  
  I had a similar problem with:
  
  ```
  from Bio.PDB import * 
  import nglview as nv
  
  parser = PDBParser(QUIET = True)
  structure = parser.get_structure("2ms2", "2ms2.pdb")
  
  save_pdb = PDBIO()
  save_pdb.set_structure(structure)
  save_pdb.save('pdb_out.pdb')
  
  view = nv.show_biopython(structure)
  view
  
  ```
  
  error was like in question:
  
  ```
  .................site-packages/nglview/adaptor.py:201, in BiopythonStructure.get_structure_string(self)
      199 io_str = StringIO()
      200 io_pdb.save(io_str)
  --> 201 return io_str.getvalue()
  
  ValueError: I/O operation on closed file
  
  ```
  
  I modified `site-packages/nglview/adaptor.py:201, in BiopythonStructure.get_structure_string(self)`:
  
  ```
  def get_structure_string(self):
          from Bio.PDB import PDBIO
          from io import StringIO
          io_pdb = PDBIO()
          io_pdb.set_structure(self._entity)
          io_str = StringIO()
          io_pdb.save(io_str)
          return io_str.getvalue()
  
  ```
  
  with :
  
  ```
  def get_structure_string(self):
          from Bio.PDB import PDBIO
          
          import mmap
          
          io_pdb = PDBIO()
          
          io_pdb.set_structure(self._entity)
          
          mo = mmap_str()
          
          io_pdb.save(mo)
          
          return mo.read()
  
  ```
  
  and added this new class `mmap_str()` , in same file:
  
  ```
  import mmap
  import copy
  
  class mmap_str():
  
      import mmap #added import at top
      
      instance = None
  
      def __init__(self):
      
          self.mm = mmap.mmap(-1, 2)
          
          self.a = ''
          
          b = '\n'
          
          self.mm.write(b.encode(encoding = 'utf-8'))
          
          self.mm.seek(0)
          
          #print('self.mm.read().decode() ',self.mm.read().decode(encoding = 'utf-8'))
          
          self.mm.seek(0)
          
      def __new__(cls, *args, **kwargs):
          if not isinstance(cls.instance, cls):
              cls.instance = object.__new__(cls)
          return cls.instance
          
      def write(self, string):
          
          self.a = str(copy.deepcopy(self.mm.read().decode(encoding = 'utf-8'))).lstrip('\n')
          
          self.mm.seek(0)
          
          #print('a -> ', self.a)
          
          len_a = len(self.a)
          
          self.mm = mmap.mmap(-1, len(self.a)+len(string))
          
          #print('a :', self.a)
          
          #print('len self.mm ', len(self.mm))
          
          #print('lenght string : ', len(string))
          
          #print(bytes((self.a+string).encode()))
          
          self.mm.write(bytes((self.a+string).encode()))
          
          self.mm.seek(0)
          
          #print('written once ')
          
          #self.mm.seek(0)
          
      def read(self):
      
          self.mm.seek(0)
          
          a = self.mm.read().decode().lstrip('\n')
          
          self.mm.seek(0)
          
          return a
          
      def __enter__(self):
          
          return self
   
      def __exit__(self, *args):
          
          pass
  
  ```
  
  if I uncomment the print statements I'll get the :
  
  ```
  IOPub data rate exceeded.
  The notebook server will temporarily stop sending output
  to the client in order to avoid crashing it. 
  
  ```
  
  error , but commenting them out I get:
  
  [![](https://i.sstatic.net/siSKY.png)](https://i.sstatic.net/siSKY.png)
  
  while using the`nglview.show_file(filename)` I get:
  
  [![enter image description here](https://i.sstatic.net/olG6j.png)](https://i.sstatic.net/olG6j.png)
  
  tha's because, as could be seen looking at the `pdb_out.pdb` file
  
  outputted by my code, `Biopytho.PDB.PDBParser.get_structure(name , filename)` doesnt retrieve the pdb header responsible for generate full CRYSTALLOGRAPHIC SYMMETRY/or biopython can't handle it (not sure about this, help if you know better), but just the coordinates.
  
  Still don't understand what is going on with the :
  
  ```
  --> 201 return io_str.getvalue()
  
  ValueError: I/O operation on closed file
  
  ```
  
  it could be something related to jupiter ipykernal ? hope somebody could shed more light into this, dont know how the framework runs, but is definitely different from a normal python interpreter. As an example:
  
  [![enter image description here](https://i.sstatic.net/cXRlL.png)](https://i.sstatic.net/cXRlL.png)
  
  Same code in one of my Python virtualenv, will run forever, so it could be ipykernel dont like `StringIO()`s or do something strange to them ?
  
  OK thanks to the hint in the answer below, I went inspecting PDBIO.py in github repo for version Biopython 1.80 and compared the save method of PDBIO : [def save(self, file, select=\_select, write\_end=True, preserve\_atom\_numbering=False):](https://github.com/biopython/biopython/blob/5ffdce852ba3721ca945ec383a69382507b4fa1b/Bio/PDB/PDBIO.py#L299) with the one in Biopython 1.79,
  
  see first bit:
  [![enter image description here](https://i.sstatic.net/PCtMW.png)](https://i.sstatic.net/PCtMW.png)
  
  and last bit:
  [![enter image description here](https://i.sstatic.net/1hjO5.png)](https://i.sstatic.net/1hjO5.png)
  
  so apparently the big difference is the `with fhandle:` block in version 1.80.
  
  So I realized that changing `adaptor.py` with adding a subclass of `StringIO` that looks like:
  
  ```
  from io import StringIO
  class StringIO(StringIO):
  
      def __exit__(self, *args, **kwargs):
          
          print('exiting from subclassed StringIO !!!!!')
          
          pass
  
  ```
  
  and modifying `def get_structure_string(self):` like this:
  
  ```
  def get_structure_string(self):
          from Bio.PDB import PDBIO
          #from io import StringIO
          io_pdb = PDBIO()
          io_pdb.set_structure(self._entity)
          io_str = StringIO()
          io_pdb.save(io_str)
          return io_str.getvalue()
  
  ```
  
  was enough to get my Biopython 1.80 work in jupiter with nglview.
  
  That told I am not sure what are the pitfalls of not closing the StringIO object we use for the visualization, but apparently its what Biopython 1.79 was doing like my first answer using a mmap object was doing too (not closing the mmap\_str)
  
  > **Comments:**
  > **username_1**: What operating system are you on? I'm wondering if it could be a Windows issue, I can also test later on my Windows machine. There was a similar error reported a while ago for iPython and `StringIO`: https://github.com/ipython/ipython/issues/9168.  
  > **username_2**: I am on a Debian VM (VMware on Debian Host), dont remember ipykernel version but tried downgrading it lower than 8 because of this  https://github.com/ipython/ipython/issues/9168 but getting same error nevertheless  
  
  ---
  
  ### Answer by username_2 on 2022-12-19. Score: 1
  
  tried to understand git, I ended up with this, seems more coherent with the previous habits in the biopython project, but cant push it.
  
  [![enter image description here](https://i.sstatic.net/zGqfC.png)](https://i.sstatic.net/zGqfC.png)
  
  Anyone could pass it along ? [of course needs to be checked out, my tests are OK, but I am a novice].
  
  
  ---
  
  