jodal / biip Goto Github PK
View Code? Open in Web Editor NEW📦 Biip interprets the data in barcodes.
Home Page: https://biip.readthedocs.io
License: Apache License 2.0
📦 Biip interprets the data in barcodes.
Home Page: https://biip.readthedocs.io
License: Apache License 2.0
Is there a plan to add ISBT barcodes to the list of supported standards? If you don't plan on adding this do you have any pointers on implementation?
Hi. Thanks for the project.
apparently it is possible to extract GCP from GTIN (even if it is variable length). Here is another library which does it https://github.com/enorganic/gtin/blob/master/scripts/update_gcp_prefix_format_list.py
Any chance to add this feature to your library?
...before the next major release.
I noticed that some EAN-13 barcodes cannot be parsed, even though they seem to be in use.
For example, biip
cannot find a valid GS1 prefix for 6712670000276 (according to the list here, 671 indeed doesn't seem to be used yet), but I can find a product associated with this barcode.
Is this barcode an edge case that is still unhandled by biip
? Any ideas on how this could be fixed?
cc @c-w
I try to decode the following GS1 string from a datamatrix:
01103663023000171021004371716020021925768618163
... which should result in: (01)10366302300017(10)2100437(17)160200(21)925768618163. But biip raise an exception:
biip._exceptions.ParseError: Failed to parse '01103663023000171021004371716020021925768618163':
- GTIN: Failed to parse '01103663023000171021004371716020021925768618163' as GTIN: Expected 8, 12, 13, or 14 digits, got 47.
- UPC: Failed to parse '01103663023000171021004371716020021925768618163' as UPC: Expected 6, 7, 8, or 12 digits, got 47.
- SSCC: Failed to parse '01103663023000171021004371716020021925768618163' as SSCC: Expected 18 digits, got 47.
- GS1: Failed to get GS1 Application Identifier from '768618163'.
Hi,
I am parsing UDIs and can parse product_number (01), serial_number (21), lot_number (10), expiration and manufacture date (17, 11), but I cannot parse additional_id (240) from the UDI.
I managed to fix that by adding the separator '\x1d' before the '240' in UDI, but sometimes the string '240' appears more than once or not in the spot for the additional_id.
Examples:
UDI = '0104062102661608112405271727112710S2400424282400522010301NNN003'
If I don't add a separator, the response is just GS1Message class, and I can only get product_number:
<class 'biip.gs1._messages.GS1Message'>
{'product_number': '04062102661608', 'serial_number': None, 'lot_number': None, 'expiration_date': None, 'manufacture_date': None, 'additional_id': None}
If I add a separator, then I get everything correct:
GS1Message(value='0104062102661738112401241727072410S230091624\x1d2400523000302NNN003', element_strings=[GS1ElementString(ai=GS1ApplicationIdentifier(ai='01', description='Global Trade Item Number (GTIN)', data_title='GTIN', fnc1_required=False, format='N2+N14'), value='04062102661738', pattern_groups=['04062102661738'], gln=None, gln_error=None, gtin=Gtin(value='04062102661738', format=GtinFormat.GTIN_13, prefix=GS1Prefix(value='406', usage='GS1 Germany'), company_prefix=GS1CompanyPrefix(value='4062102'), payload='406210266173', check_digit=8, packaging_level=None), gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='11', description='Production date (YYMMDD)', data_title='PROD DATE', fnc1_required=False, format='N2+N6'), value='240124', pattern_groups=['240124'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=datetime.date(2024, 1, 24), decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='17', description='Expiration date (YYMMDD)', data_title='USE BY OR EXPIRY', fnc1_required=False, format='N2+N6'), value='270724', pattern_groups=['270724'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=datetime.date(2027, 7, 24), decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='10', description='Batch or lot number', data_title='BATCH/LOT', fnc1_required=True, format='N2+X..20'), value='S230091624', pattern_groups=['S230091624'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None), GS1ElementString(ai=GS1ApplicationIdentifier(ai='240', description='Additional product identification assigned by the manufacturer', data_title='ADDITIONAL ID', fnc1_required=True, format='N3+X..30'), value='0523000302NNN003', pattern_groups=['0523000302NNN003'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None)])
{'product_number': '04062102661738', 'serial_number': None, 'lot_number': 'S230091624', 'expiration_date': datetime.date(2027, 7, 24), 'manufacture_date': datetime.date(2024, 1, 24), 'additional_id': '0523000302NNN003'}
So basically, is there something wrong with my UDI, is there something missing?
Thanks!
Hello, I tried parsing the data from the following barcode (data is 1021072911172405310100693570007182
and does not include any separator/FNC1 characters) and received a ParseError
The data should be the following: (10)21072911(17)240531(01)00693570007182
(lot, expiry, GTIN)
I'm aware that ai 10 (lot) can vary in length so I wanted to check my understanding and confirm that this is not an issue with biip
. Has this barcode not been constructed properly?
Thank you,
Hello,
I tried parsing the same gtin value in 3.1.0 and 3.2.0 and it seems that 3.2.0 is raising an unhandled exception. Maybe this is related to #292?
3.1.0
, it's working fine:python
Python 3.12.0 (main, Oct 30 2023, 16:10:32) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import biip
>>> biip.parse("701197206489")
ParseResult(value='701197206489', symbology_identifier=None, gtin=Gtin(value='701197206489', format=GtinFormat.GTIN_12, prefix=GS1Prefix(value='070', usage='GS1 US'), company_prefix=GS1CompanyPrefix(value='0701197'), payload='70119720648', check_digit=9, packaging_level=None), gtin_error=None, upc=Upc(value='701197206489', format=UpcFormat.UPC_A, number_system_digit=7, payload='70119720648', check_digit=9), upc_error=None, sscc=None, sscc_error="Failed to parse '701197206489' as SSCC: Expected 18 digits, got 12.", gs1_message=None, gs1_message_error="Failed to get GS1 Application Identifier from '701197206489'.")
3.2.0
, it's raising TypeError
$ python
Python 3.12.0 (main, Oct 30 2023, 16:10:32) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import biip
>>> biip.parse("701197206489")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/test/.venv/lib/python3.12/site-packages/biip/_parser.py", line 89, in parse
parse_func(val, config, queue, result)
File "~/test/.venv/lib/python3.12/site-packages/biip/_parser.py", line 236, in _parse_gs1_message
result.gs1_message = GS1Message.parse(
^^^^^^^^^^^^^^^^^
File "~/test/.venv/lib/python3.12/site-packages/biip/gs1/_messages.py", line 76, in parse
element_string = GS1ElementString.extract(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/test/.venv/lib/python3.12/site-packages/biip/gs1/_element_strings.py", line 151, in extract
value = "".join(pattern_groups)
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: sequence item 1: expected str instance, NoneType found
Hi @jodal,
First of all thanks for your awesome library.
I would like to know if you have plans to support compressed UPC-E barcodes. As far as I know compressed version is not valid GTIN.
I might be wrong but it seems like the algorithm to calculate the check digit is either different than the one in GTIN or there's no such algorithm at all. When uncompressed UPC-E becomes valid GTIN-12 (it becomes a UPC-A barcode). But when compressed it is not valid GTIN-8, it must be expanded to become GTIN-12 (though it might look like it is valid, as with this example 02345673
which can be treated as GTIN-8).
You can check here for GTIN compatibility https://www.barcodefaq.com/1d/upc-ean/#GTIN_Compliance. Note that in the given example they expanded 02349036
to 00023400000900
which i believe is incorrect because the check digit must be 6
.
Here's a sample code to expand UPC-E to UPC-A - https://code.activestate.com/recipes/528911-barcodes-convert-upc-e-to-upc-a. I tested i on 02349036
and it gives 023400000906
which is a valid UPC-A/GTIN-12.
And here's how to compress UPC-A back to UPC-E - https://gist.github.com/corpit/8204456. Also works as expected.
I think the biggest problem is to distinguish EAN-8 from UPC-E to know when to make the decompression.
As far as I can see from the source code it doesn't take into account this edge case
960, 961 & 9620 & 9624 have been assigned to GS1 UK for GTIN-8 allocation. 9625 & 9626 have been assigned to GS1 Poland for GTIN-8 allocation.
Hello!
I tried parsing data from the following barcode and revieved the following error:
Failed to match '158993a' with GS1 AI (15) pattern '^15(\d{6})$'.
Barcode:
Data: 0104150011164140211GTFG32DLF1723033110158993A
I tried parsing with the following code:
def parse_udi(udi):
print("parse udi")
print(udi)
result = GS1Message.parse(udi)
print(result)
print(result.get(ai="17"))
print(result.get(ai="10"))
Other Barcodes like 0104046963351946172401011019A21G8345
are working fine!
It seems like the parser runs into an error with the (21) AI. Using the same faulty barcode string without the (21) AI works fine
01041500111641401723033110158993A
I tried looking into #113 and #137 but didnt get any clues that helped me.
Edit
Another barcode with the (21) AI seems to work partialy.
01041500111641401726013110V1002521JGFMG4P38R
gets parsed successfully but returns
GS1ElementString(ai=GS1ApplicationIdentifier(ai='10', description='Batch or lot number', data_title='BATCH/LOT', fnc1_required=True, format='N2+X..20'), value='V1002521JGFMG4P38R', pattern_groups=['V1002521JGFMG4P38R'], gln=None, gln_error=None, gtin=None, gtin_error=None, sscc=None, sscc_error=None, date=None, decimal=None, money=None)
where the (21) AI is located in the (10) AI:
Hello!
Some of the GS1 barcodes I am scanning contain some silly dates, such as '000000'. Currently parsing fails completely, as month 0 and day 0 are not a valid month/day respectively.
Is it possible to decide how certain errors are handled, and if they should fallback to defaults or fail completely?
Example of a GS1 barcode that fails: 019906600092731431030078881500000010215359
This is just an idea. I'm not using this for now
GTIN-13 includes ISBN-13. It is possible to extract some useful information, see https://github.com/inventaire/isbn3 and https://github.com/inventaire/isbn3/blob/master/lib/groups.js
GS1 has developed a standard URI format for encoding GS1 Application Identifiers named "GS1 Web URI".
The standard can be found here: https://www.gs1.org/standards/Digital-Link/1-0
If support for this in Biip would be useful for you, please reach out to me.
For some reason AI20 is not begin detected
Here's an example, what is begin returned
(01)10884521761599(11)210701(10)21G0073JZ2023
vs what I expect
(01)10884521761599(11)210701(10)21G0073JZ(20)23
Any advice would be helpful.
It is actually a feature request.
Sometimes in internal usage, we don't care for a valid GTIN. In parsers, there should be an option to skip check for invalid GTIN.
For example. Something like:
biip.gs1.GS1Message.parser(code, fnc1=some_fnc1, check_gtin=False)
If AI 01 or 02 is 14 digit long, it is okay. No need to check for check digit. It will save a little time and system resources if an organization has all valid GTIN, and they don't want to check its validity, and it will also enable an organization to parse any 14-digit code (valid or invalid) for internal use.
Furthermore, currently, if someone wants to get only Lot number or serial number or any other information other than GTIN, if the code has invalid GTIN, he is unable to get any other information because GTIN validation is returning the function with exception.
So, if someone wants to skip check for Valid GTIN, he should have a bool argument to send to the parser function.
Feel the package will do much more good if it supports other common AIs such as GLN, GRAI, GINC, GSIN, etc.
Thank you for the project, @jodal
I have encountered some issues with barcodes not always being encoded correctly. Specifically, when an element string with a fixed length ends with a separator character, and when the barcode is encoded as a human-readable interpretation. Perhaps, making the parsing less strict with an optional argument like "strict=False" would be helpful.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.