old_contents: from extraction.runnables import Extractor, RunnableError, ExtractorResult
  import csxextract.interfaces as interfaces
  import csxextract.config as config
  import defusedxml.ElementTree as safeET
  import xml.etree.ElementTree as ET
  import xml.sax.saxutils as xmlutils
  import requests
  import re
  
  
  # Returns full TEI xml document of the PDF
  class GrobidTEIExtractor(interfaces.FullTextTEIExtractor):
     result_file_name = '.tei'
  
     def extract(self, data, dep_results):
        xml = _call_grobid_method(data, 'processFulltextDocument')
        return ExtractorResult(xml_result=xml)
  
  # Returns TEI xml document only of the PDF's header info
  class GrobidHeaderTEIExtractor(interfaces.HeaderTEIExtractor):
     result_file_name = '.header.tei'
  
     def extract(self, data, dep_results):
        xml = _call_grobid_method(data, 'processHeaderDocument')
        return ExtractorResult(xml_result=xml)
  
  def _call_grobid_method(data, method):
        url = '{0}/{1}'.format(config.GROBID_HOST, method)
        files = {'input': data}
        vars = {}
  
        try:
           resp = requests.post(url, files=files, data=vars)
        except requests.exceptions.RequestException as ex:
           raise RunnableError('Request to Grobid server failed')
  
        if resp.status_code != 200:
           raise RunnableError('Grobid returned status {0} instead of 200\nPossible Error:\n{1}'.format(resp.status_code, resp.text))
  
        # remove all namespace info from xml string
        # this is hacky but makes parsing it much much easier down the road
        remove_xmlns = re.compile(r'\sxmlns[^"]+"[^"]+"')
        xml_text = remove_xmlns.sub('', resp.content)
  
        xml = safeET.fromstring(xml_text)
  
        return xml
  
  
new_contents: from extraction.runnables import Extractor, RunnableError, ExtractorResult
  import csxextract.interfaces as interfaces
  import csxextract.config as config
  import defusedxml.ElementTree as safeET
  import xml.etree.ElementTree as ET
  import xml.sax.saxutils as xmlutils
  import requests
  import re
  
  
  # Returns full TEI xml document of the PDF
  class GrobidTEIExtractor(interfaces.FullTextTEIExtractor):
     result_file_name = '.tei'
  
     def extract(self, data, dep_results):
        xml = _call_grobid_method(data, 'processFulltextDocument')
        return ExtractorResult(xml_result=xml)
  
  # Returns TEI xml document only of the PDF's header info
  class GrobidHeaderTEIExtractor(interfaces.HeaderTEIExtractor):
     result_file_name = '.header.tei'
  
     def extract(self, data, dep_results):
        xml = _call_grobid_method(data, 'processHeaderDocument')
        return ExtractorResult(xml_result=xml)
  
  class GrobidCitationTEIExtractor(Extractor):
     result_file_name = '.cite.tei'
  
     def extract(self, data, dep_results):
        xml = _call_grobid_method(data, 'processReferences')
        return ExtractorResult(xml_result=xml)
  
  def _call_grobid_method(data, method):
        url = '{0}/{1}'.format(config.GROBID_HOST, method)
        files = {'input': data}
        vars = {}
  
        try:
           resp = requests.post(url, files=files, data=vars)
        except requests.exceptions.RequestException as ex:
           raise RunnableError('Request to Grobid server failed')
  
        if resp.status_code != 200:
           raise RunnableError('Grobid returned status {0} instead of 200\nPossible Error:\n{1}'.format(resp.status_code, resp.text))
  
        # remove all namespace info from xml string
        # this is hacky but makes parsing it much much easier down the road
        remove_xmlns = re.compile(r'\sxmlns[^"]+"[^"]+"')
        xml_text = remove_xmlns.sub('', resp.content)
  
        xml = safeET.fromstring(xml_text)
  
        return xml
  
  
subject: Add citation extraction from grobid